refactor(editor): extract attachment block (#9308)

This commit is contained in:
Saul-Mirone
2024-12-25 12:19:58 +00:00
parent d8bc145465
commit ebd97752bf
35 changed files with 272 additions and 125 deletions

View File

@@ -1,3 +1,4 @@
import { addAttachments } from '@blocksuite/affine-block-attachment';
import {
CanvasElementType,
SurfaceGroupLikeModel,
@@ -75,7 +76,7 @@ import {
getSortedCloneElements,
serializeElement,
} from '../utils/clone-utils.js';
import { addAttachments, addImages } from '../utils/common.js';
import { addImages } from '../utils/common.js';
import { deleteElements } from '../utils/crud.js';
import {
isAttachmentBlock,

View File

@@ -1,3 +1,4 @@
import { addAttachments } from '@blocksuite/affine-block-attachment';
import { AttachmentIcon, LinkIcon } from '@blocksuite/affine-components/icons';
import { MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
@@ -14,7 +15,7 @@ import {
} from '../../../../../_common/utils/index.js';
import { ImageIcon } from '../../../../../image-block/styles.js';
import type { NoteToolOption } from '../../../gfx-tool/note-tool.js';
import { addAttachments, addImages } from '../../../utils/common.js';
import { addImages } from '../../../utils/common.js';
import { getTooltipWithShortcut } from '../../utils.js';
import { EdgelessToolbarToolMixin } from '../mixins/tool.mixin.js';
import { NOTE_MENU_ITEMS } from './note-menu-config.js';

View File

@@ -1,7 +1,6 @@
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
import { toast } from '@blocksuite/affine-components/toast';
import {
type AttachmentBlockProps,
DEFAULT_NOTE_HEIGHT,
DEFAULT_NOTE_WIDTH,
type ImageBlockProps,
@@ -9,10 +8,6 @@ import {
type NoteBlockModel,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import {
EMBED_CARD_HEIGHT,
EMBED_CARD_WIDTH,
} from '@blocksuite/affine-shared/consts';
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
import type { NoteChildrenFlavour } from '@blocksuite/affine-shared/types';
import {
@@ -22,7 +17,6 @@ import {
import type { BlockStdScope } from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
import {
Bound,
type IPoint,
type IVec,
Point,
@@ -30,91 +24,10 @@ import {
Vec,
} from '@blocksuite/global/utils';
import {
getFileType,
uploadAttachmentBlob,
} from '../../../attachment-block/utils.js';
import { calcBoundByOrigin, readImageSize } from '../components/utils.js';
import { DEFAULT_NOTE_OFFSET_X, DEFAULT_NOTE_OFFSET_Y } from './consts.js';
import { addBlock } from './crud.js';
export async function addAttachments(
std: BlockStdScope,
files: File[],
point?: IVec
): Promise<string[]> {
if (!files.length) return [];
const attachmentService = std.getService('affine:attachment');
const gfx = std.get(GfxControllerIdentifier);
if (!attachmentService) {
console.error('Attachment service not found');
return [];
}
const maxFileSize = attachmentService.maxFileSize;
const isSizeExceeded = files.some(file => file.size > maxFileSize);
if (isSizeExceeded) {
toast(
std.host,
`You can only upload files less than ${humanFileSize(
maxFileSize,
true,
0
)}`
);
return [];
}
let { x, y } = gfx.viewport.center;
if (point) [x, y] = gfx.viewport.toModelCoord(...point);
const CARD_STACK_GAP = 32;
const dropInfos: { blockId: string; file: File }[] = files.map(
(file, index) => {
const point = new Point(
x + index * CARD_STACK_GAP,
y + index * CARD_STACK_GAP
);
const center = Vec.toVec(point);
const bound = Bound.fromCenter(
center,
EMBED_CARD_WIDTH.cubeThick,
EMBED_CARD_HEIGHT.cubeThick
);
const blockId = std.doc.addBlock(
'affine:attachment',
{
name: file.name,
size: file.size,
type: file.type,
style: 'cubeThick',
xywh: bound.serialize(),
} satisfies Partial<AttachmentBlockProps>,
gfx.surface
);
return { blockId, file };
}
);
// upload file and update the attachment model
const uploadPromises = dropInfos.map(async ({ blockId, file }) => {
const filetype = await getFileType(file);
await uploadAttachmentBlob(std.host, blockId, file, filetype, true);
return blockId;
});
const blockIds = await Promise.all(uploadPromises);
gfx.selection.set({
elements: blockIds,
editing: false,
});
return blockIds;
}
export async function addImages(
std: BlockStdScope,
files: File[],