From 70e4c8feab5c6527d8f945d51b949e807034d984 Mon Sep 17 00:00:00 2001 From: pengx17 Date: Fri, 27 Dec 2024 13:47:06 +0000 Subject: [PATCH] feat(core): info modal should render backlinks with preview (#9387) fix AF-2033 --- .../bi-directional-link-panel.css.ts | 8 + .../bi-directional-link-panel.tsx | 251 ++++++++++-------- .../desktop/dialogs/doc-info/info-modal.tsx | 5 +- .../desktop/dialogs/doc-info/links-row.css.ts | 9 +- .../desktop/dialogs/doc-info/links-row.tsx | 28 +- .../mobile/components/doc-info/doc-info.tsx | 2 + 6 files changed, 171 insertions(+), 132 deletions(-) diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.css.ts b/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.css.ts index a61032987..953dbf477 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.css.ts +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.css.ts @@ -89,6 +89,14 @@ globalStyle(`${link} .affine-reference-title`, { borderBottom: 'none', }); +globalStyle(`${link} svg`, { + color: cssVarV2('icon/secondary'), +}); + +globalStyle(`${link}:hover svg`, { + color: cssVarV2('icon/primary'), +}); + export const linkPreviewContainer = style({ display: 'flex', flexDirection: 'column', diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.tsx index 9225fa6fa..11f76f4aa 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.tsx @@ -160,29 +160,13 @@ const usePreviewExtensions = () => { return [extensions, portals] as const; }; -export const BiDirectionalLinkPanel = () => { - const { docLinksService, workspaceService, docService } = useServices({ +const useBacklinkGroups = () => { + const { docLinksService } = useServices({ DocLinksService, - WorkspaceService, - DocService, }); - const [extensions, portals] = usePreviewExtensions(); - const t = useI18n(); - - const [show, setShow] = useBiDirectionalLinkPanelCollapseState( - docService.doc.id - ); - - const links = useLiveData( - show ? docLinksService.links.links$ : new LiveData([] as Link[]) - ); const backlinkGroups = useLiveData( LiveData.computed(get => { - if (!show) { - return []; - } - const links = get(docLinksService.backlinks.backlinks$); // group by docId @@ -202,17 +186,17 @@ export const BiDirectionalLinkPanel = () => { }) ); - const backlinkCount = useMemo(() => { - return backlinkGroups.reduce((acc, link) => acc + link.links.length, 0); - }, [backlinkGroups]); + return backlinkGroups; +}; - const handleClickShow = useCallback(() => { - setShow(!show); - track.doc.biDirectionalLinksPanel.$.toggle({ - type: show ? 'collapse' : 'expand', - }); - }, [show, setShow]); +export const BacklinkGroups = () => { + const [extensions, portals] = usePreviewExtensions(); + const { workspaceService, docService } = useServices({ + WorkspaceService, + DocService, + }); + const backlinkGroups = useBacklinkGroups(); const textRendererOptions = useMemo(() => { const docLinkBaseURLMiddleware: JobMiddleware = ({ adapterConfigs }) => { adapterConfigs.set( @@ -228,6 +212,128 @@ export const BiDirectionalLinkPanel = () => { }; }, [extensions, workspaceService.workspace.id]); + return ( + <> + {backlinkGroups.map(linkGroup => ( + { + track.doc.biDirectionalLinksPanel.backlinkTitle.navigate(); + }} + /> + } + length={linkGroup.links.length} + docId={docService.doc.id} + linkDocId={linkGroup.docId} + > +
+ {linkGroup.links.map(link => { + if (!link.markdownPreview) { + return null; + } + const searchParams = new URLSearchParams(); + const displayMode = link.displayMode || 'page'; + searchParams.set('mode', displayMode); + + let blockId = link.blockId; + if ( + link.parentFlavour === 'affine:database' && + link.parentBlockId + ) { + // if parentBlockFlavour is 'affine:database', + // we will fallback to the database block instead + blockId = link.parentBlockId; + } else if (displayMode === 'edgeless' && link.noteBlockId) { + // if note has displayMode === 'edgeless' && has noteBlockId, + // set noteBlockId as blockId + blockId = link.noteBlockId; + } + + searchParams.set('blockIds', blockId); + + const to = { + pathname: '/' + linkGroup.docId, + search: '?' + searchParams.toString(), + hash: '', + }; + + // if this backlink has no noteBlock && displayMode is edgeless, we will render + // the link as a page link + const edgelessLink = + displayMode === 'edgeless' && !link.noteBlockId; + + return ( + { + track.doc.biDirectionalLinksPanel.backlinkPreview.navigate(); + }} + > + {edgelessLink ? ( + <> + [Edgeless] + + + ) : ( + + )} + + ); + })} +
+
+ ))} + <> + {portals.map(p => ( + {p.portal} + ))} + + + ); +}; + +export const BiDirectionalLinkPanel = () => { + const { docLinksService, docService } = useServices({ + DocLinksService, + DocService, + }); + + const t = useI18n(); + + const [show, setShow] = useBiDirectionalLinkPanelCollapseState( + docService.doc.id + ); + + const links = useLiveData( + show ? docLinksService.links.links$ : new LiveData([] as Link[]) + ); + + const backlinkGroups = useBacklinkGroups(); + + const backlinkCount = useMemo(() => { + return backlinkGroups.reduce((acc, link) => acc + link.links.length, 0); + }, [backlinkGroups]); + + const handleClickShow = useCallback(() => { + setShow(!show); + track.doc.biDirectionalLinksPanel.$.toggle({ + type: show ? 'collapse' : 'expand', + }); + }, [show, setShow]); return (
{!show && ( @@ -254,89 +360,7 @@ export const BiDirectionalLinkPanel = () => {
{t['com.affine.page-properties.backlinks']()} · {backlinkCount}
- {backlinkGroups.map(linkGroup => ( - { - track.doc.biDirectionalLinksPanel.backlinkTitle.navigate(); - }} - /> - } - length={linkGroup.links.length} - docId={docService.doc.id} - linkDocId={linkGroup.docId} - > -
- {linkGroup.links.map(link => { - if (!link.markdownPreview) { - return null; - } - const searchParams = new URLSearchParams(); - const displayMode = link.displayMode || 'page'; - searchParams.set('mode', displayMode); - - let blockId = link.blockId; - if ( - link.parentFlavour === 'affine:database' && - link.parentBlockId - ) { - // if parentBlockFlavour is 'affine:database', - // we will fallback to the database block instead - blockId = link.parentBlockId; - } else if (displayMode === 'edgeless' && link.noteBlockId) { - // if note has displayMode === 'edgeless' && has noteBlockId, - // set noteBlockId as blockId - blockId = link.noteBlockId; - } - - searchParams.set('blockIds', blockId); - - const to = { - pathname: '/' + linkGroup.docId, - search: '?' + searchParams.toString(), - hash: '', - }; - - // if this backlink has no noteBlock && displayMode is edgeless, we will render - // the link as a page link - const edgelessLink = - displayMode === 'edgeless' && !link.noteBlockId; - - return ( - { - track.doc.biDirectionalLinksPanel.backlinkPreview.navigate(); - }} - > - {edgelessLink ? ( - <> - [Edgeless] - - - ) : ( - - )} - - ); - })} -
-
- ))} +
@@ -354,13 +378,6 @@ export const BiDirectionalLinkPanel = () => {
)} - { - <> - {portals.map(p => ( - {p.portal} - ))} - - }
); }; diff --git a/packages/frontend/core/src/desktop/dialogs/doc-info/info-modal.tsx b/packages/frontend/core/src/desktop/dialogs/doc-info/info-modal.tsx index 22182b05a..74a57e555 100644 --- a/packages/frontend/core/src/desktop/dialogs/doc-info/info-modal.tsx +++ b/packages/frontend/core/src/desktop/dialogs/doc-info/info-modal.tsx @@ -5,6 +5,7 @@ import { PropertyCollapsibleContent, PropertyCollapsibleSection, } from '@affine/component'; +import { BacklinkGroups } from '@affine/core/components/blocksuite/block-suite-editor/bi-directional-link-panel'; import { CreatePropertyMenuItems } from '@affine/core/components/doc-properties/menu/create-doc-property'; import { DocPropertyRow } from '@affine/core/components/doc-properties/table'; import type { DocCustomPropertyInfo } from '@affine/core/modules/db'; @@ -162,7 +163,8 @@ export const InfoTable = ({ {backlinks && backlinks.length > 0 ? ( <> } onClick={onClose} label={t['com.affine.page-properties.backlinks']()} /> @@ -172,6 +174,7 @@ export const InfoTable = ({ {links && links.length > 0 ? ( <> void; }) => { return ( - {references.map(link => ( - - ))} + {Array.isArray(references) + ? references.map(link => ( + + )) + : references} ); }; diff --git a/packages/frontend/core/src/mobile/components/doc-info/doc-info.tsx b/packages/frontend/core/src/mobile/components/doc-info/doc-info.tsx index a86d00afd..1b121a49d 100644 --- a/packages/frontend/core/src/mobile/components/doc-info/doc-info.tsx +++ b/packages/frontend/core/src/mobile/components/doc-info/doc-info.tsx @@ -131,6 +131,7 @@ export const DocInfoSheet = ({ @@ -141,6 +142,7 @@ export const DocInfoSheet = ({