From afbe9d5f8c0829aced5925ef47783f32930c588e Mon Sep 17 00:00:00 2001 From: sid597 Date: Thu, 26 Feb 2026 10:53:44 +0530 Subject: [PATCH 1/4] Rebase ENG-1468 onto eng-1472 (fresh redo) --- .../components/DiscourseContextOverlay.tsx | 12 +++--- .../settings/DiscourseNodeCanvasSettings.tsx | 40 +++++++++++++------ .../settings/DiscourseNodeSpecification.tsx | 13 +++++- .../settings/DiscourseRelationConfigPanel.tsx | 30 ++++++++------ .../src/components/settings/NodeConfig.tsx | 17 ++++---- apps/roam/src/index.ts | 12 +----- .../src/utils/deriveDiscourseNodeAttribute.ts | 19 ++++----- 7 files changed, 80 insertions(+), 63 deletions(-) diff --git a/apps/roam/src/components/DiscourseContextOverlay.tsx b/apps/roam/src/components/DiscourseContextOverlay.tsx index c2a9a1720..f8cbf16b8 100644 --- a/apps/roam/src/components/DiscourseContextOverlay.tsx +++ b/apps/roam/src/components/DiscourseContextOverlay.tsx @@ -12,8 +12,7 @@ import { ContextContent } from "./DiscourseContext"; import useInViewport from "react-in-viewport/dist/es/lib/useInViewport"; import normalizePageTitle from "roamjs-components/queries/normalizePageTitle"; import deriveDiscourseNodeAttribute from "~/utils/deriveDiscourseNodeAttribute"; -import getSettingValueFromTree from "roamjs-components/util/getSettingValueFromTree"; -import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid"; +import { getDiscourseNodeSetting } from "~/components/settings/utils/accessors"; import nanoid from "nanoid"; import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; import getDiscourseContextResults from "~/utils/getDiscourseContextResults"; @@ -180,11 +179,10 @@ const useDiscourseContext = (uid: string, tag: string) => { .then(({ refs, results }) => { const discourseNode = findDiscourseNode({ uid: uid }); if (discourseNode) { - const attribute = getSettingValueFromTree({ - tree: getBasicTreeByParentUid(discourseNode.type), - key: "Overlay", - defaultValue: "Overlay", - }); + const attribute = + getDiscourseNodeSetting(discourseNode.type, [ + "overlay", + ]) || "Overlay"; return deriveDiscourseNodeAttribute({ uid: uid, attribute, diff --git a/apps/roam/src/components/settings/DiscourseNodeCanvasSettings.tsx b/apps/roam/src/components/settings/DiscourseNodeCanvasSettings.tsx index 287f4194b..7caea89cf 100644 --- a/apps/roam/src/components/settings/DiscourseNodeCanvasSettings.tsx +++ b/apps/roam/src/components/settings/DiscourseNodeCanvasSettings.tsx @@ -7,15 +7,16 @@ import { Icon, ControlGroup, } from "@blueprintjs/core"; -import React, { useState, useMemo } from "react"; -import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid"; -import getSettingValueFromTree from "roamjs-components/util/getSettingValueFromTree"; +import React, { useState } from "react"; import setInputSetting from "roamjs-components/util/setInputSetting"; import { DiscourseNodeFlagPanel, DiscourseNodeTextPanel, } from "./components/BlockPropSettingPanels"; -import { setDiscourseNodeSetting } from "~/components/settings/utils/accessors"; +import { + getDiscourseNodeSetting, + setDiscourseNodeSetting, +} from "~/components/settings/utils/accessors"; export const formatHexColor = (color: string) => { if (!color) return ""; @@ -36,20 +37,35 @@ const DiscourseNodeCanvasSettings = ({ nodeType: string; uid: string; }) => { - const tree = useMemo(() => getBasicTreeByParentUid(uid), [uid]); const [color, setColor] = useState(() => { - const color = getSettingValueFromTree({ tree, key: "color" }); + const color = + getDiscourseNodeSetting(nodeType, ["canvasSettings", "color"]) ?? + ""; return formatHexColor(color); }); - const alias = getSettingValueFromTree({ tree, key: "alias" }); - const [queryBuilderAlias, setQueryBuilderAlias] = useState(() => - getSettingValueFromTree({ tree, key: "query-builder-alias" }), + const alias = + getDiscourseNodeSetting(nodeType, ["canvasSettings", "alias"]) ?? + ""; + const [queryBuilderAlias, setQueryBuilderAlias] = useState( + () => + getDiscourseNodeSetting(nodeType, [ + "canvasSettings", + "query-builder-alias", + ]) ?? "", ); const [isKeyImage, setIsKeyImage] = useState( - () => getSettingValueFromTree({ tree, key: "key-image" }) === "true", + () => + getDiscourseNodeSetting(nodeType, [ + "canvasSettings", + "key-image", + ]) ?? false, ); - const [keyImageOption, setKeyImageOption] = useState(() => - getSettingValueFromTree({ tree, key: "key-image-option" }), + const [keyImageOption, setKeyImageOption] = useState( + () => + getDiscourseNodeSetting(nodeType, [ + "canvasSettings", + "key-image-option", + ]) ?? "", ); return ( diff --git a/apps/roam/src/components/settings/DiscourseNodeSpecification.tsx b/apps/roam/src/components/settings/DiscourseNodeSpecification.tsx index b23404556..110b39c6c 100644 --- a/apps/roam/src/components/settings/DiscourseNodeSpecification.tsx +++ b/apps/roam/src/components/settings/DiscourseNodeSpecification.tsx @@ -8,7 +8,10 @@ import getDiscourseNodes from "~/utils/getDiscourseNodes"; import getDiscourseNodeFormatExpression from "~/utils/getDiscourseNodeFormatExpression"; import QueryEditor from "~/components/QueryEditor"; import internalError from "~/utils/internalError"; -import { setDiscourseNodeSetting } from "~/components/settings/utils/accessors"; +import { + getDiscourseNodeSetting, + setDiscourseNodeSetting, +} from "~/components/settings/utils/accessors"; import { DiscourseNodeFlagPanel } from "~/components/settings/components/BlockPropSettingPanels"; const NodeSpecification = ({ @@ -27,7 +30,13 @@ const NodeSpecification = ({ ?.uid, [parentUid], ); - const [enabled, setEnabled] = React.useState(!!enabledBlockUid); + const [enabled, setEnabled] = React.useState( + () => + getDiscourseNodeSetting(node.type, [ + "specification", + "enabled", + ]) ?? false, + ); React.useEffect(() => { if (enabled) { diff --git a/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx b/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx index ce5638308..b0eb95429 100644 --- a/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx +++ b/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx @@ -32,7 +32,6 @@ import type { RoamBasicNode, TreeNode, } from "roamjs-components/types"; -import getSettingValueFromTree from "roamjs-components/util/getSettingValueFromTree"; import MenuItemSelect from "roamjs-components/components/MenuItemSelect"; import setInputSetting from "roamjs-components/util/setInputSetting"; import toFlexRegex from "roamjs-components/util/toFlexRegex"; @@ -52,6 +51,7 @@ import posthog from "posthog-js"; import { getSetting, setSetting } from "~/utils/extensionSettings"; import { USE_REIFIED_RELATIONS } from "~/data/userSettings"; import { + getGlobalSetting, setGlobalSetting, getGlobalSettings, } from "~/components/settings/utils/accessors"; @@ -139,10 +139,11 @@ export const RelationEditPanel = ({ const [tab, setTab] = useState(0); const initialSourceUid = useMemo( () => - getSettingValueFromTree({ - tree: editingRelationInfo.children, - key: "source", - }), + getGlobalSetting([ + "Relations", + editingRelationInfo.uid, + "source", + ]) ?? "", [], ); const initialSource = useMemo( @@ -152,10 +153,11 @@ export const RelationEditPanel = ({ const [source, setSource] = useState(initialSourceUid); const initialDestinationUid = useMemo( () => - getSettingValueFromTree({ - tree: editingRelationInfo.children, - key: "destination", - }), + getGlobalSetting([ + "Relations", + editingRelationInfo.uid, + "destination", + ]) ?? "", [], ); const initialDestination = useMemo( @@ -165,10 +167,12 @@ export const RelationEditPanel = ({ const [destination, setDestination] = useState(initialDestinationUid); const [label, setLabel] = useState(editingRelationInfo.text); const [complement, setComplement] = useState( - getSettingValueFromTree({ - tree: editingRelationInfo.children, - key: "complement", - }), + () => + getGlobalSetting([ + "Relations", + editingRelationInfo.uid, + "complement", + ]) ?? "", ); const edgeCallback = useCallback( diff --git a/apps/roam/src/components/settings/NodeConfig.tsx b/apps/roam/src/components/settings/NodeConfig.tsx index 20447a426..98c6a181a 100644 --- a/apps/roam/src/components/settings/NodeConfig.tsx +++ b/apps/roam/src/components/settings/NodeConfig.tsx @@ -9,7 +9,7 @@ import DiscourseNodeAttributes from "./DiscourseNodeAttributes"; import DiscourseNodeCanvasSettings from "./DiscourseNodeCanvasSettings"; import DiscourseNodeIndex from "./DiscourseNodeIndex"; import { OnloadArgs } from "roamjs-components/types"; -import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid"; +import { getDiscourseNodeSetting } from "~/components/settings/utils/accessors"; import DiscourseNodeSuggestiveRules from "./DiscourseNodeSuggestiveRules"; import { getFormattedConfigTree } from "~/utils/discourseConfigRef"; import refreshConfigTree from "~/utils/refreshConfigTree"; @@ -87,10 +87,11 @@ const NodeConfig = ({ isSpecificationEnabled?: boolean; }) => { if (isSpecificationEnabled === undefined) - isSpecificationEnabled = !!getSubTree({ - tree: getBasicTreeByParentUid(specificationUid), - key: "enabled", - })?.uid?.length; + isSpecificationEnabled = + getDiscourseNodeSetting(node.type, [ + "specification", + "enabled", + ]) ?? false; if (format.trim().length === 0 && !isSpecificationEnabled) { setTagError(""); setFormatError("Error: you must set either a format or specification"); @@ -128,7 +129,7 @@ const NodeConfig = ({ setFormatError(""); } }, - [specificationUid], + [node.type], ); useEffect(() => { @@ -266,7 +267,9 @@ const NodeConfig = ({ description="Select which attribute is used for the discourse overlay" settingKeys={["overlay"]} options={attributeNode.children.map((c) => c.text)} - initialValue={getBasicTreeByParentUid(overlayUid)[0]?.text} + initialValue={ + getDiscourseNodeSetting(node.type, ["overlay"]) ?? "" + } order={0} parentUid={node.type} uid={overlayUid} diff --git a/apps/roam/src/index.ts b/apps/roam/src/index.ts index 9eb8095aa..542cf481a 100644 --- a/apps/roam/src/index.ts +++ b/apps/roam/src/index.ts @@ -31,11 +31,8 @@ import { setSyncActivity, } from "./utils/syncDgNodesToSupabase"; import { initPluginTimer } from "./utils/pluginTimer"; -import { getUidAndBooleanSetting } from "./utils/getExportSettings"; -import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid"; -import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; -import { DISCOURSE_CONFIG_PAGE_TITLE } from "./utils/renderNodeConfigPage"; import { getSetting } from "./utils/extensionSettings"; +import { getFeatureFlag } from "./components/settings/utils/accessors"; import { initPostHog } from "./utils/posthog"; import { STREAMLINE_STYLING_KEY, @@ -112,12 +109,7 @@ export default runExtension(async (onloadArgs) => { document.addEventListener("input", discourseNodeSearchTriggerListener); document.addEventListener("selectionchange", nodeCreationPopoverListener); - const isSuggestiveModeEnabled = getUidAndBooleanSetting({ - tree: getBasicTreeByParentUid( - getPageUidByPageTitle(DISCOURSE_CONFIG_PAGE_TITLE), - ), - text: "(BETA) Suggestive Mode Enabled", - }).value; + const isSuggestiveModeEnabled = getFeatureFlag("Suggestive mode enabled"); if (isSuggestiveModeEnabled) { initializeSupabaseSync(); diff --git a/apps/roam/src/utils/deriveDiscourseNodeAttribute.ts b/apps/roam/src/utils/deriveDiscourseNodeAttribute.ts index 84cf8985b..21dc21a77 100644 --- a/apps/roam/src/utils/deriveDiscourseNodeAttribute.ts +++ b/apps/roam/src/utils/deriveDiscourseNodeAttribute.ts @@ -1,7 +1,5 @@ -import getSubTree from "roamjs-components/util/getSubTree"; -import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid"; -import getSettingValueFromTree from "roamjs-components/util/getSettingValueFromTree"; import getAttributeValueByBlockAndName from "roamjs-components/queries/getAttributeValueByBlockAndName"; +import { getDiscourseNodeSetting } from "~/components/settings/utils/accessors"; import getDiscourseContextResults from "./getDiscourseContextResults"; import findDiscourseNode from "./findDiscourseNode"; import getDiscourseNodes from "./getDiscourseNodes"; @@ -52,15 +50,12 @@ const deriveNodeAttribute = async ({ const discourseNode = findDiscourseNode({ uid, nodes }); if (!discourseNode) return 0; const nodeType = discourseNode.type; - const attributeNode = getSubTree({ - tree: getBasicTreeByParentUid(nodeType || ""), - key: "Attributes", - }); - const scoreFormula = getSettingValueFromTree({ - tree: attributeNode.children, - key: attribute, - defaultValue: "{count:Has Any Relation To:any}", - }); + const attributes = + getDiscourseNodeSetting>(nodeType || "", [ + "attributes", + ]) ?? {}; + const scoreFormula = + attributes[attribute] ?? "{count:Has Any Relation To:any}"; let postProcess = scoreFormula; let totalOffset = 0; const matches = scoreFormula.matchAll(/{([^}]+)}/g); From 51c07b5fb14d8a4502507b5fa06a05c0faa42d8a Mon Sep 17 00:00:00 2001 From: sid597 Date: Fri, 27 Feb 2026 15:44:37 +0530 Subject: [PATCH 2/4] Remove unnecessary lazy initializer from complement useState --- .../settings/DiscourseRelationConfigPanel.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx b/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx index b0eb95429..8f0788b66 100644 --- a/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx +++ b/apps/roam/src/components/settings/DiscourseRelationConfigPanel.tsx @@ -167,12 +167,11 @@ export const RelationEditPanel = ({ const [destination, setDestination] = useState(initialDestinationUid); const [label, setLabel] = useState(editingRelationInfo.text); const [complement, setComplement] = useState( - () => - getGlobalSetting([ - "Relations", - editingRelationInfo.uid, - "complement", - ]) ?? "", + getGlobalSetting([ + "Relations", + editingRelationInfo.uid, + "complement", + ]) ?? "", ); const edgeCallback = useCallback( From baa1b609232d1b19fbd0c5161847ba9e6d1cd5f4 Mon Sep 17 00:00:00 2001 From: sid597 Date: Fri, 27 Feb 2026 16:23:23 +0530 Subject: [PATCH 3/4] =?UTF-8?q?Revert=20index.ts=20suggestive=20mode=20cha?= =?UTF-8?q?nge=20=E2=80=94=20getFeatureFlag=20has=20no=20legacy=20fallback?= =?UTF-8?q?,=20deferred=20to=20ENG-1479?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/roam/src/index.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/roam/src/index.ts b/apps/roam/src/index.ts index 542cf481a..9eb8095aa 100644 --- a/apps/roam/src/index.ts +++ b/apps/roam/src/index.ts @@ -31,8 +31,11 @@ import { setSyncActivity, } from "./utils/syncDgNodesToSupabase"; import { initPluginTimer } from "./utils/pluginTimer"; +import { getUidAndBooleanSetting } from "./utils/getExportSettings"; +import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid"; +import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; +import { DISCOURSE_CONFIG_PAGE_TITLE } from "./utils/renderNodeConfigPage"; import { getSetting } from "./utils/extensionSettings"; -import { getFeatureFlag } from "./components/settings/utils/accessors"; import { initPostHog } from "./utils/posthog"; import { STREAMLINE_STYLING_KEY, @@ -109,7 +112,12 @@ export default runExtension(async (onloadArgs) => { document.addEventListener("input", discourseNodeSearchTriggerListener); document.addEventListener("selectionchange", nodeCreationPopoverListener); - const isSuggestiveModeEnabled = getFeatureFlag("Suggestive mode enabled"); + const isSuggestiveModeEnabled = getUidAndBooleanSetting({ + tree: getBasicTreeByParentUid( + getPageUidByPageTitle(DISCOURSE_CONFIG_PAGE_TITLE), + ), + text: "(BETA) Suggestive Mode Enabled", + }).value; if (isSuggestiveModeEnabled) { initializeSupabaseSync(); From f43913b2bae3722cf4e03f3fe05ba03638ddf660 Mon Sep 17 00:00:00 2001 From: sid597 Date: Fri, 27 Feb 2026 22:02:58 +0530 Subject: [PATCH 4/4] Break circular dep: inline DISCOURSE_CONFIG_PAGE_TITLE --- apps/roam/src/utils/discourseConfigRef.ts | 3 ++- apps/roam/src/utils/getExportSettings.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/roam/src/utils/discourseConfigRef.ts b/apps/roam/src/utils/discourseConfigRef.ts index 24f758269..47f40f588 100644 --- a/apps/roam/src/utils/discourseConfigRef.ts +++ b/apps/roam/src/utils/discourseConfigRef.ts @@ -7,7 +7,8 @@ import { getUidAndBooleanSetting, BooleanSetting, } from "./getExportSettings"; -import { DISCOURSE_CONFIG_PAGE_TITLE } from "~/utils/renderNodeConfigPage"; +// Inlined to break circular dep: accessors → discourseConfigRef → renderNodeConfigPage → ~/components barrel → accessors +const DISCOURSE_CONFIG_PAGE_TITLE = "roam/js/discourse-graph"; import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; import { getSuggestiveModeConfigAndUids, diff --git a/apps/roam/src/utils/getExportSettings.ts b/apps/roam/src/utils/getExportSettings.ts index 21cadbc5c..7ec21974c 100644 --- a/apps/roam/src/utils/getExportSettings.ts +++ b/apps/roam/src/utils/getExportSettings.ts @@ -2,7 +2,8 @@ import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByPar import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; import { RoamBasicNode } from "roamjs-components/types"; import { getSubTree } from "roamjs-components/util"; -import { DISCOURSE_CONFIG_PAGE_TITLE } from "~/utils/renderNodeConfigPage"; +// Inlined to avoid circular dep: accessors → discourseConfigRef → getExportSettings → renderNodeConfigPage → ~/components barrel → accessors +const DISCOURSE_CONFIG_PAGE_TITLE = "roam/js/discourse-graph"; type UidPair = { uid?: string;