From 9789edad4cc2c3cc84dbab2ec730c39de31907ed Mon Sep 17 00:00:00 2001 From: 01zulfi <85733202+01zulfi@users.noreply.github.com> Date: Thu, 12 Mar 2026 10:17:32 +0500 Subject: [PATCH] editor: show internal link's note title in hover popup Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com> --- apps/web/src/components/editor/tiptap.tsx | 8 ++++++++ packages/editor/src/index.ts | 3 +++ packages/editor/src/toolbar/tools/link.tsx | 20 +++++++++++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/apps/web/src/components/editor/tiptap.tsx b/apps/web/src/components/editor/tiptap.tsx index a80977140..2ba994bd8 100644 --- a/apps/web/src/components/editor/tiptap.tsx +++ b/apps/web/src/components/editor/tiptap.tsx @@ -69,6 +69,7 @@ import { UpgradeDialog } from "../../dialogs/buy-dialog/upgrade-dialog"; import { ConfirmDialog } from "../../dialogs/confirm"; import { strings } from "@notesnook/intl"; import { handleInternalLink } from "../../common"; +import { db } from "../../common/db"; export type OnChangeHandler = ( content: () => string, @@ -426,6 +427,13 @@ function TipTap(props: TipTapProps) { const link = parseInternalLink(url); if (link) handleInternalLink(url, openInNewTab); else window.open(url, "_blank"); + }, + getLinkTitle: async (url) => { + const link = parseInternalLink(url); + if (link && link.type === "note") { + const note = await db.notes.note(link.id); + return note?.title; + } } }; }, [ diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index 122c4bc77..4a046c3ca 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -94,6 +94,7 @@ interface TiptapStorage { timeFormat?: DateTimeOptions["timeFormat"]; dayFormat?: DateTimeOptions["dayFormat"]; openLink?: (url: string, openInNewTab?: boolean) => void; + getLinkTitle?: (url: string) => Promise; downloadAttachment?: (attachment: Attachment) => void; openAttachmentPicker?: (type: AttachmentType) => void; previewAttachment?: (attachment: Attachment) => void; @@ -148,6 +149,7 @@ const useTiptap = ( openAttachmentPicker, previewAttachment, openLink, + getLinkTitle, onBeforeCreate, dateFormat, timeFormat, @@ -395,6 +397,7 @@ const useTiptap = ( editor.storage.createInternalLink = createInternalLink; editor.storage.getAttachmentData = getAttachmentData; editor.storage.downloadCsvTable = downloadCsvTable; + editor.storage.getLinkTitle = getLinkTitle; if (onBeforeCreate) onBeforeCreate({ editor }); }, diff --git a/packages/editor/src/toolbar/tools/link.tsx b/packages/editor/src/toolbar/tools/link.tsx index 266ac363c..add82b175 100644 --- a/packages/editor/src/toolbar/tools/link.tsx +++ b/packages/editor/src/toolbar/tools/link.tsx @@ -19,7 +19,7 @@ along with this program. If not, see . import { ToolProps } from "../types.js"; import { ToolButton } from "../components/tool-button.js"; -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { ResponsivePresenter } from "../../components/responsive/index.js"; import { LinkPopup } from "../popups/link-popup.js"; import { useToolbarLocation } from "../stores/toolbar-store.js"; @@ -204,9 +204,19 @@ export function OpenLink(props: ToolProps) { ); const { node } = selectedNode.current || {}; const link = node ? findMark(node, "link") : null; - if (!link) return null; - const href = link?.attrs.href; - if (!href) return null; + const href = link?.attrs.href ?? null; + const [title, setTitle] = useState(href ?? ""); + + useEffect(() => { + if (!href) return; + + (async () => { + const result = await editor.storage.getLinkTitle?.(href); + setTitle(result || href); + })(); + }, [href]); + + if (!link || !href) return null; return ( @@ -232,7 +242,7 @@ export function OpenLink(props: ToolProps) { ":hover": { color: "accent", opacity: 0.8 } }} > - {href} + {title}