Skip to content

Commit b776e72

Browse files
authored
ENG-788 - Add Discourse Context Overlay to tldraw canvas (#380)
* Enhance DiscourseNodeUtil and HomePersonalSettings with overlay functionality - Introduced DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY to manage the visibility of the Discourse Context overlay in the canvas. - Updated HomePersonalSettings to include a checkbox for enabling/disabling the overlay feature. - Integrated useMemo in DiscourseNodeUtil to optimize the overlay setting retrieval. - Added conditional rendering for the DiscourseContextOverlay in the canvas based on the overlay state. * Refactor DiscourseContextOverlay to support uid prop and improve tag handling - Updated DiscourseContextOverlay to accept uid prop, allowing for more flexible tag resolution. - Refactored getOverlayInfo call to utilize the new tag logic based on uid or tag. - Adjusted DiscourseNodeUtil to pass uid instead of deriving tag from it, enhancing clarity and functionality. * .
1 parent 19ebc63 commit b776e72

4 files changed

Lines changed: 66 additions & 6 deletions

File tree

apps/roam/src/components/DiscourseContextOverlay.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import getDiscourseNodes from "~/utils/getDiscourseNodes";
1515
import getDiscourseRelations from "~/utils/getDiscourseRelations";
1616
import ExtensionApiContextProvider from "roamjs-components/components/ExtensionApiContext";
1717
import { OnloadArgs } from "roamjs-components/types/native";
18+
import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid";
1819

1920
type DiscourseData = {
2021
results: Awaited<ReturnType<typeof getDiscourseContextResults>>;
@@ -57,15 +58,24 @@ const getOverlayInfo = async (tag: string): Promise<DiscourseData> => {
5758
}
5859
};
5960

60-
const DiscourseContextOverlay = ({ tag, id }: { tag: string; id: string }) => {
61-
const tagUid = useMemo(() => getPageUidByPageTitle(tag), [tag]);
61+
type DiscourseContextOverlayProps =
62+
| { id: string; tag: string; uid?: never }
63+
| { id: string; uid: string; tag?: never }
64+
| { id: string; tag: string; uid: string };
65+
const DiscourseContextOverlay = ({
66+
tag,
67+
id,
68+
uid,
69+
}: DiscourseContextOverlayProps) => {
70+
const newTag = tag ?? (uid ? (getPageTitleByPageUid(uid) ?? "") : "");
71+
const tagUid = uid || getPageUidByPageTitle(newTag);
6272
const [loading, setLoading] = useState(true);
6373
const [results, setResults] = useState<DiscourseData["results"]>([]);
6474
const [refs, setRefs] = useState(0);
6575
const [score, setScore] = useState<number | string>(0);
6676
const getInfo = useCallback(
6777
() =>
68-
getOverlayInfo(tag)
78+
getOverlayInfo(newTag)
6979
.then(({ refs, results }) => {
7080
const discourseNode = findDiscourseNode(tagUid);
7181
if (discourseNode) {

apps/roam/src/components/canvas/DiscourseNodeUtil.tsx

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
TLDefaultFontStyle,
2323
DefaultFontStyle,
2424
} from "tldraw";
25-
import React, { useState, useEffect, useRef } from "react";
25+
import React, { useState, useEffect, useRef, useMemo } from "react";
2626
import { useExtensionAPI } from "roamjs-components/components/ExtensionApiContext";
2727
import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle";
2828
import isLiveBlock from "roamjs-components/queries/isLiveBlock";
@@ -38,8 +38,12 @@ import calcCanvasNodeSizeAndImg from "~/utils/calcCanvasNodeSizeAndImg";
3838
import { createTextJsxFromSpans } from "./DiscourseRelationShape/helpers";
3939
import { loadImage } from "~/utils/loadImage";
4040
import { getRelationColor } from "./DiscourseRelationShape/DiscourseRelationUtil";
41-
import { AUTO_CANVAS_RELATIONS_KEY } from "~/data/userSettings";
41+
import {
42+
AUTO_CANVAS_RELATIONS_KEY,
43+
DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY,
44+
} from "~/data/userSettings";
4245
import { getSetting } from "~/utils/extensionSettings";
46+
import DiscourseContextOverlay from "~/components/DiscourseContextOverlay";
4347

4448
// TODO REPLACE WITH TLDRAW DEFAULTS
4549
// https://github.com/tldraw/tldraw/pull/1580/files
@@ -450,13 +454,20 @@ export class BaseDiscourseNodeUtil extends ShapeUtil<DiscourseNodeShape> {
450454
const {
451455
canvasSettings: { alias = "", "key-image": isKeyImage = "" } = {},
452456
} = discourseContext.nodes[shape.type] || {};
457+
// eslint-disable-next-line react-hooks/rules-of-hooks
458+
const isOverlayEnabled = useMemo(
459+
() => getSetting(DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, false),
460+
[],
461+
);
453462

454463
const isEditing = this.editor.getEditingShapeId() === shape.id;
455464
// eslint-disable-next-line react-hooks/rules-of-hooks
456465
const contentRef = useRef<HTMLDivElement>(null);
457466
// eslint-disable-next-line react-hooks/rules-of-hooks
458467
const [loaded, setLoaded] = useState("");
459468
// eslint-disable-next-line react-hooks/rules-of-hooks
469+
const [overlayMounted, setOverlayMounted] = useState(false);
470+
// eslint-disable-next-line react-hooks/rules-of-hooks
460471
useEffect(() => {
461472
if (
462473
shape.props.uid !== loaded &&
@@ -498,7 +509,11 @@ export class BaseDiscourseNodeUtil extends ShapeUtil<DiscourseNodeShape> {
498509
<HTMLContainer
499510
id={shape.id}
500511
className="roamjs-tldraw-node pointer-events-auto flex items-center justify-center overflow-hidden rounded-2xl"
501-
style={{ background: backgroundColor, color: textColor }}
512+
style={{
513+
background: backgroundColor,
514+
color: textColor,
515+
}}
516+
onPointerEnter={() => setOverlayMounted(true)}
502517
>
503518
<div style={{ pointerEvents: "all" }}>
504519
{shape.props.imageUrl && isKeyImage ? (
@@ -519,6 +534,17 @@ export class BaseDiscourseNodeUtil extends ShapeUtil<DiscourseNodeShape> {
519534
fontSize: FONT_SIZES[shape.props.size],
520535
}}
521536
>
537+
{overlayMounted && isOverlayEnabled && (
538+
<div
539+
className="roamjs-discourse-context-overlay-container absolute right-0 top-0"
540+
onPointerDown={(e) => e.stopPropagation()}
541+
>
542+
<DiscourseContextOverlay
543+
uid={shape.props.uid}
544+
id={`${shape.id}-overlay`}
545+
/>
546+
</div>
547+
)}
522548
{alias
523549
? new RegExp(alias).exec(shape.props.title)?.[1] ||
524550
shape.props.title

apps/roam/src/components/settings/HomePersonalSettings.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import {
1515
import { NodeSearchMenuTriggerSetting } from "../DiscourseNodeSearchMenu";
1616
import {
1717
AUTO_CANVAS_RELATIONS_KEY,
18+
DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY,
1819
DISCOURSE_TOOL_SHORTCUT_KEY,
1920
} from "~/data/userSettings";
2021
import KeyboardShortcutInput from "./KeyboardShortcutInput";
22+
import { getSetting, setSetting } from "~/utils/extensionSettings";
2123

2224
const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => {
2325
const extensionAPI = onloadArgs.extensionAPI;
@@ -177,6 +179,26 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => {
177179
</>
178180
}
179181
/>
182+
<Checkbox
183+
defaultChecked={getSetting(
184+
DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY,
185+
false,
186+
)}
187+
onChange={(e) => {
188+
const target = e.target as HTMLInputElement;
189+
setSetting(DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, target.checked);
190+
}}
191+
labelElement={
192+
<>
193+
(BETA) Overlay in Canvas
194+
<Description
195+
description={
196+
"Whether or not to overlay Discourse Context information over Canvas Nodes."
197+
}
198+
/>
199+
</>
200+
}
201+
/>
180202
</div>
181203
);
182204
};

apps/roam/src/data/userSettings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ export const DEFAULT_FILTERS_KEY = "default-filters";
55
export const QUERY_BUILDER_SETTINGS_KEY = "query-builder-settings";
66
export const AUTO_CANVAS_RELATIONS_KEY = "auto-canvas-relations";
77
export const DISCOURSE_TOOL_SHORTCUT_KEY = "discourse-tool-shortcut";
8+
export const DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY =
9+
"discourse-context-overlay-in-canvas";

0 commit comments

Comments
 (0)