diff --git a/apps/roam/src/components/DiscourseFloatingMenu.tsx b/apps/roam/src/components/DiscourseFloatingMenu.tsx index 07f71b694..713ecc9a5 100644 --- a/apps/roam/src/components/DiscourseFloatingMenu.tsx +++ b/apps/roam/src/components/DiscourseFloatingMenu.tsx @@ -13,6 +13,7 @@ import { import { FeedbackWidget } from "./BirdEatsBugs"; import { render as renderSettings } from "~/components/settings/Settings"; import posthog from "posthog-js"; +import { getPersonalSetting } from "./settings/utils/accessors"; type DiscourseFloatingMenuProps = { // CSS placement class @@ -128,7 +129,7 @@ export const installDiscourseFloatingMenu = ( floatingMenuAnchor.id = ANCHOR_ID; document.getElementById("app")?.appendChild(floatingMenuAnchor); } - if (onLoadArgs.extensionAPI.settings.get("hide-feedback-button") as boolean) { + if (getPersonalSetting(["Hide feedback button"])) { floatingMenuAnchor.classList.add("hidden"); } ReactDOM.render( diff --git a/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx b/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx index fc2f1d742..c362e420f 100644 --- a/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx +++ b/apps/roam/src/components/canvas/DiscourseNodeUtil.tsx @@ -35,11 +35,7 @@ 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, - DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, -} from "~/data/userSettings"; -import { getSetting } from "~/utils/extensionSettings"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; import DiscourseContextOverlay from "~/components/DiscourseContextOverlay"; import { getDiscourseNodeColors } from "~/utils/getDiscourseNodeColors"; import { render as renderToast } from "roamjs-components/components/Toast"; @@ -435,7 +431,7 @@ export class BaseDiscourseNodeUtil extends BaseBoxShapeUtil } = discourseContext.nodes[shape.type] || {}; // eslint-disable-next-line react-hooks/rules-of-hooks const isOverlayEnabled = useMemo( - () => getSetting(DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, false), + () => getPersonalSetting(["Overlay in canvas"]), [], ); @@ -516,10 +512,9 @@ export class BaseDiscourseNodeUtil extends BaseBoxShapeUtil uid, }); - const autoCanvasRelations = getSetting( - AUTO_CANVAS_RELATIONS_KEY, - false, - ); + const autoCanvasRelations = getPersonalSetting([ + "Auto canvas relations", + ]); if (autoCanvasRelations) { try { const relationIds = getRelationIds(); diff --git a/apps/roam/src/components/canvas/Tldraw.tsx b/apps/roam/src/components/canvas/Tldraw.tsx index 074a438a3..24f94b8ab 100644 --- a/apps/roam/src/components/canvas/Tldraw.tsx +++ b/apps/roam/src/components/canvas/Tldraw.tsx @@ -96,8 +96,6 @@ import ToastListener, { dispatchToastEvent } from "./ToastListener"; import { CanvasDrawerPanel } from "./CanvasDrawer"; import { ClipboardPanel, ClipboardProvider } from "./Clipboard"; import internalError from "~/utils/internalError"; -import { AUTO_CANVAS_RELATIONS_KEY } from "~/data/userSettings"; -import { getSetting } from "~/utils/extensionSettings"; import { isPluginTimerReady, waitForPluginTimer } from "~/utils/pluginTimer"; import { HistoryEntry } from "@tldraw/store"; import { TLRecord } from "@tldraw/tlschema"; @@ -105,6 +103,7 @@ import { WHITE_LOGO_SVG } from "~/icons"; import { BLOCK_REF_REGEX } from "roamjs-components/dom"; import { defaultHandleExternalTextContent } from "./defaultHandleExternalTextContent"; import posthog from "posthog-js"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; declare global { // eslint-disable-next-line @typescript-eslint/consistent-type-definitions @@ -1132,10 +1131,9 @@ const InsideEditorAndUiContext = ({ editor.sideEffects.registerAfterCreateHandler("shape", (shape) => { const util = editor.getShapeUtil(shape); if (util instanceof BaseDiscourseNodeUtil) { - const autoCanvasRelations = getSetting( - AUTO_CANVAS_RELATIONS_KEY, - false, - ); + const autoCanvasRelations = getPersonalSetting([ + "Auto canvas relations", + ]); if (autoCanvasRelations) { void util.createExistingRelations({ shape: shape as DiscourseNodeShape, diff --git a/apps/roam/src/components/canvas/uiOverrides.tsx b/apps/roam/src/components/canvas/uiOverrides.tsx index c3aafa80e..3f48f1ec2 100644 --- a/apps/roam/src/components/canvas/uiOverrides.tsx +++ b/apps/roam/src/components/canvas/uiOverrides.tsx @@ -42,10 +42,9 @@ import calcCanvasNodeSizeAndImg from "~/utils/calcCanvasNodeSizeAndImg"; import { AddReferencedNodeType } from "./DiscourseRelationShape/DiscourseRelationTool"; import { getRelationColor } from "./DiscourseRelationShape/DiscourseRelationUtil"; import DiscourseGraphPanel from "./DiscourseToolPanel"; -import { DISCOURSE_TOOL_SHORTCUT_KEY } from "~/data/userSettings"; -import { getSetting } from "~/utils/extensionSettings"; import { CustomDefaultToolbar } from "./CustomDefaultToolbar"; import { renderModifyNodeDialog } from "~/components/ModifyNodeDialog"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; export const getOnSelectForShape = ({ shape, @@ -271,10 +270,12 @@ export const createUiOverrides = ({ }): TLUiOverrides => ({ tools: (editor, tools) => { // Get the custom keyboard shortcut for the discourse tool - const discourseToolCombo = getSetting(DISCOURSE_TOOL_SHORTCUT_KEY, { + const discourseToolCombo = getPersonalSetting([ + "Discourse tool shortcut", + ]) || { key: "", modifiers: 0, - }) as IKeyCombo; + }; // For discourse tool, just use the key directly since we don't allow modifiers const discourseToolShortcut = discourseToolCombo?.key?.toUpperCase() || ""; diff --git a/apps/roam/src/components/settings/HomePersonalSettings.tsx b/apps/roam/src/components/settings/HomePersonalSettings.tsx index f4d2c74a3..a21b01d82 100644 --- a/apps/roam/src/components/settings/HomePersonalSettings.tsx +++ b/apps/roam/src/components/settings/HomePersonalSettings.tsx @@ -22,7 +22,7 @@ import { STREAMLINE_STYLING_KEY, DISALLOW_DIAGNOSTICS, } from "~/data/userSettings"; -import { getSetting, setSetting } from "~/utils/extensionSettings"; +import { setSetting } from "~/utils/extensionSettings"; import { enablePostHog, disablePostHog } from "~/utils/posthog"; import KeyboardShortcutInput from "./KeyboardShortcutInput"; import streamlineStyling from "~/styles/streamlineStyling"; @@ -67,7 +67,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Overlay" description="Whether or not to overlay discourse context information over discourse node references." settingKeys={["Discourse context overlay"]} - initialValue={getSetting("discourse-context-overlay", false)} onChange={(checked) => { void setSetting("discourse-context-overlay", checked); onPageRefObserverChange(overlayHandler)(checked); @@ -81,7 +80,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Suggestive mode overlay" description="Whether or not to overlay suggestive mode button over discourse node references." settingKeys={["Suggestive mode overlay"]} - initialValue={getSetting("suggestive-mode-overlay", false)} onChange={(checked) => { void setSetting("suggestive-mode-overlay", checked); onPageRefObserverChange(getSuggestiveOverlayHandler(onloadArgs))( @@ -94,7 +92,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Text selection popup" description="Whether or not to show the discourse node menu when selecting text." settingKeys={["Text selection popup"]} - initialValue={getSetting("text-selection-popup", true)} onChange={(checked) => { void setSetting("text-selection-popup", checked); }} @@ -103,7 +100,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Disable sidebar open" description="Disable opening new nodes in the sidebar when created" settingKeys={["Disable sidebar open"]} - initialValue={getSetting("disable-sidebar-open", false)} onChange={(checked) => { void setSetting("disable-sidebar-open", checked); }} @@ -112,7 +108,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Page preview" description="Whether or not to display page previews when hovering over page refs" settingKeys={["Page preview"]} - initialValue={getSetting("page-preview", false)} onChange={(checked) => { void setSetting("page-preview", checked); onPageRefObserverChange(previewPageRefHandler)(checked); @@ -122,7 +117,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Hide feedback button" description="Hide the 'Send feedback' button at the bottom right of the screen." settingKeys={["Hide feedback button"]} - initialValue={getSetting("hide-feedback-button", false)} onChange={(checked) => { void setSetting("hide-feedback-button", checked); if (checked) { @@ -136,7 +130,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Auto canvas relations" description="Automatically add discourse relations to canvas when a node is added" settingKeys={["Auto canvas relations"]} - initialValue={getSetting(AUTO_CANVAS_RELATIONS_KEY, false)} onChange={(checked) => { void setSetting(AUTO_CANVAS_RELATIONS_KEY, checked); }} @@ -146,10 +139,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="(BETA) Overlay in canvas" description="Whether or not to overlay discourse context information over canvas nodes." settingKeys={["Overlay in canvas"]} - initialValue={getSetting( - DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, - false, - )} onChange={(checked) => { void setSetting(DISCOURSE_CONTEXT_OVERLAY_IN_CANVAS_KEY, checked); }} @@ -158,7 +147,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Streamline styling" description="Apply streamlined styling to your personal graph for a cleaner appearance." settingKeys={["Streamline styling"]} - initialValue={getSetting(STREAMLINE_STYLING_KEY, false)} onChange={(checked) => { void setSetting(STREAMLINE_STYLING_KEY, checked); const existingStyleElement = @@ -176,7 +164,6 @@ const HomePersonalSettings = ({ onloadArgs }: { onloadArgs: OnloadArgs }) => { title="Disable product diagnostics" description="Disable sending usage signals and error reports that help us improve the product." settingKeys={["Disable product diagnostics"]} - initialValue={getSetting(DISALLOW_DIAGNOSTICS, false)} onChange={(checked) => { void setSetting(DISALLOW_DIAGNOSTICS, checked); if (checked) { diff --git a/apps/roam/src/components/settings/QuerySettings.tsx b/apps/roam/src/components/settings/QuerySettings.tsx index e40613c0c..121e69c95 100644 --- a/apps/roam/src/components/settings/QuerySettings.tsx +++ b/apps/roam/src/components/settings/QuerySettings.tsx @@ -23,9 +23,6 @@ const QuerySettings = ({ title="Hide query metadata" description="Hide the Roam blocks that are used to power each query" settingKeys={["Query", "Hide query metadata"]} - initialValue={ - (extensionAPI.settings.get(HIDE_METADATA_KEY) as boolean) ?? true - } onChange={(checked) => { void extensionAPI.settings.set(HIDE_METADATA_KEY, checked); posthog.capture("Query Settings: Hide Metadata Toggled", { diff --git a/apps/roam/src/index.ts b/apps/roam/src/index.ts index 9eb8095aa..eadb9cf3a 100644 --- a/apps/roam/src/index.ts +++ b/apps/roam/src/index.ts @@ -35,20 +35,18 @@ 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 { initPostHog } from "./utils/posthog"; -import { - STREAMLINE_STYLING_KEY, - DISALLOW_DIAGNOSTICS, -} from "./data/userSettings"; import { initSchema } from "./components/settings/utils/init"; +import { getPersonalSetting } from "./components/settings/utils/accessors"; export const DEFAULT_CANVAS_PAGE_FORMAT = "Canvas/*"; export default runExtension(async (onloadArgs) => { const isEncrypted = window.roamAlphaAPI.graph.isEncrypted; const isOffline = window.roamAlphaAPI.graph.type === "offline"; - const disallowDiagnostics = getSetting(DISALLOW_DIAGNOSTICS, false); + const disallowDiagnostics = getPersonalSetting([ + "Disable product diagnostics", + ]); if (!isEncrypted && !isOffline && !disallowDiagnostics) { initPostHog(); } @@ -91,7 +89,9 @@ export default runExtension(async (onloadArgs) => { const discourseFloatingMenuStyle = addStyle(discourseFloatingMenuStyles); // Add streamline styling only if enabled - const isStreamlineStylingEnabled = getSetting(STREAMLINE_STYLING_KEY, false); + const isStreamlineStylingEnabled = getPersonalSetting([ + "Streamline styling", + ]); let streamlineStyleElement: HTMLStyleElement | null = null; if (isStreamlineStylingEnabled) { streamlineStyleElement = addStyle(streamlineStyling); diff --git a/apps/roam/src/utils/createDiscourseNode.ts b/apps/roam/src/utils/createDiscourseNode.ts index 851cba630..f4e749d2e 100644 --- a/apps/roam/src/utils/createDiscourseNode.ts +++ b/apps/roam/src/utils/createDiscourseNode.ts @@ -12,6 +12,7 @@ import { OnloadArgs, RoamBasicNode } from "roamjs-components/types"; import runQuery from "./runQuery"; import updateBlock from "roamjs-components/writes/updateBlock"; import posthog from "posthog-js"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; type Props = { text: string; @@ -32,8 +33,8 @@ const createDiscourseNode = async ({ text: text, }); const handleOpenInSidebar = (uid: string) => { - if (extensionAPI?.settings.get("disable-sidebar-open")) return; - openBlockInSidebar(uid); + if (getPersonalSetting(["Disable sidebar open"])) return; + void openBlockInSidebar(uid); setTimeout(() => { const sidebarTitle = document.querySelector( ".rm-sidebar-outline .rm-title-display", diff --git a/apps/roam/src/utils/initializeObserversAndListeners.ts b/apps/roam/src/utils/initializeObserversAndListeners.ts index 4f2a3fa68..c5f431c97 100644 --- a/apps/roam/src/utils/initializeObserversAndListeners.ts +++ b/apps/roam/src/utils/initializeObserversAndListeners.ts @@ -61,6 +61,7 @@ import { renderPossibleDuplicates } from "~/components/VectorDuplicateMatches"; import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid"; import findDiscourseNode from "./findDiscourseNode"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; const debounce = (fn: () => void, delay = 250) => { let timeout: number; @@ -191,11 +192,11 @@ export const initObservers = async ({ }>, ) => { if (!/page/i.test(e.detail.action)) return; - window.roamAlphaAPI.ui.mainWindow + void window.roamAlphaAPI.ui.mainWindow .getOpenPageOrBlockUid() .then((u) => u || window.roamAlphaAPI.util.dateToPageUid(new Date())) .then((parentUid) => { - createBlock({ + return createBlock({ parentUid, order: Number.MAX_VALUE, node: { text: `[[${e.detail.val}]]` }, @@ -203,7 +204,7 @@ export const initObservers = async ({ }); }) as EventListener; - if (onloadArgs.extensionAPI.settings.get("suggestive-mode-overlay")) { + if (getPersonalSetting(["Suggestive mode overlay"])) { addPageRefObserver(getSuggestiveOverlayHandler(onloadArgs)); } @@ -226,9 +227,9 @@ export const initObservers = async ({ }, }); - if (onloadArgs.extensionAPI.settings.get("page-preview")) + if (getPersonalSetting(["Page preview"])) addPageRefObserver(previewPageRefHandler); - if (onloadArgs.extensionAPI.settings.get("discourse-context-overlay")) { + if (getPersonalSetting(["Discourse context overlay"])) { const overlayHandler = getOverlayHandler(onloadArgs); onPageRefObserverChange(overlayHandler)(true); } @@ -383,7 +384,7 @@ export const initObservers = async ({ const nodeCreationPopoverListener = debounce(() => { const isTextSelectionPopupEnabled = - onloadArgs.extensionAPI.settings.get("text-selection-popup") !== false; + getPersonalSetting(["Text selection popup"]) !== false; if (!isTextSelectionPopupEnabled) return; diff --git a/apps/roam/src/utils/internalError.ts b/apps/roam/src/utils/internalError.ts index 6a1be6508..201909ef6 100644 --- a/apps/roam/src/utils/internalError.ts +++ b/apps/roam/src/utils/internalError.ts @@ -2,8 +2,7 @@ import posthog from "posthog-js"; import type { Properties } from "posthog-js"; import renderToast from "roamjs-components/components/Toast"; import sendErrorEmail from "~/utils/sendErrorEmail"; -import { getSetting } from "~/utils/extensionSettings"; -import { DISALLOW_DIAGNOSTICS } from "~/data/userSettings"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; const NON_WORD = /\W+/g; @@ -23,7 +22,7 @@ const internalError = ({ forceSendInDev?: boolean; }): void => { if ( - getSetting(DISALLOW_DIAGNOSTICS, false) || + getPersonalSetting(["Disable product diagnostics"]) || (process.env.NODE_ENV === "development" && forceSendInDev !== true) ) { console.error(error, context); diff --git a/apps/roam/src/utils/posthog.ts b/apps/roam/src/utils/posthog.ts index b1cc4a8dd..65aca92b9 100644 --- a/apps/roam/src/utils/posthog.ts +++ b/apps/roam/src/utils/posthog.ts @@ -2,8 +2,7 @@ import getCurrentUserUid from "roamjs-components/queries/getCurrentUserUid"; import { getVersionWithDate } from "./getVersion"; import posthog from "posthog-js"; import type { CaptureResult } from "posthog-js"; -import { getSetting } from "./extensionSettings"; -import { DISALLOW_DIAGNOSTICS } from "~/data/userSettings"; +import { getPersonalSetting } from "~/components/settings/utils/accessors"; let initialized = false; @@ -70,7 +69,7 @@ export const disablePostHog = (): void => { }; export const initPostHog = (): void => { - const disabled = getSetting(DISALLOW_DIAGNOSTICS, false); + const disabled = getPersonalSetting(["Disable product diagnostics"]); if (!disabled) { doInitPostHog(); } diff --git a/apps/roam/src/utils/registerCommandPaletteCommands.ts b/apps/roam/src/utils/registerCommandPaletteCommands.ts index e3643ca1a..fb9489265 100644 --- a/apps/roam/src/utils/registerCommandPaletteCommands.ts +++ b/apps/roam/src/utils/registerCommandPaletteCommands.ts @@ -18,6 +18,10 @@ import { } from "./pageRefObserverHandlers"; import { HIDE_METADATA_KEY } from "~/data/userSettings"; import posthog from "posthog-js"; +import { + getPersonalSetting, + setPersonalSetting, +} from "~/components/settings/utils/accessors"; export const registerCommandPaletteCommands = (onloadArgs: OnloadArgs) => { const { extensionAPI } = onloadArgs; @@ -156,12 +160,13 @@ export const registerCommandPaletteCommands = (onloadArgs: OnloadArgs) => { }; const toggleDiscourseContextOverlay = async () => { - const currentValue = - (extensionAPI.settings.get("discourse-context-overlay") as boolean) ?? - false; + const currentValue = getPersonalSetting([ + "Discourse context overlay", + ]); const newValue = !currentValue; try { await extensionAPI.settings.set("discourse-context-overlay", newValue); + setPersonalSetting(["Discourse context overlay"], newValue); } catch (error) { const e = error as Error; renderToast({ @@ -182,11 +187,14 @@ export const registerCommandPaletteCommands = (onloadArgs: OnloadArgs) => { }; const toggleQueryMetadata = async () => { - const currentValue = - (extensionAPI.settings.get(HIDE_METADATA_KEY) as boolean) ?? true; + const currentValue = getPersonalSetting([ + "Query", + "Hide query metadata", + ]); const newValue = !currentValue; try { await extensionAPI.settings.set(HIDE_METADATA_KEY, newValue); + setPersonalSetting(["Query", "Hide query metadata"], newValue); } catch (error) { const e = error as Error; renderToast({