From b5406fa57ad1e2187200b01eb42a74a61323ca9a Mon Sep 17 00:00:00 2001 From: fundon Date: Wed, 19 Mar 2025 12:34:18 +0000 Subject: [PATCH] refactor(editor): edgeless image toolbar config extension (#10718) --- .../blocks/block-image/src/configs/toolbar.ts | 58 +++++++++++++++++++ .../blocks/block-image/src/image-spec.ts | 11 ++-- .../src/edgeless/configs/toolbar/image.ts | 11 ---- .../src/edgeless/configs/toolbar/index.ts | 6 -- 4 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 blocksuite/affine/blocks/block-image/src/configs/toolbar.ts delete mode 100644 blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/image.ts diff --git a/blocksuite/affine/blocks/block-image/src/configs/toolbar.ts b/blocksuite/affine/blocks/block-image/src/configs/toolbar.ts new file mode 100644 index 0000000000..71d9586682 --- /dev/null +++ b/blocksuite/affine/blocks/block-image/src/configs/toolbar.ts @@ -0,0 +1,58 @@ +import { ImageBlockModel } from '@blocksuite/affine-model'; +import { + type ToolbarModuleConfig, + ToolbarModuleExtension, +} from '@blocksuite/affine-shared/services'; +import { BlockFlavourIdentifier } from '@blocksuite/block-std'; +import { CaptionIcon, DownloadIcon } from '@blocksuite/icons/lit'; +import type { ExtensionType } from '@blocksuite/store'; + +import { ImageEdgelessBlockComponent } from '../image-edgeless-block'; + +const trackBaseProps = { + category: 'image', + type: 'card view', +}; + +const builtinSurfaceToolbarConfig = { + actions: [ + { + id: 'a.download', + tooltip: 'Download', + icon: DownloadIcon(), + run(ctx) { + const block = ctx.getCurrentBlockByType(ImageEdgelessBlockComponent); + block?.download(); + }, + }, + { + id: 'b.caption', + tooltip: 'Caption', + icon: CaptionIcon(), + run(ctx) { + const block = ctx.getCurrentBlockByType(ImageEdgelessBlockComponent); + block?.captionEditor?.show(); + + ctx.track('OpenedCaptionEditor', { + ...trackBaseProps, + control: 'add caption', + }); + }, + }, + ], + + when: ctx => ctx.getSurfaceModelsByType(ImageBlockModel).length === 1, +} as const satisfies ToolbarModuleConfig; + +export const createBuiltinToolbarConfigExtension = ( + flavour: string +): ExtensionType[] => { + const name = flavour.split(':').pop(); + + return [ + ToolbarModuleExtension({ + id: BlockFlavourIdentifier(`affine:surface:${name}`), + config: builtinSurfaceToolbarConfig, + }), + ]; +}; diff --git a/blocksuite/affine/blocks/block-image/src/image-spec.ts b/blocksuite/affine/blocks/block-image/src/image-spec.ts index cd80484d25..1071d7c13f 100644 --- a/blocksuite/affine/blocks/block-image/src/image-spec.ts +++ b/blocksuite/affine/blocks/block-image/src/image-spec.ts @@ -1,3 +1,4 @@ +import { ImageBlockSchema } from '@blocksuite/affine-model'; import { SlashMenuConfigExtension } from '@blocksuite/affine-widget-slash-menu'; import { BlockViewExtension, @@ -8,14 +9,15 @@ import type { ExtensionType } from '@blocksuite/store'; import { literal } from 'lit/static-html.js'; import { ImageBlockAdapterExtensions } from './adapters/extension'; -import { imageSlashMenuConfig } from './configs/slash-menu.js'; +import { imageSlashMenuConfig } from './configs/slash-menu'; +import { createBuiltinToolbarConfigExtension } from './configs/toolbar'; import { ImageProxyService } from './image-proxy-service'; import { ImageBlockService, ImageDropOption } from './image-service'; -const flavour = 'affine:image'; +const flavour = ImageBlockSchema.model.flavour; export const imageToolbarWidget = WidgetViewExtension( - 'affine:image', + flavour, 'imageToolbar', literal`affine-image-toolbar-widget` ); @@ -35,7 +37,8 @@ export const ImageBlockSpec: ExtensionType[] = [ imageToolbarWidget, ImageDropOption, ImageBlockAdapterExtensions, - SlashMenuConfigExtension('affine:image', imageSlashMenuConfig), + createBuiltinToolbarConfigExtension(flavour), + SlashMenuConfigExtension(flavour, imageSlashMenuConfig), ].flat(); export const ImageStoreSpec: ExtensionType[] = [ImageProxyService]; diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/image.ts b/blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/image.ts deleted file mode 100644 index 1a0e5030eb..0000000000 --- a/blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/image.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ToolbarModuleConfig } from '@blocksuite/affine-shared/services'; - -export const builtinImageToolbarConfig = { - actions: [ - { - id: 'a.test', - label: 'Image', - run() {}, - }, - ], -} as const satisfies ToolbarModuleConfig; diff --git a/blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/index.ts b/blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/index.ts index 3890dc3536..e8d589e982 100644 --- a/blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/index.ts +++ b/blocksuite/affine/blocks/block-root/src/edgeless/configs/toolbar/index.ts @@ -6,7 +6,6 @@ import { builtinBrushToolbarConfig } from './brush'; import { builtinConnectorToolbarConfig } from './connector'; import { builtinFrameToolbarConfig } from './frame'; import { builtinGroupToolbarConfig } from './group'; -import { builtinImageToolbarConfig } from './image'; import { builtinMindmapToolbarConfig } from './mindmap'; import { builtinMiscToolbarConfig } from './misc'; import { builtinNoteToolbarConfig } from './note'; @@ -14,11 +13,6 @@ import { builtinShapeToolbarConfig } from './shape'; import { builtinTextToolbarConfig } from './text'; export const EdgelessElementToolbarExtension: ExtensionType[] = [ - ToolbarModuleExtension({ - id: BlockFlavourIdentifier('affine:surface:image'), - config: builtinImageToolbarConfig, - }), - ToolbarModuleExtension({ id: BlockFlavourIdentifier('affine:surface:brush'), config: builtinBrushToolbarConfig,