fix: render embed linked/synced doc as affine-reference for shared pages (#7179)

fix TOV-779
This commit is contained in:
pengx17
2024-06-07 11:42:48 +00:00
parent 8dc3fd2a99
commit ab26e0f360
5 changed files with 84 additions and 12 deletions

View File

@@ -46,6 +46,7 @@ function forwardSlot<T extends Record<string, Slot<any>>>(
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' ? (
<BlocksuiteDocEditor page={page} ref={docRef} />
<BlocksuiteDocEditor shared={shared} page={page} ref={docRef} />
) : (
<BlocksuiteEdgelessEditor page={page} ref={edgelessRef} />
<BlocksuiteEdgelessEditor
shared={shared}
page={page}
ref={edgelessRef}
/>
)}
</div>
);

View File

@@ -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<AffineEditorContainer, EditorProps>(
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<AffineEditorContainer, EditorProps>(
<BlocksuiteEditorContainer
mode={mode}
page={page}
shared={shared}
ref={onRefChange}
className={className}
style={style}

View File

@@ -7,7 +7,6 @@ import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import { QuickSearchService } from '@affine/core/modules/cmdk';
import { PeekViewService } from '@affine/core/modules/peek-view';
import { WorkbenchService } from '@affine/core/modules/workbench';
import type { BlockSpec } from '@blocksuite/block-std';
import {
BiDirectionalLinkPanel,
DocMetaTags,
@@ -16,7 +15,7 @@ import {
PageEditor,
} from '@blocksuite/presets';
import type { Doc } from '@blocksuite/store';
import { useLiveData, useService } from '@toeverything/infra';
import { type DocMode, useLiveData, useService } from '@toeverything/infra';
import React, {
forwardRef,
Fragment,
@@ -31,6 +30,7 @@ import { PagePropertiesTable } from '../../affine/page-properties';
import { AffinePageReference } from '../../affine/reference-link';
import { BlocksuiteEditorJournalDocTitle } from './journal-doc-title';
import {
patchForSharedPage,
patchNotificationService,
patchPeekViewService,
patchQuickSearchService,
@@ -66,9 +66,10 @@ const adapted = {
interface BlocksuiteEditorProps {
page: Doc;
shared?: boolean;
}
const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => {
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<DocTitle>(null);
const docRef = useRef<PageEditor | null>(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<EdgelessEditor | null>(null);
const onDocRef = useCallback(

View File

@@ -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`<affine-reference
.delta=${{
insert: '',
attributes: {
reference: {
type: 'LinkedPage',
pageId: this.model.pageId,
},
},
} as const}
.config=${this.referenceNodeConfig}
></affine-reference>`;
}
}
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;
});
}

View File

@@ -114,6 +114,7 @@ const PageDetailEditorMain = memo(function PageDetailEditorMain({
}
mode={mode}
page={page}
shared={isPublic}
defaultSelectedBlockId={blockId}
onLoadEditor={onLoadEditor}
/>