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
@@ -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,
@@ -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';
@@ -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[],
@@ -1,3 +1,7 @@
import {
type AttachmentBlockComponent,
attachmentViewToggleMenu,
} from '@blocksuite/affine-block-attachment';
import { getEmbedCardIcons } from '@blocksuite/affine-block-embed';
import {
CaptionIcon,
@@ -18,8 +22,6 @@ import { property } from 'lit/decorators.js';
import { join } from 'lit/directives/join.js';
import type { EmbedCardStyle } from '../../../_common/types.js';
import type { AttachmentBlockComponent } from '../../../attachment-block/index.js';
import { attachmentViewToggleMenu } from '../../../attachment-block/index.js';
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
export class EdgelessChangeAttachmentButton extends WithDisposable(LitElement) {
@@ -1,3 +1,4 @@
import type { AttachmentBlockComponent } from '@blocksuite/affine-block-attachment';
import type { BookmarkBlockComponent } from '@blocksuite/affine-block-bookmark';
import type {
EmbedFigmaBlockComponent,
@@ -31,7 +32,6 @@ import {
notifyDocCreated,
promptDocTitle,
} from '../../../../_common/utils/render-linked-doc.js';
import type { AttachmentBlockComponent } from '../../../../attachment-block/attachment-block.js';
import type { ImageBlockComponent } from '../../../../image-block/image-block.js';
import { duplicate } from '../../../edgeless/utils/clipboard-utils.js';
import { getSortedCloneElements } from '../../../edgeless/utils/clone-utils.js';
@@ -1,3 +1,4 @@
import { addSiblingAttachmentBlocks } from '@blocksuite/affine-block-attachment';
import {
getInlineEditorByModel,
insertContent,
@@ -60,7 +61,6 @@ import { cssVarV2 } from '@toeverything/theme/v2';
import type { TemplateResult } from 'lit';
import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js';
import { addSiblingAttachmentBlocks } from '../../../attachment-block/utils.js';
import { getSurfaceBlock } from '../../../surface-ref-block/utils.js';
import type { PageRootBlockComponent } from '../../page/page-root-block.js';
import { formatDate, formatTime } from '../../utils/misc.js';
@@ -1,3 +1,4 @@
import { addSiblingAttachmentBlocks } from '@blocksuite/affine-block-attachment';
import {
FigmaIcon,
GithubIcon,
@@ -49,7 +50,6 @@ import type { TemplateResult } from 'lit';
import { toggleEmbedCardCreateModal } from '../../../_common/components/embed-card/modal/embed-card-create-modal.js';
import { textConversionConfigs } from '../../../_common/configs/text-conversion.js';
import { addSiblingAttachmentBlocks } from '../../../attachment-block/utils.js';
import type { DataViewBlockComponent } from '../../../data-view-block/index.js';
import { getSurfaceBlock } from '../../../surface-ref-block/utils.js';
import type { RootBlockComponent } from '../../types.js';