mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 06:18:45 +08:00
feat(core): enhance share page with selector (#8319)
Closes [BS-1346](https://linear.app/affine-design/issue/BS-1346/白板上的-link-to-block-在只读模式下打开无法跳转和高亮) <div class='graphite__hidden'> <div>🎥 Video uploaded on Graphite:</div> <a href="https://app.graphite.dev/media/video/8ypiIKZXudF5a0tIgIzf/84bb27a9-608f-4cfc-a4c8-58de8aa5d791.mov"> <img src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/8ypiIKZXudF5a0tIgIzf/84bb27a9-608f-4cfc-a4c8-58de8aa5d791.mov"> </a> </div> <video src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/8ypiIKZXudF5a0tIgIzf/84bb27a9-608f-4cfc-a4c8-58de8aa5d791.mov">Screen Recording 2024-09-20 at 06.21.45.mov</video>
This commit is contained in:
@@ -3,12 +3,14 @@ import { AppFallback } from '@affine/core/components/affine/app-container';
|
||||
import { EditorOutlineViewer } from '@affine/core/components/blocksuite/outline-viewer';
|
||||
import { useActiveBlocksuiteEditor } from '@affine/core/components/hooks/use-block-suite-editor';
|
||||
import { usePageDocumentTitle } from '@affine/core/components/hooks/use-global-state';
|
||||
import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-helper';
|
||||
import { PageDetailEditor } from '@affine/core/components/page-detail-editor';
|
||||
import { SharePageNotFoundError } from '@affine/core/components/share-page-not-found-error';
|
||||
import { AppContainer, MainContainer } from '@affine/core/components/workspace';
|
||||
import { AuthService } from '@affine/core/modules/cloud';
|
||||
import {
|
||||
type Editor,
|
||||
type EditorSelector,
|
||||
EditorService,
|
||||
EditorsService,
|
||||
} from '@affine/core/modules/editor';
|
||||
@@ -17,7 +19,12 @@ import { ShareReaderService } from '@affine/core/modules/share-doc';
|
||||
import { CloudBlobStorage } from '@affine/core/modules/workspace-engine';
|
||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { type DocMode, DocModes } from '@blocksuite/blocks';
|
||||
import {
|
||||
type DocMode,
|
||||
DocModes,
|
||||
RefNodeSlotsProvider,
|
||||
} from '@blocksuite/blocks';
|
||||
import { DisposableGroup } from '@blocksuite/global/utils';
|
||||
import { Logo1Icon } from '@blocksuite/icons/rc';
|
||||
import type { AffineEditorContainer } from '@blocksuite/presets';
|
||||
import type { Doc, Workspace } from '@toeverything/infra';
|
||||
@@ -57,16 +64,29 @@ export const SharePage = ({
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
const { mode, isTemplate, templateName, templateSnapshotUrl } =
|
||||
const { mode, selector, isTemplate, templateName, templateSnapshotUrl } =
|
||||
useMemo(() => {
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
const queryStringMode = searchParams.get('mode') as DocMode | null;
|
||||
const blockIds = searchParams
|
||||
.get('blockIds')
|
||||
?.split(',')
|
||||
.filter(v => v.length);
|
||||
const elementIds = searchParams
|
||||
.get('elementIds')
|
||||
?.split(',')
|
||||
.filter(v => v.length);
|
||||
|
||||
return {
|
||||
mode:
|
||||
queryStringMode && DocModes.includes(queryStringMode)
|
||||
? queryStringMode
|
||||
: null,
|
||||
selector: {
|
||||
blockIds,
|
||||
elementIds,
|
||||
refreshKey: searchParams.get('refreshKey') || undefined,
|
||||
},
|
||||
isTemplate: searchParams.has('isTemplate'),
|
||||
templateName: searchParams.get('templateName') || '',
|
||||
templateSnapshotUrl: searchParams.get('snapshotUrl') || '',
|
||||
@@ -94,6 +114,7 @@ export const SharePage = ({
|
||||
workspaceBinary={data.workspaceBinary}
|
||||
docBinary={data.docBinary}
|
||||
publishMode={mode || data.publishMode}
|
||||
selector={selector}
|
||||
isTemplate={isTemplate}
|
||||
templateName={templateName}
|
||||
templateSnapshotUrl={templateSnapshotUrl}
|
||||
@@ -110,6 +131,7 @@ const SharePageInner = ({
|
||||
workspaceBinary,
|
||||
docBinary,
|
||||
publishMode = 'page' as DocMode,
|
||||
selector,
|
||||
isTemplate,
|
||||
templateName,
|
||||
templateSnapshotUrl,
|
||||
@@ -119,6 +141,7 @@ const SharePageInner = ({
|
||||
workspaceBinary: Uint8Array;
|
||||
docBinary: Uint8Array;
|
||||
publishMode?: DocMode;
|
||||
selector?: EditorSelector;
|
||||
isTemplate?: boolean;
|
||||
templateName?: string;
|
||||
templateSnapshotUrl?: string;
|
||||
@@ -180,6 +203,10 @@ const SharePageInner = ({
|
||||
const editor = doc.scope.get(EditorsService).createEditor();
|
||||
editor.setMode(publishMode);
|
||||
|
||||
if (selector) {
|
||||
editor.setSelector(selector);
|
||||
}
|
||||
|
||||
setEditor(editor);
|
||||
})
|
||||
.catch(err => {
|
||||
@@ -190,11 +217,13 @@ const SharePageInner = ({
|
||||
workspaceId,
|
||||
workspacesService,
|
||||
publishMode,
|
||||
selector,
|
||||
workspaceBinary,
|
||||
docBinary,
|
||||
]);
|
||||
|
||||
const pageTitle = useLiveData(page?.title$);
|
||||
const { jumpToPageBlock, openPage } = useNavigateHelper();
|
||||
|
||||
usePageDocumentTitle(pageTitle);
|
||||
|
||||
@@ -209,12 +238,35 @@ const SharePageInner = ({
|
||||
editorContainer,
|
||||
(editorContainer as any).docTitle
|
||||
);
|
||||
|
||||
const disposable = new DisposableGroup();
|
||||
const refNodeSlots =
|
||||
editorContainer.host?.std.getOptional(RefNodeSlotsProvider);
|
||||
if (refNodeSlots) {
|
||||
disposable.add(
|
||||
refNodeSlots.docLinkClicked.on(({ pageId, params }) => {
|
||||
if (params) {
|
||||
const { mode, blockIds, elementIds } = params;
|
||||
return jumpToPageBlock(
|
||||
workspaceId,
|
||||
pageId,
|
||||
mode,
|
||||
blockIds,
|
||||
elementIds
|
||||
);
|
||||
}
|
||||
|
||||
return openPage(workspaceId, pageId);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return () => {
|
||||
unbind();
|
||||
editor.setEditorContainer(null);
|
||||
};
|
||||
},
|
||||
[editor, setActiveBlocksuiteEditor]
|
||||
[editor, setActiveBlocksuiteEditor, jumpToPageBlock, openPage, workspaceId]
|
||||
);
|
||||
|
||||
if (!workspace || !page || !editor) {
|
||||
|
||||
Reference in New Issue
Block a user