Skip to content

Commit b74dd1c

Browse files
committed
feat(core): support block links on Bi-Directional Links (#8169)
Clsoes [AF-1348](https://linear.app/affine-design/issue/AF-1348/修复-bi-directional-links-里面的链接地址) * Links to the current document should be ignored on `Backlinks` * Links to the current document should be ignored on `Outgoing links` https://github.com/user-attachments/assets/dbc43cea-5aca-4c6f-886a-356e3a91c1f1
1 parent b7d05d2 commit b74dd1c

File tree

10 files changed

+221
-98
lines changed

10 files changed

+221
-98
lines changed

packages/frontend/core/src/components/affine/reference-link/index.tsx

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ export interface PageReferenceRendererOptions {
3535
journalHelper: ReturnType<typeof useJournalHelper>;
3636
t: ReturnType<typeof useI18n>;
3737
docMode?: DocMode;
38-
// linking doc with block or element
39-
blockIds?: string[];
40-
elementIds?: string[];
38+
// Link to block or element
39+
linkToNode?: boolean;
4140
}
4241
// use a function to be rendered in the lit renderer
4342
export function pageReferenceRenderer({
@@ -46,8 +45,7 @@ export function pageReferenceRenderer({
4645
journalHelper,
4746
t,
4847
docMode,
49-
blockIds,
50-
elementIds,
48+
linkToNode = false,
5149
}: PageReferenceRendererOptions) {
5250
const { isPageJournal, getLocalizedJournalDateString } = journalHelper;
5351
const referencedPage = pageMetaHelper.getDocMeta(pageId);
@@ -62,7 +60,7 @@ export function pageReferenceRenderer({
6260
} else {
6361
Icon = LinkedPageIcon;
6462
}
65-
if (blockIds?.length || elementIds?.length) {
63+
if (linkToNode) {
6664
Icon = BlockLinkIcon;
6765
}
6866
}
@@ -89,33 +87,33 @@ export function AffinePageReference({
8987
docCollection,
9088
wrapper: Wrapper,
9189
mode = 'page',
92-
params = {},
90+
params,
9391
}: {
9492
pageId: string;
9593
docCollection: DocCollection;
9694
wrapper?: React.ComponentType<PropsWithChildren>;
9795
mode?: DocMode;
98-
params?: {
99-
mode?: DocMode;
100-
blockIds?: string[];
101-
elementIds?: string[];
102-
};
96+
params?: URLSearchParams;
10397
}) {
10498
const pageMetaHelper = useDocMetaHelper(docCollection);
10599
const journalHelper = useJournalHelper(docCollection);
106100
const t = useI18n();
107101

108-
const { mode: linkedWithMode, blockIds, elementIds } = params;
102+
let linkWithMode: DocMode | null = null;
103+
let linkToNode = false;
104+
if (params) {
105+
linkWithMode = params.get('mode') as DocMode;
106+
linkToNode = params.has('blockIds') || params.has('elementIds');
107+
}
109108

110109
const el = pageReferenceRenderer({
111-
docMode: linkedWithMode ?? mode,
110+
docMode: linkWithMode ?? mode,
112111
pageId,
113112
pageMetaHelper,
114113
journalHelper,
115114
docCollection,
116115
t,
117-
blockIds,
118-
elementIds,
116+
linkToNode,
119117
});
120118

121119
const ref = useRef<HTMLAnchorElement>(null);
@@ -154,20 +152,11 @@ export function AffinePageReference({
154152

155153
const query = useMemo(() => {
156154
// A block/element reference link
157-
const search = new URLSearchParams();
158-
if (linkedWithMode) {
159-
search.set('mode', linkedWithMode);
160-
}
161-
if (blockIds?.length) {
162-
search.set('blockIds', blockIds.join(','));
163-
}
164-
if (elementIds?.length) {
165-
search.set('elementIds', elementIds.join(','));
166-
}
167-
search.set('refreshKey', refreshKey);
168-
169-
return search.size > 0 ? `?${search.toString()}` : '';
170-
}, [blockIds, elementIds, linkedWithMode, refreshKey]);
155+
let str = params?.toString() ?? '';
156+
if (str.length) str += '&';
157+
str += `refreshKey=${refreshKey}`;
158+
return '?' + str;
159+
}, [params, refreshKey]);
171160

172161
return (
173162
<WorkbenchLink

packages/frontend/core/src/components/blocksuite/block-suite-editor/bi-directional-link-panel.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,14 @@ export const BiDirectionalLinkPanel = () => {
6363
{t['com.affine.page-properties.outgoing-links']()} ·{' '}
6464
{links.length}
6565
</div>
66-
{links.map(link => (
67-
<div key={link.docId} className={styles.link}>
66+
{links.map((link, i) => (
67+
<div
68+
key={`${link.docId}-${link.params?.toString()}-${i}`}
69+
className={styles.link}
70+
>
6871
<AffinePageReference
6972
pageId={link.docId}
73+
params={link.params}
7074
docCollection={workspaceService.workspace.docCollection}
7175
/>
7276
</div>

packages/frontend/core/src/components/blocksuite/block-suite-editor/lit-adaper.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
77
import { EditorService } from '@affine/core/modules/editor';
88
import { EditorSettingService } from '@affine/core/modules/editor-settting';
99
import { PeekViewService } from '@affine/core/modules/peek-view';
10+
import { toURLSearchParams } from '@affine/core/utils';
1011
import type { DocMode } from '@blocksuite/blocks';
1112
import { DocTitle, EdgelessEditor, PageEditor } from '@blocksuite/presets';
1213
import type { Doc } from '@blocksuite/store';
@@ -90,12 +91,14 @@ const usePatchSpecs = (page: Doc, shared: boolean, mode: DocMode) => {
9091
const pageId = data.pageId;
9192
if (!pageId) return <span />;
9293

94+
const params = toURLSearchParams(data.params);
95+
9396
return (
9497
<AffinePageReference
9598
docCollection={page.collection}
9699
pageId={pageId}
97100
mode={mode}
98-
params={data.params}
101+
params={params}
99102
/>
100103
);
101104
};

packages/frontend/core/src/modules/doc-link/entities/doc-links.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { DocsSearchService } from '../../docs-search';
66
export interface Link {
77
docId: string;
88
title: string;
9+
params?: URLSearchParams;
910
}
1011

1112
export class DocLinks extends Entity {

packages/frontend/core/src/modules/docs-search/entities/docs-indexer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class DocsIndexer extends Entity {
3636
/**
3737
* increase this number to re-index all docs
3838
*/
39-
static INDEXER_VERSION = 1;
39+
static INDEXER_VERSION = 2;
4040

4141
private readonly jobQueue: JobQueue<IndexerJobPayload> =
4242
new IndexedDBJobQueue<IndexerJobPayload>(

packages/frontend/core/src/modules/docs-search/schema.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ export const blockIndexSchema = defineSchema({
1111
blockId: 'String',
1212
content: 'FullText',
1313
flavour: 'String',
14-
ref: 'String',
1514
blob: 'String',
15+
// reference doc id
16+
// ['xxx','yyy']
17+
refDocId: 'String',
18+
// reference info
19+
// [{"docId":"xxx","mode":"page","blockIds":["gt5Yfq1maYvgNgpi13rIq"]},{"docId":"yyy","mode":"edgeless","blockIds":["k5prpOlDF-9CzfatmO0W7"]}]
20+
ref: 'String',
1621
});
1722

1823
export type BlockIndexSchema = typeof blockIndexSchema;

0 commit comments

Comments
 (0)