diff --git a/apps/roam/src/components/DiscourseContextOverlay.tsx b/apps/roam/src/components/DiscourseContextOverlay.tsx index 64dd8c6c8..417b68664 100644 --- a/apps/roam/src/components/DiscourseContextOverlay.tsx +++ b/apps/roam/src/components/DiscourseContextOverlay.tsx @@ -15,6 +15,7 @@ import getDiscourseNodes from "~/utils/getDiscourseNodes"; import getDiscourseRelations from "~/utils/getDiscourseRelations"; import ExtensionApiContextProvider from "roamjs-components/components/ExtensionApiContext"; import { OnloadArgs } from "roamjs-components/types/native"; +import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid"; type DiscourseData = { results: Awaited>; @@ -57,15 +58,24 @@ const getOverlayInfo = async (tag: string): Promise => { } }; -const DiscourseContextOverlay = ({ tag, id }: { tag: string; id: string }) => { - const tagUid = useMemo(() => getPageUidByPageTitle(tag), [tag]); +type DiscourseContextOverlayProps = + | { id: string; tag: string; uid?: never } + | { id: string; uid: string; tag?: never } + | { id: string; tag: string; uid: string }; +const DiscourseContextOverlay = ({ + tag, + id, + uid, +}: DiscourseContextOverlayProps) => { + const newTag = tag ?? (uid ? (getPageTitleByPageUid(uid) ?? "") : ""); + const tagUid = uid || getPageUidByPageTitle(newTag); const [loading, setLoading] = useState(true); const [results, setResults] = useState([]); const [refs, setRefs] = useState(0); const [score, setScore] = useState(0); const getInfo = useCallback( () => - getOverlayInfo(tag) + getOverlayInfo(newTag) .then(({ refs, results }) => { const discourseNode = findDiscourseNode(tagUid); if (discourseNode) { diff --git a/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx b/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx index f31f90c34..2ae4eaca8 100644 --- a/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx +++ b/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx @@ -22,7 +22,7 @@ import { TLDefaultFontStyle, DefaultFontStyle, } from "tldraw"; -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useEffect, useRef, useMemo } from "react"; import { useExtensionAPI } from "roamjs-components/components/ExtensionApiContext"; import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; import isLiveBlock from "roamjs-components/queries/isLiveBlock"; @@ -38,8 +38,12 @@ import calcCanvasNodeSizeAndImg from "~/utils/calcCanvasNodeSizeAndImg"; import { createTextJsxFromSpans } from "./DiscourseRelationShape/helpers"; import { loadImage } from "~/utils/loadImage"; import { getRelationColor } from "./DiscourseRelationShape/DiscourseRelationUtil"; -import { AUTO_CANVAS_RELATIONS_KEY } from "~/data/userSettings"; +import { + AUTO_CANVAS_RELATIONS_KEY, + DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, +} from "~/data/userSettings"; import { getSetting } from "~/utils/extensionSettings"; +import DiscourseContextOverlay from "~/components/DiscourseContextOverlay"; // TODO REPLACE WITH TLDRAW DEFAULTS // https://github.com/tldraw/tldraw/pull/1580/files @@ -450,6 +454,11 @@ export class BaseDiscourseNodeUtil extends ShapeUtil { const { canvasSettings: { alias = "", "key-image": isKeyImage = "" } = {}, } = discourseContext.nodes[shape.type] || {}; + // eslint-disable-next-line react-hooks/rules-of-hooks + const isOverlayEnabled = useMemo( + () => getSetting(DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, false), + [], + ); const isEditing = this.editor.getEditingShapeId() === shape.id; // eslint-disable-next-line react-hooks/rules-of-hooks @@ -457,6 +466,8 @@ export class BaseDiscourseNodeUtil extends ShapeUtil { // eslint-disable-next-line react-hooks/rules-of-hooks const [loaded, setLoaded] = useState(""); // eslint-disable-next-line react-hooks/rules-of-hooks + const [overlayMounted, setOverlayMounted] = useState(false); + // eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { if ( shape.props.uid !== loaded && @@ -498,7 +509,11 @@ export class BaseDiscourseNodeUtil extends ShapeUtil { setOverlayMounted(true)} >
{shape.props.imageUrl && isKeyImage ? ( @@ -519,6 +534,17 @@ export class BaseDiscourseNodeUtil extends ShapeUtil { fontSize: FONT_SIZES[shape.props.size], }} > + {overlayMounted && isOverlayEnabled && ( +
e.stopPropagation()} + > + +
+ )} {alias ? new RegExp(alias).exec(shape.props.title)?.[1] || shape.props.title diff --git a/apps/roam/src/components/settings/HomePersonalSettings.tsx b/apps/roam/src/components/settings/HomePersonalSettings.tsx index 77f64cedd..6200b22e9 100644 --- a/apps/roam/src/components/settings/HomePersonalSettings.tsx +++ b/apps/roam/src/components/settings/HomePersonalSettings.tsx @@ -15,9 +15,11 @@ import { import { NodeSearchMenuTriggerSetting } from "../DiscourseNodeSearchMenu"; import { AUTO_CANVAS_RELATIONS_KEY, + DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, DISCOURSE_TOOL_SHORTCUT_KEY, } from "~/data/userSettings"; import KeyboardShortcutInput from "./KeyboardShortcutInput"; +import { getSetting, setSetting } from "~/utils/extensionSettings"; const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { const extensionAPI = onloadArgs.extensionAPI; @@ -177,6 +179,26 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { } /> + { + const target = e.target as HTMLInputElement; + setSetting(DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, target.checked); + }} + labelElement={ + <> + (BETA) Overlay in Canvas + + + } + />
); }; diff --git a/apps/roam/src/data/userSettings.ts b/apps/roam/src/data/userSettings.ts index 89cd8298a..df0fce8fd 100644 --- a/apps/roam/src/data/userSettings.ts +++ b/apps/roam/src/data/userSettings.ts @@ -5,3 +5,5 @@ export const DEFAULT_FILTERS_KEY = "default-filters"; export const QUERY_BUILDER_SETTINGS_KEY = "query-builder-settings"; export const AUTO_CANVAS_RELATIONS_KEY = "auto-canvas-relations"; export const DISCOURSE_TOOL_SHORTCUT_KEY = "discourse-tool-shortcut"; +export const DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY = + "discourse-context-overlay-in-canvas";