From 679e9e1966f20ad684bd7c1fb1cd3baacad94234 Mon Sep 17 00:00:00 2001 From: pengx17 Date: Wed, 2 Apr 2025 02:21:32 +0000 Subject: [PATCH] feat(core): add copy link to doc peek view controls (#11373) fix AF-2314 --- .../peek-view/view/peek-view-controls.tsx | 40 ++++++++++++++++++- packages/frontend/i18n/src/i18n.gen.ts | 4 ++ packages/frontend/i18n/src/resources/en.json | 1 + 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/packages/frontend/core/src/modules/peek-view/view/peek-view-controls.tsx b/packages/frontend/core/src/modules/peek-view/view/peek-view-controls.tsx index 1dd334ce4..8a6b8dd9e 100644 --- a/packages/frontend/core/src/modules/peek-view/view/peek-view-controls.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/peek-view-controls.tsx @@ -1,4 +1,5 @@ -import { IconButton } from '@affine/component'; +import { IconButton, notify } from '@affine/component'; +import { copyTextToClipboard } from '@affine/core/utils/clipboard'; import { useI18n } from '@affine/i18n'; import track from '@affine/track'; import type { DocMode } from '@blocksuite/affine/model'; @@ -6,6 +7,7 @@ import { CloseIcon, ExpandFullIcon, InformationIcon, + LinkIcon, OpenInNewIcon, SplitViewIcon, } from '@blocksuite/icons/rc'; @@ -21,7 +23,10 @@ import { useMemo, } from 'react'; +import { ServerService } from '../../cloud'; import { WorkspaceDialogService } from '../../dialogs'; +import { DocsService } from '../../doc/services/docs'; +import { toURLSearchParams } from '../../navigation'; import { WorkbenchService } from '../../workbench'; import type { AttachmentPeekViewInfo, @@ -105,6 +110,8 @@ export const DocPeekViewControls = ({ const workbench = useService(WorkbenchService).workbench; const t = useI18n(); const workspaceDialogService = useService(WorkspaceDialogService); + const serverService = useService(ServerService); + const docsService = useService(DocsService); const controls = useMemo(() => { return [ { @@ -140,6 +147,27 @@ export const DocPeekViewControls = ({ peekView.close(false); }, }, + { + icon: , + nameKey: 'copy-link', + name: t['com.affine.peek-view-controls.copy-link'](), + onClick: async () => { + const preferredMode = docsService.list.getPrimaryMode(docRef.docId); + const search = toURLSearchParams({ + mode: docRef.mode || preferredMode, + blockIds: docRef.blockIds, + elementIds: docRef.elementIds, + xywh: docRef.xywh, + }); + const url = new URL( + workbench.basename$.value + '/' + docRef.docId, + serverService.server.baseUrl + ); + if (search?.size) url.search = search.toString(); + await copyTextToClipboard(url.toString()); + notify.success({ title: t['Copied link to clipboard']() }); + }, + }, { icon: , nameKey: 'info', @@ -149,7 +177,15 @@ export const DocPeekViewControls = ({ }, }, ].filter((opt): opt is ControlButtonProps => Boolean(opt)); - }, [t, peekView, workbench, docRef, workspaceDialogService]); + }, [ + t, + peekView, + workbench, + docRef, + docsService.list, + serverService.server.baseUrl, + workspaceDialogService, + ]); return (
{controls.map(option => ( diff --git a/packages/frontend/i18n/src/i18n.gen.ts b/packages/frontend/i18n/src/i18n.gen.ts index e6bd98b27..8749010cc 100644 --- a/packages/frontend/i18n/src/i18n.gen.ts +++ b/packages/frontend/i18n/src/i18n.gen.ts @@ -4379,6 +4379,10 @@ export function useAFFiNEI18N(): { * `Open in center peek` */ ["com.affine.peek-view-controls.open-doc-in-center-peek"](): string; + /** + * `Copy link` + */ + ["com.affine.peek-view-controls.copy-link"](): string; /** * `Click or drag` */ diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 8573a2ea3..983cda218 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -1086,6 +1086,7 @@ "com.affine.peek-view-controls.open-attachment-in-new-tab": "Open in new tab", "com.affine.peek-view-controls.open-attachment-in-split-view": "Open in split view", "com.affine.peek-view-controls.open-doc-in-center-peek": "Open in center peek", + "com.affine.peek-view-controls.copy-link": "Copy link", "com.affine.split-view-drag-handle.tooltip": "Click or drag", "com.affine.split-view-folder-warning.description": "Split view does not support folders.", "do-not-show-this-again": "Do not show this again",