From ab26e0f3602167908269513daa4e8affa93a9cf2 Mon Sep 17 00:00:00 2001 From: pengx17 Date: Fri, 7 Jun 2024 11:42:48 +0000 Subject: [PATCH] fix: render embed linked/synced doc as affine-reference for shared pages (#7179) fix TOV-779 --- .../blocksuite-editor-container.tsx | 11 ++-- .../block-suite-editor/blocksuite-editor.tsx | 12 ++++- .../block-suite-editor/lit-adaper.tsx | 21 +++++--- .../specs/custom/spec-patchers.tsx | 51 ++++++++++++++++++- .../src/components/page-detail-editor.tsx | 1 + 5 files changed, 84 insertions(+), 12 deletions(-) diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx index 693db046ad..f8fab4519c 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor-container.tsx @@ -46,6 +46,7 @@ function forwardSlot>>( interface BlocksuiteEditorContainerProps { page: Doc; mode: DocMode; + shared?: boolean; className?: string; style?: React.CSSProperties; defaultSelectedBlockId?: string; @@ -102,7 +103,7 @@ export const BlocksuiteEditorContainer = forwardRef< AffineEditorContainer, BlocksuiteEditorContainerProps >(function AffineEditorContainer( - { page, mode, className, style, defaultSelectedBlockId }, + { page, mode, className, style, defaultSelectedBlockId, shared }, ref ) { const scrolledRef = useRef(false); @@ -327,9 +328,13 @@ export const BlocksuiteEditorContainer = forwardRef< ref={rootRef} > {mode === 'page' ? ( - + ) : ( - + )} ); diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx index 8f39e7c0f8..d551b025fe 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/blocksuite-editor.tsx @@ -23,6 +23,7 @@ export type ErrorBoundaryProps = { export type EditorProps = { page: Doc; mode: 'page' | 'edgeless'; + shared?: boolean; defaultSelectedBlockId?: string; // on Editor instance instantiated onLoadEditor?: (editor: AffineEditorContainer) => () => void; @@ -54,7 +55,15 @@ function usePageRoot(page: Doc) { const BlockSuiteEditorImpl = forwardRef( function BlockSuiteEditorImpl( - { mode, page, className, defaultSelectedBlockId, onLoadEditor, style }, + { + mode, + page, + className, + defaultSelectedBlockId, + onLoadEditor, + shared, + style, + }, ref ) { usePageRoot(page); @@ -89,6 +98,7 @@ const BlockSuiteEditorImpl = forwardRef( { +const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => { const [reactToLit, portals] = useLitPortalFactory(); const peekViewService = useService(PeekViewService); const quickSearchService = useService(QuickSearchService); @@ -82,6 +83,8 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => { }; }, [page.collection]); + const specs = mode === 'page' ? PageModeSpecs : EdgelessModeSpecs; + const confirmModal = useConfirmModal(); const patchedSpecs = useMemo(() => { let patched = patchReferenceRenderer(specs, reactToLit, referenceRenderer); @@ -95,6 +98,9 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => { if (!page.readonly) { patched = patchQuickSearchService(patched, quickSearchService); } + if (shared) { + patched = patchForSharedPage(patched); + } return patched; }, [ confirmModal, @@ -103,6 +109,7 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => { quickSearchService, reactToLit, referenceRenderer, + shared, specs, ]); @@ -124,7 +131,7 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => { export const BlocksuiteDocEditor = forwardRef< PageEditor, BlocksuiteEditorProps ->(function BlocksuiteDocEditor({ page }, ref) { +>(function BlocksuiteDocEditor({ page, shared }, ref) { const titleRef = useRef(null); const docRef = useRef(null); const [docPage, setDocPage] = @@ -166,7 +173,7 @@ export const BlocksuiteDocEditor = forwardRef< // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const [specs, portals] = usePatchSpecs(page, PageModeSpecs); + const [specs, portals] = usePatchSpecs(page, !!shared, 'page'); return ( <> @@ -203,8 +210,8 @@ export const BlocksuiteDocEditor = forwardRef< export const BlocksuiteEdgelessEditor = forwardRef< EdgelessEditor, BlocksuiteEditorProps ->(function BlocksuiteEdgelessEditor({ page }, ref) { - const [specs, portals] = usePatchSpecs(page, EdgelessModeSpecs); +>(function BlocksuiteEdgelessEditor({ page, shared }, ref) { + const [specs, portals] = usePatchSpecs(page, !!shared, 'edgeless'); const editorRef = useRef(null); const onDocRef = useCallback( diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx index 482c98f3d0..01f4b97bdd 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/specs/custom/spec-patchers.tsx @@ -18,10 +18,16 @@ import type { BlockSpec, WidgetElement } from '@blocksuite/block-std'; import { type AffineReference, AffineSlashMenuWidget, + EmbedBlockElement, + type EmbedLinkedDocBlockService, + type EmbedLinkedDocModel, type ParagraphBlockService, + ReferenceNodeConfig, type RootService, } from '@blocksuite/blocks'; -import { LitElement, type TemplateResult } from 'lit'; +import { html, LitElement, type TemplateResult } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { literal } from 'lit/static-html.js'; import React, { createElement, type ReactNode } from 'react'; const logger = new DebugLogger('affine::spec-patchers'); @@ -377,3 +383,46 @@ export function patchQuickSearchService( return specs; } + +@customElement('affine-linked-doc-ref-block') +export class LinkedDocBlockComponent extends EmbedBlockElement< + EmbedLinkedDocModel, + EmbedLinkedDocBlockService +> { + referenceNodeConfig = new ReferenceNodeConfig(); + override render() { + this.referenceNodeConfig.setDoc(this.model.doc); + return html``; + } +} + +export function patchForSharedPage(specs: BlockSpec[]) { + return specs.map(spec => { + const linkedDocNames = [ + 'affine:embed-linked-doc', + 'affine:embed-synced-doc', + ]; + + if (linkedDocNames.includes(spec.schema.model.flavour)) { + spec = { + ...spec, + view: { + component: literal`affine-linked-doc-ref-block`, + widgets: {}, + }, + }; + } + return spec; + }); +} diff --git a/packages/frontend/core/src/components/page-detail-editor.tsx b/packages/frontend/core/src/components/page-detail-editor.tsx index 5d100e69d3..434df66ec8 100644 --- a/packages/frontend/core/src/components/page-detail-editor.tsx +++ b/packages/frontend/core/src/components/page-detail-editor.tsx @@ -114,6 +114,7 @@ const PageDetailEditorMain = memo(function PageDetailEditorMain({ } mode={mode} page={page} + shared={isPublic} defaultSelectedBlockId={blockId} onLoadEditor={onLoadEditor} />