diff --git a/apps/roam/src/components/DiscourseContextOverlay.tsx b/apps/roam/src/components/DiscourseContextOverlay.tsx index ae262442b..70b130132 100644 --- a/apps/roam/src/components/DiscourseContextOverlay.tsx +++ b/apps/roam/src/components/DiscourseContextOverlay.tsx @@ -37,8 +37,12 @@ const getOverlayInfo = async ( ignoreCache?: boolean, ): Promise => { try { - const relations = getDiscourseRelations(); - const nodes = getDiscourseNodes(relations); + const trace = { + source: "DiscourseContextOverlay:getOverlayInfo", + content: tag, + }; + const relations = getDiscourseRelations(undefined, trace); + const nodes = getDiscourseNodes(relations, undefined, trace); const [results, refs] = await Promise.all([ getDiscourseContextResults({ diff --git a/apps/roam/src/components/DiscourseNodeMenu.tsx b/apps/roam/src/components/DiscourseNodeMenu.tsx index 60680e00f..f2721d8a0 100644 --- a/apps/roam/src/components/DiscourseNodeMenu.tsx +++ b/apps/roam/src/components/DiscourseNodeMenu.tsx @@ -27,9 +27,13 @@ import { getNewDiscourseNodeText } from "~/utils/formatUtils"; import { OnloadArgs } from "roamjs-components/types"; import { formatHexColor } from "./settings/DiscourseNodeCanvasSettings"; import posthog from "posthog-js"; -import { setPersonalSetting } from "~/components/settings/utils/accessors"; +import { + setPersonalSetting, + type SettingsSnapshot, +} from "~/components/settings/utils/accessors"; import { PERSONAL_KEYS } from "~/components/settings/utils/settingKeys"; import type { PersonalSettings } from "~/components/settings/utils/zodSchema"; +import type { PerformanceTraceContext } from "~/utils/performanceLogger"; type Props = { textarea?: HTMLTextAreaElement; @@ -38,6 +42,24 @@ type Props = { trigger?: JSX.Element; isShift?: boolean; menuMaxHeight?: number; + trace?: PerformanceTraceContext; + settingsSnapshot?: SettingsSnapshot; + getSettingsSnapshot?: (trace?: PerformanceTraceContext) => SettingsSnapshot; +}; + +const compactTraceContent = (content?: string): string | undefined => { + const compacted = content?.replace(/\s+/g, " ").trim(); + return compacted ? compacted.slice(0, 120) : undefined; +}; + +const getNodeMenuTraceContent = ({ + trace, + textarea, + blockUid, +}: Pick): string | undefined => { + if (trace?.content) return compactTraceContent(trace.content); + if (blockUid) return `blockUid:${blockUid}`; + return compactTraceContent(textarea?.value); }; const NodeMenu = ({ @@ -48,6 +70,9 @@ const NodeMenu = ({ trigger, isShift, menuMaxHeight, + trace, + settingsSnapshot, + getSettingsSnapshot, }: { onClose: () => void } & Props) => { const isInitialTextSelected = !!textarea && textarea.selectionStart !== textarea.selectionEnd; @@ -55,10 +80,24 @@ const NodeMenu = ({ const [showNodeTypes, setShowNodeTypes] = useState( isInitialTextSelected || (isShift ?? false), ); - const userDiscourseNodes = useMemo( - () => getDiscourseNodes().filter((n) => n.backedBy === "user"), - [], - ); + const userDiscourseNodes = useMemo(() => { + const traceContext = { + source: trace?.source ?? "component:DiscourseNodeMenu:userDiscourseNodes", + content: getNodeMenuTraceContent({ trace, textarea, blockUid }), + }; + return getDiscourseNodes( + undefined, + settingsSnapshot ?? getSettingsSnapshot?.(traceContext), + traceContext, + ).filter((n) => n.backedBy === "user"); + }, [ + blockUid, + getSettingsSnapshot, + settingsSnapshot, + textarea, + trace?.content, + trace?.source, + ]); const discourseNodes = userDiscourseNodes.filter( (n) => showNodeTypes || n.tag, ); @@ -359,10 +398,12 @@ export const TextSelectionNodeMenu = ({ textarea, extensionAPI, onClose, + settingsSnapshot, }: { textarea: HTMLTextAreaElement; extensionAPI: OnloadArgs["extensionAPI"]; onClose: () => void; + settingsSnapshot?: SettingsSnapshot; }) => { const trigger = (