fix: render embed linked/synced doc as affine-reference for shared pages (#7179)
fix TOV-779
This commit is contained in:
@@ -46,6 +46,7 @@ function forwardSlot<T extends Record<string, Slot<any>>>(
|
|||||||
interface BlocksuiteEditorContainerProps {
|
interface BlocksuiteEditorContainerProps {
|
||||||
page: Doc;
|
page: Doc;
|
||||||
mode: DocMode;
|
mode: DocMode;
|
||||||
|
shared?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
defaultSelectedBlockId?: string;
|
defaultSelectedBlockId?: string;
|
||||||
@@ -102,7 +103,7 @@ export const BlocksuiteEditorContainer = forwardRef<
|
|||||||
AffineEditorContainer,
|
AffineEditorContainer,
|
||||||
BlocksuiteEditorContainerProps
|
BlocksuiteEditorContainerProps
|
||||||
>(function AffineEditorContainer(
|
>(function AffineEditorContainer(
|
||||||
{ page, mode, className, style, defaultSelectedBlockId },
|
{ page, mode, className, style, defaultSelectedBlockId, shared },
|
||||||
ref
|
ref
|
||||||
) {
|
) {
|
||||||
const scrolledRef = useRef(false);
|
const scrolledRef = useRef(false);
|
||||||
@@ -327,9 +328,13 @@ export const BlocksuiteEditorContainer = forwardRef<
|
|||||||
ref={rootRef}
|
ref={rootRef}
|
||||||
>
|
>
|
||||||
{mode === 'page' ? (
|
{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>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export type ErrorBoundaryProps = {
|
|||||||
export type EditorProps = {
|
export type EditorProps = {
|
||||||
page: Doc;
|
page: Doc;
|
||||||
mode: 'page' | 'edgeless';
|
mode: 'page' | 'edgeless';
|
||||||
|
shared?: boolean;
|
||||||
defaultSelectedBlockId?: string;
|
defaultSelectedBlockId?: string;
|
||||||
// on Editor instance instantiated
|
// on Editor instance instantiated
|
||||||
onLoadEditor?: (editor: AffineEditorContainer) => () => void;
|
onLoadEditor?: (editor: AffineEditorContainer) => () => void;
|
||||||
@@ -54,7 +55,15 @@ function usePageRoot(page: Doc) {
|
|||||||
|
|
||||||
const BlockSuiteEditorImpl = forwardRef<AffineEditorContainer, EditorProps>(
|
const BlockSuiteEditorImpl = forwardRef<AffineEditorContainer, EditorProps>(
|
||||||
function BlockSuiteEditorImpl(
|
function BlockSuiteEditorImpl(
|
||||||
{ mode, page, className, defaultSelectedBlockId, onLoadEditor, style },
|
{
|
||||||
|
mode,
|
||||||
|
page,
|
||||||
|
className,
|
||||||
|
defaultSelectedBlockId,
|
||||||
|
onLoadEditor,
|
||||||
|
shared,
|
||||||
|
style,
|
||||||
|
},
|
||||||
ref
|
ref
|
||||||
) {
|
) {
|
||||||
usePageRoot(page);
|
usePageRoot(page);
|
||||||
@@ -89,6 +98,7 @@ const BlockSuiteEditorImpl = forwardRef<AffineEditorContainer, EditorProps>(
|
|||||||
<BlocksuiteEditorContainer
|
<BlocksuiteEditorContainer
|
||||||
mode={mode}
|
mode={mode}
|
||||||
page={page}
|
page={page}
|
||||||
|
shared={shared}
|
||||||
ref={onRefChange}
|
ref={onRefChange}
|
||||||
className={className}
|
className={className}
|
||||||
style={style}
|
style={style}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
|
|||||||
import { QuickSearchService } from '@affine/core/modules/cmdk';
|
import { QuickSearchService } from '@affine/core/modules/cmdk';
|
||||||
import { PeekViewService } from '@affine/core/modules/peek-view';
|
import { PeekViewService } from '@affine/core/modules/peek-view';
|
||||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||||
import type { BlockSpec } from '@blocksuite/block-std';
|
|
||||||
import {
|
import {
|
||||||
BiDirectionalLinkPanel,
|
BiDirectionalLinkPanel,
|
||||||
DocMetaTags,
|
DocMetaTags,
|
||||||
@@ -16,7 +15,7 @@ import {
|
|||||||
PageEditor,
|
PageEditor,
|
||||||
} from '@blocksuite/presets';
|
} from '@blocksuite/presets';
|
||||||
import type { Doc } from '@blocksuite/store';
|
import type { Doc } from '@blocksuite/store';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { type DocMode, useLiveData, useService } from '@toeverything/infra';
|
||||||
import React, {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
Fragment,
|
Fragment,
|
||||||
@@ -31,6 +30,7 @@ import { PagePropertiesTable } from '../../affine/page-properties';
|
|||||||
import { AffinePageReference } from '../../affine/reference-link';
|
import { AffinePageReference } from '../../affine/reference-link';
|
||||||
import { BlocksuiteEditorJournalDocTitle } from './journal-doc-title';
|
import { BlocksuiteEditorJournalDocTitle } from './journal-doc-title';
|
||||||
import {
|
import {
|
||||||
|
patchForSharedPage,
|
||||||
patchNotificationService,
|
patchNotificationService,
|
||||||
patchPeekViewService,
|
patchPeekViewService,
|
||||||
patchQuickSearchService,
|
patchQuickSearchService,
|
||||||
@@ -66,9 +66,10 @@ const adapted = {
|
|||||||
|
|
||||||
interface BlocksuiteEditorProps {
|
interface BlocksuiteEditorProps {
|
||||||
page: Doc;
|
page: Doc;
|
||||||
|
shared?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => {
|
const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => {
|
||||||
const [reactToLit, portals] = useLitPortalFactory();
|
const [reactToLit, portals] = useLitPortalFactory();
|
||||||
const peekViewService = useService(PeekViewService);
|
const peekViewService = useService(PeekViewService);
|
||||||
const quickSearchService = useService(QuickSearchService);
|
const quickSearchService = useService(QuickSearchService);
|
||||||
@@ -82,6 +83,8 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => {
|
|||||||
};
|
};
|
||||||
}, [page.collection]);
|
}, [page.collection]);
|
||||||
|
|
||||||
|
const specs = mode === 'page' ? PageModeSpecs : EdgelessModeSpecs;
|
||||||
|
|
||||||
const confirmModal = useConfirmModal();
|
const confirmModal = useConfirmModal();
|
||||||
const patchedSpecs = useMemo(() => {
|
const patchedSpecs = useMemo(() => {
|
||||||
let patched = patchReferenceRenderer(specs, reactToLit, referenceRenderer);
|
let patched = patchReferenceRenderer(specs, reactToLit, referenceRenderer);
|
||||||
@@ -95,6 +98,9 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => {
|
|||||||
if (!page.readonly) {
|
if (!page.readonly) {
|
||||||
patched = patchQuickSearchService(patched, quickSearchService);
|
patched = patchQuickSearchService(patched, quickSearchService);
|
||||||
}
|
}
|
||||||
|
if (shared) {
|
||||||
|
patched = patchForSharedPage(patched);
|
||||||
|
}
|
||||||
return patched;
|
return patched;
|
||||||
}, [
|
}, [
|
||||||
confirmModal,
|
confirmModal,
|
||||||
@@ -103,6 +109,7 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => {
|
|||||||
quickSearchService,
|
quickSearchService,
|
||||||
reactToLit,
|
reactToLit,
|
||||||
referenceRenderer,
|
referenceRenderer,
|
||||||
|
shared,
|
||||||
specs,
|
specs,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -124,7 +131,7 @@ const usePatchSpecs = (page: Doc, specs: BlockSpec[]) => {
|
|||||||
export const BlocksuiteDocEditor = forwardRef<
|
export const BlocksuiteDocEditor = forwardRef<
|
||||||
PageEditor,
|
PageEditor,
|
||||||
BlocksuiteEditorProps
|
BlocksuiteEditorProps
|
||||||
>(function BlocksuiteDocEditor({ page }, ref) {
|
>(function BlocksuiteDocEditor({ page, shared }, ref) {
|
||||||
const titleRef = useRef<DocTitle>(null);
|
const titleRef = useRef<DocTitle>(null);
|
||||||
const docRef = useRef<PageEditor | null>(null);
|
const docRef = useRef<PageEditor | null>(null);
|
||||||
const [docPage, setDocPage] =
|
const [docPage, setDocPage] =
|
||||||
@@ -166,7 +173,7 @@ export const BlocksuiteDocEditor = forwardRef<
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [specs, portals] = usePatchSpecs(page, PageModeSpecs);
|
const [specs, portals] = usePatchSpecs(page, !!shared, 'page');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -203,8 +210,8 @@ export const BlocksuiteDocEditor = forwardRef<
|
|||||||
export const BlocksuiteEdgelessEditor = forwardRef<
|
export const BlocksuiteEdgelessEditor = forwardRef<
|
||||||
EdgelessEditor,
|
EdgelessEditor,
|
||||||
BlocksuiteEditorProps
|
BlocksuiteEditorProps
|
||||||
>(function BlocksuiteEdgelessEditor({ page }, ref) {
|
>(function BlocksuiteEdgelessEditor({ page, shared }, ref) {
|
||||||
const [specs, portals] = usePatchSpecs(page, EdgelessModeSpecs);
|
const [specs, portals] = usePatchSpecs(page, !!shared, 'edgeless');
|
||||||
const editorRef = useRef<EdgelessEditor | null>(null);
|
const editorRef = useRef<EdgelessEditor | null>(null);
|
||||||
|
|
||||||
const onDocRef = useCallback(
|
const onDocRef = useCallback(
|
||||||
|
|||||||
@@ -18,10 +18,16 @@ import type { BlockSpec, WidgetElement } from '@blocksuite/block-std';
|
|||||||
import {
|
import {
|
||||||
type AffineReference,
|
type AffineReference,
|
||||||
AffineSlashMenuWidget,
|
AffineSlashMenuWidget,
|
||||||
|
EmbedBlockElement,
|
||||||
|
type EmbedLinkedDocBlockService,
|
||||||
|
type EmbedLinkedDocModel,
|
||||||
type ParagraphBlockService,
|
type ParagraphBlockService,
|
||||||
|
ReferenceNodeConfig,
|
||||||
type RootService,
|
type RootService,
|
||||||
} from '@blocksuite/blocks';
|
} 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';
|
import React, { createElement, type ReactNode } from 'react';
|
||||||
|
|
||||||
const logger = new DebugLogger('affine::spec-patchers');
|
const logger = new DebugLogger('affine::spec-patchers');
|
||||||
@@ -377,3 +383,46 @@ export function patchQuickSearchService(
|
|||||||
|
|
||||||
return specs;
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ const PageDetailEditorMain = memo(function PageDetailEditorMain({
|
|||||||
}
|
}
|
||||||
mode={mode}
|
mode={mode}
|
||||||
page={page}
|
page={page}
|
||||||
|
shared={isPublic}
|
||||||
defaultSelectedBlockId={blockId}
|
defaultSelectedBlockId={blockId}
|
||||||
onLoadEditor={onLoadEditor}
|
onLoadEditor={onLoadEditor}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user