From 32c40bbf098369078c70265b06a2ca32707e0194 Mon Sep 17 00:00:00 2001 From: L-Sun Date: Thu, 3 Jul 2025 12:21:28 +0800 Subject: [PATCH] refactor(core): minimize comment editor (#12995) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### PR Dependency Tree * **PR #12995** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **New Features** * Introduced a new clipboard module, making clipboard-related functionality available for external use. * Added a comprehensive extension system for the comment editor, supporting rich text features, widgets, and configurable options. * **Bug Fixes** * Improved stability by ensuring comment highlighting features and toolbar event subscriptions handle missing dependencies gracefully, preventing potential runtime errors. * **Refactor** * Simplified comment editor view manager setup for easier configuration and maintenance. * **Chores** * Updated package exports to expose new clipboard modules and configurations. * Removed confirm modal and portal-related logic from the comment editor component. * Adjusted temporary store creation to omit adding an extra surface block under the root page. --- blocksuite/affine/all/package.json | 1 + .../affine/all/src/foundation/clipboard.ts | 1 + .../blocks/attachment/src/attachment-block.ts | 8 +- .../blocks/bookmark/src/bookmark-block.ts | 8 +- .../affine/blocks/code/src/code-block.ts | 8 +- .../blocks/database/src/database-block.ts | 8 +- .../embed/src/common/embed-block-element.ts | 8 +- .../affine/blocks/image/src/image-block.ts | 8 +- .../blocks/paragraph/src/paragraph-block.ts | 8 +- .../affine/blocks/root/src/configs/toolbar.ts | 23 ++- .../surface-ref/src/surface-ref-block.ts | 8 +- blocksuite/affine/foundation/package.json | 1 + blocksuite/affine/foundation/src/clipboard.ts | 2 +- .../affine/widgets/toolbar/src/toolbar.ts | 8 +- .../comment/comment-editor/index.tsx | 40 +---- .../comment/comment-editor/specs.ts | 162 ++++++++++++++++++ .../comment/services/snapshot-helper.ts | 3 - 17 files changed, 238 insertions(+), 67 deletions(-) create mode 100644 blocksuite/affine/all/src/foundation/clipboard.ts create mode 100644 packages/frontend/core/src/components/comment/comment-editor/specs.ts diff --git a/blocksuite/affine/all/package.json b/blocksuite/affine/all/package.json index a9d14f869..8bfd36db5 100644 --- a/blocksuite/affine/all/package.json +++ b/blocksuite/affine/all/package.json @@ -285,6 +285,7 @@ "./sync": "./src/sync/index.ts", "./extensions/store": "./src/extensions/store.ts", "./extensions/view": "./src/extensions/view.ts", + "./foundation/clipboard": "./src/foundation/clipboard.ts", "./foundation/store": "./src/foundation/store.ts", "./foundation/view": "./src/foundation/view.ts" }, diff --git a/blocksuite/affine/all/src/foundation/clipboard.ts b/blocksuite/affine/all/src/foundation/clipboard.ts new file mode 100644 index 000000000..ee189e487 --- /dev/null +++ b/blocksuite/affine/all/src/foundation/clipboard.ts @@ -0,0 +1 @@ +export * from '@blocksuite/affine-foundation/clipboard'; diff --git a/blocksuite/affine/blocks/attachment/src/attachment-block.ts b/blocksuite/affine/blocks/attachment/src/attachment-block.ts index 7184ea381..40f88f1a9 100644 --- a/blocksuite/affine/blocks/attachment/src/attachment-block.ts +++ b/blocksuite/affine/blocks/attachment/src/attachment-block.ts @@ -94,9 +94,11 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent { diff --git a/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts b/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts index 9f9eed4de..e363b41a1 100644 --- a/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts +++ b/blocksuite/affine/blocks/bookmark/src/bookmark-block.ts @@ -130,9 +130,11 @@ export class BookmarkBlockComponent extends CaptionedBlockComponent { diff --git a/blocksuite/affine/blocks/code/src/code-block.ts b/blocksuite/affine/blocks/code/src/code-block.ts index d11057f69..df140da6d 100644 --- a/blocksuite/affine/blocks/code/src/code-block.ts +++ b/blocksuite/affine/blocks/code/src/code-block.ts @@ -392,9 +392,11 @@ export class CodeBlockComponent extends CaptionedBlockComponent } get isCommentHighlighted() { - return this.std - .get(BlockCommentManager) - .isBlockCommentHighlighted(this.model); + return ( + this.std + .getOptional(BlockCommentManager) + ?.isBlockCommentHighlighted(this.model) ?? false + ); } override async getUpdateComplete() { diff --git a/blocksuite/affine/blocks/database/src/database-block.ts b/blocksuite/affine/blocks/database/src/database-block.ts index ead546425..11ed65da8 100644 --- a/blocksuite/affine/blocks/database/src/database-block.ts +++ b/blocksuite/affine/blocks/database/src/database-block.ts @@ -313,9 +313,11 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent TemplateResult) => { diff --git a/blocksuite/affine/blocks/image/src/image-block.ts b/blocksuite/affine/blocks/image/src/image-block.ts index 63409fdb6..f50bfbfc9 100644 --- a/blocksuite/affine/blocks/image/src/image-block.ts +++ b/blocksuite/affine/blocks/image/src/image-block.ts @@ -69,9 +69,11 @@ export class ImageBlockComponent extends CaptionedBlockComponent schema.model.flavour); + if ( + supportFlavours.some( + flavour => !std.getOptional(BlockViewIdentifier(flavour)) + ) + ) + return false; + const [ok, { selectedModels }] = chain .pipe(getSelectedModelsCommand, { types: ['block', 'text'], diff --git a/blocksuite/affine/blocks/surface-ref/src/surface-ref-block.ts b/blocksuite/affine/blocks/surface-ref/src/surface-ref-block.ts index ae1aba95a..893f5e793 100644 --- a/blocksuite/affine/blocks/surface-ref/src/surface-ref-block.ts +++ b/blocksuite/affine/blocks/surface-ref/src/surface-ref-block.ts @@ -143,9 +143,11 @@ export class SurfaceRefBlockComponent extends BlockComponent { diff --git a/blocksuite/affine/foundation/package.json b/blocksuite/affine/foundation/package.json index d4e60611a..ba8d998b4 100644 --- a/blocksuite/affine/foundation/package.json +++ b/blocksuite/affine/foundation/package.json @@ -32,6 +32,7 @@ }, "exports": { ".": "./src/index.ts", + "./clipboard": "./src/clipboard.ts", "./store": "./src/store.ts", "./view": "./src/view.ts" }, diff --git a/blocksuite/affine/foundation/src/clipboard.ts b/blocksuite/affine/foundation/src/clipboard.ts index 57d95ddaf..c6b5685cf 100644 --- a/blocksuite/affine/foundation/src/clipboard.ts +++ b/blocksuite/affine/foundation/src/clipboard.ts @@ -43,7 +43,7 @@ const imageClipboardConfigs = [ }); }); -const PlainTextClipboardConfig = ClipboardAdapterConfigExtension({ +export const PlainTextClipboardConfig = ClipboardAdapterConfigExtension({ mimeType: 'text/plain', adapter: MixTextAdapter, priority: 70, diff --git a/blocksuite/affine/widgets/toolbar/src/toolbar.ts b/blocksuite/affine/widgets/toolbar/src/toolbar.ts index fe002876d..3d10946b0 100644 --- a/blocksuite/affine/widgets/toolbar/src/toolbar.ts +++ b/blocksuite/affine/widgets/toolbar/src/toolbar.ts @@ -579,9 +579,11 @@ export class AffineToolbarWidget extends WidgetComponent { ); // Handles elements when resizing - const edgelessSlots = std.get(EdgelessLegacySlotIdentifier); - disposables.add(edgelessSlots.elementResizeStart.subscribe(dragStart)); - disposables.add(edgelessSlots.elementResizeEnd.subscribe(dragEnd)); + const edgelessSlots = std.getOptional(EdgelessLegacySlotIdentifier); + if (edgelessSlots) { + disposables.add(edgelessSlots.elementResizeStart.subscribe(dragStart)); + disposables.add(edgelessSlots.elementResizeEnd.subscribe(dragEnd)); + } // Handles elements when hovering disposables.add( diff --git a/packages/frontend/core/src/components/comment/comment-editor/index.tsx b/packages/frontend/core/src/components/comment/comment-editor/index.tsx index 30f85c10a..97efb7aaa 100644 --- a/packages/frontend/core/src/components/comment/comment-editor/index.tsx +++ b/packages/frontend/core/src/components/comment/comment-editor/index.tsx @@ -1,6 +1,4 @@ -import { useConfirmModal, useLitPortalFactory } from '@affine/component'; import { LitDocEditor, type PageEditor } from '@affine/core/blocksuite/editors'; -import { getViewManager } from '@affine/core/blocksuite/manager/view'; import { SnapshotHelper } from '@affine/core/modules/comment/services/snapshot-helper'; import type { RichText } from '@blocksuite/affine/rich-text'; import { ViewportElementExtension } from '@blocksuite/affine/shared/services'; @@ -10,7 +8,6 @@ import { useFramework, useService } from '@toeverything/infra'; import clsx from 'clsx'; import { forwardRef, - Fragment, useCallback, useEffect, useImperativeHandle, @@ -19,45 +16,21 @@ import { useState, } from 'react'; +import { getCommentEditorViewManager } from './specs'; import * as styles from './style.css'; const usePatchSpecs = (readonly: boolean) => { - const [reactToLit, portals] = useLitPortalFactory(); const framework = useFramework(); - const confirmModal = useConfirmModal(); + // const confirmModal = useConfirmModal(); const patchedSpecs = useMemo(() => { - const manager = getViewManager() - .config.init() - .foundation(framework) - .theme(framework) - .editorConfig(framework) - .editorView({ - framework, - reactToLit, - confirmModal, - }) - .linkedDoc(framework) - .paragraph(false) - .codeBlockHtmlPreview(framework).value; + const manager = getCommentEditorViewManager(framework); return manager .get(readonly ? 'preview-page' : 'page') .concat([ViewportElementExtension('.comment-editor-viewport')]); - }, [confirmModal, framework, reactToLit, readonly]); + }, [framework, readonly]); - return [ - patchedSpecs, - useMemo( - () => ( - <> - {portals.map(p => ( - {p.portal} - ))} - - ), - [portals] - ), - ] as const; + return patchedSpecs; }; interface CommentEditorProps { @@ -115,7 +88,7 @@ export const CommentEditor = forwardRef( if (!defaultSnapshotOrDoc) { throw new Error('Either defaultSnapshot or doc must be provided'); } - const [specs, portals] = usePatchSpecs(!!readonly); + const specs = usePatchSpecs(!!readonly); const doc = useSnapshotDoc(defaultSnapshotOrDoc, readonly); const snapshotHelper = useService(SnapshotHelper); const editorRef = useRef(null); @@ -196,7 +169,6 @@ export const CommentEditor = forwardRef( className={clsx(styles.container, 'comment-editor-viewport')} > {doc && } - {portals} {!readonly && (