Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 8 additions & 85 deletions apps/roam/src/discourseGraphsMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import refreshConfigTree from "./utils/refreshConfigTree";
import getBasicTreeByParentUid from "roamjs-components/queries/getBasicTreeByParentUid";
import getSettingValueFromTree from "roamjs-components/util/getSettingValueFromTree";
import { render } from "./components/DiscourseNodeMenu";
import { render as discourseOverlayRender } from "./components/DiscourseContextOverlay";
import { render as previewRender } from "./components/LivePreview";
import { render as renderReferenceContext } from "./components/ReferenceContext";
import DiscourseContext from "./components/DiscourseContext";
import createHTMLObserver from "roamjs-components/dom/createHTMLObserver";
Expand All @@ -45,56 +43,11 @@ import { Condition, QBClause } from "./utils/types";
import styles from "./styles/discourseGraphStyles.css";
import { DISCOURSE_CONFIG_PAGE_TITLE } from "./settings/configPages";
import { formatHexColor } from "./components/settings/DiscourseNodeCanvasSettings";

export const SETTING = "discourse-graphs";

// TODO POST MIGRATE - move this logic within the toggle
const pageRefObservers = new Set<(s: HTMLSpanElement) => void>();
const pageRefObserverRef: { current?: MutationObserver } = {
current: undefined,
};
const enablePageRefObserver = () =>
(pageRefObserverRef.current = createHTMLObserver({
useBody: true,
tag: "SPAN",
className: "rm-page-ref",
callback: (s: HTMLSpanElement) => {
pageRefObservers.forEach((f) => f(s));
},
}));
const disablePageRefObserver = () => {
pageRefObserverRef.current?.disconnect();
pageRefObserverRef.current = undefined;
};
const onPageRefObserverChange =
(handler: (s: HTMLSpanElement) => void) => (b: boolean) => {
if (b) {
if (!pageRefObservers.size) enablePageRefObserver();
pageRefObservers.add(handler);
} else {
pageRefObservers.delete(handler);
if (!pageRefObservers.size) disablePageRefObserver();
}
};

const previewPageRefHandler = (s: HTMLSpanElement) => {
const tag =
s.getAttribute("data-tag") ||
s.parentElement?.getAttribute("data-link-title");
if (tag && !s.getAttribute("data-roamjs-discourse-augment-tag")) {
s.setAttribute("data-roamjs-discourse-augment-tag", "true");
const parent = document.createElement("span");
previewRender({
parent,
tag,
registerMouseEvents: ({ open, close }) => {
s.addEventListener("mouseenter", (e) => open(e.ctrlKey));
s.addEventListener("mouseleave", close);
},
});
s.appendChild(parent);
}
};
import {
onPageRefObserverChange,
overlayPageRefHandler,
previewPageRefHandler,
} from "./utils/pageRefObserverHandlers";

export const getPlainTitleFromSpecification = ({
specification,
Expand Down Expand Up @@ -136,32 +89,6 @@ const initializeDiscourseGraphsMode = async (args: OnloadArgs) => {
unloads.delete(removeStyle);
});

const overlayPageRefHandler = (s: HTMLSpanElement) => {
if (s.parentElement && !s.parentElement.closest(".rm-page-ref")) {
const tag =
s.getAttribute("data-tag") ||
s.parentElement.getAttribute("data-link-title");
if (
tag &&
!s.getAttribute("data-roamjs-discourse-overlay") &&
isDiscourseNode(getPageUidByPageTitle(tag))
) {
s.setAttribute("data-roamjs-discourse-overlay", "true");
const parent = document.createElement("span");
discourseOverlayRender({
parent,
tag: tag.replace(/\\"/g, '"'),
onloadArgs: args,
});
if (s.hasAttribute("data-tag")) {
s.appendChild(parent);
} else {
s.parentElement.appendChild(parent);
}
}
}
};

const { pageUid, observer } = await createConfigObserver({
title: DISCOURSE_CONFIG_PAGE_TITLE,
config: {
Expand Down Expand Up @@ -228,7 +155,9 @@ const initializeDiscourseGraphsMode = async (args: OnloadArgs) => {
disabled: true,
options: {
onChange: (val) => {
onPageRefObserverChange(overlayPageRefHandler)(val);
onPageRefObserverChange((s) =>
overlayPageRefHandler(s, args),
)(val);
},
},
} as Field<FlagField>,
Expand Down Expand Up @@ -474,12 +403,6 @@ const initializeDiscourseGraphsMode = async (args: OnloadArgs) => {
unloads.delete(removeObservers);
});

if (isFlagEnabled("preview")) pageRefObservers.add(previewPageRefHandler);
// if (isFlagEnabled("grammar.overlay")) {
// pageRefObservers.add(overlayPageRefHandler);
// }
if (pageRefObservers.size) enablePageRefObserver();

const queryPages = args.extensionAPI.settings.get("query-pages");
const queryPageArray = Array.isArray(queryPages)
? queryPages
Expand Down
34 changes: 18 additions & 16 deletions apps/roam/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { runExtension } from "roamjs-components/util";

import { renderTldrawCanvas } from "./components/canvas/Tldraw";
import { renderQueryPage, renderQueryBlock } from "./components/QueryBuilder";
import { QueryBuilderLoadedToast } from "./components/toastMessages";

import runQuery from "./utils/runQuery";
import isDiscourseNode from "./utils/isDiscourseNode";
Expand All @@ -25,12 +26,20 @@ import { registerCommandPaletteCommands } from "./settings/commandPalette";
import { createSettingsPanel } from "./settings/settingsPanel";

import { renderNodeConfigPage } from "./settings/configPages";
import { isCanvasPage as checkIfCanvasPage } from "./utils/isCanvasPage";
import { isCurrentPageCanvas as isCanvasPage } from "./utils/isCanvasPage";
import { isDiscourseNodeConfigPage as isNodeConfigPage } from "./utils/isDiscourseNodeConfigPage";
import { isQueryPage } from "./utils/isQueryPage";
import { listActiveQueries } from "./utils/listActiveQueries";
import { registerSmartBlock } from "./utils/registerSmartBlock";
import isFlagEnabled from "./utils/isFlagEnabled";

import { QueryBuilderLoadedToast } from "./components/toastMessages";
import {
enablePageRefObserver,
addPageRefObserver,
getPageRefObserversSize,
previewPageRefHandler,
overlayPageRefHandler,
} from "./utils/pageRefObserverHandlers";

export const DEFAULT_CANVAS_PAGE_FORMAT = "Canvas/*";

Expand Down Expand Up @@ -61,17 +70,6 @@ export default runExtension(async (onloadArgs) => {
await initializeDiscourseGraphsMode(onloadArgs);

// Observers and Listeners
const isDiscourseNodePage = (title: string) =>
title.startsWith("discourse-graph/nodes/");
const isCanvasPage = ({
title,
h1,
}: {
title: string;
h1: HTMLHeadingElement;
}) =>
checkIfCanvasPage({ title, extensionAPI }) && !!h1.closest(".roam-article");

const pageTitleObserver = createHTMLObserver({
tag: "H1",
className: "rm-title-display",
Expand All @@ -80,7 +78,7 @@ export default runExtension(async (onloadArgs) => {
const title = getPageTitleValueByHtmlElement(h1);
const props = { title, h1, onloadArgs };

if (isDiscourseNodePage(title)) renderNodeConfigPage(props);
if (isNodeConfigPage(title)) renderNodeConfigPage(props);
else if (isQueryPage(props)) renderQueryPage(props);
else if (isCanvasPage(props)) renderTldrawCanvas(props);
},
Expand Down Expand Up @@ -113,7 +111,11 @@ export default runExtension(async (onloadArgs) => {
}) as EventListener;
document.addEventListener("roamjs:query-builder:action", pageActionListener);

registerSmartBlock(extensionAPI);
if (isFlagEnabled("preview")) addPageRefObserver(previewPageRefHandler);
if (isFlagEnabled("grammar.overlay")) {
addPageRefObserver((s) => overlayPageRefHandler(s, onloadArgs));
}
if (!!getPageRefObserversSize()) enablePageRefObserver();

// Window
// @ts-ignore
Expand All @@ -130,9 +132,9 @@ export default runExtension(async (onloadArgs) => {
isDiscourseNode: isDiscourseNode,
};

// Command Palette and Roam Settings
registerCommandPaletteCommands(onloadArgs);
createSettingsPanel(onloadArgs);
registerSmartBlock(extensionAPI);

return {
elements: [style, settingsStyle],
Expand Down
13 changes: 13 additions & 0 deletions apps/roam/src/utils/isCanvasPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,16 @@ export const isCanvasPage = ({
const canvasRegex = new RegExp(`^${format}$`.replace(/\*/g, ".+"));
return canvasRegex.test(title);
};

export const isCurrentPageCanvas = ({
title,
h1,
onloadArgs,
}: {
title: string;
h1: HTMLHeadingElement;
onloadArgs: OnloadArgs;
}) => {
const { extensionAPI } = onloadArgs;
return isCanvasPage({ title, extensionAPI }) && !!h1.closest(".roam-article");
};
4 changes: 4 additions & 0 deletions apps/roam/src/utils/isDiscourseNodeConfigPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { NODE_CONFIG_PAGE_TITLE } from "~/settings/configPages";

export const isDiscourseNodeConfigPage = (title: string) =>
title.startsWith(NODE_CONFIG_PAGE_TITLE);
101 changes: 101 additions & 0 deletions apps/roam/src/utils/pageRefObserverHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { createHTMLObserver } from "roamjs-components/dom";
import { render as previewRender } from "../components/LivePreview";
import isDiscourseNode from "./isDiscourseNode";
import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle";
import { render as discourseOverlayRender } from "../components/DiscourseContextOverlay";
import { OnloadArgs } from "roamjs-components/types";

const pageRefObservers = new Set<(s: HTMLSpanElement) => void>();
const pageRefObserverRef: { current?: MutationObserver } = {
current: undefined,
};

export const overlayPageRefHandler = (s: HTMLSpanElement, args: OnloadArgs) => {
if (s.parentElement && !s.parentElement.closest(".rm-page-ref")) {
const tag =
s.getAttribute("data-tag") ||
s.parentElement.getAttribute("data-link-title");
if (
tag &&
!s.getAttribute("data-roamjs-discourse-overlay") &&
isDiscourseNode(getPageUidByPageTitle(tag))
) {
s.setAttribute("data-roamjs-discourse-overlay", "true");
const parent = document.createElement("span");
discourseOverlayRender({
parent,
tag: tag.replace(/\\"/g, '"'),
onloadArgs: args,
});
if (s.hasAttribute("data-tag")) {
s.appendChild(parent);
} else {
s.parentElement.appendChild(parent);
}
}
}
};

export const previewPageRefHandler = (s: HTMLSpanElement) => {
const tag =
s.getAttribute("data-tag") ||
s.parentElement?.getAttribute("data-link-title");
if (tag && !s.getAttribute("data-roamjs-discourse-augment-tag")) {
s.setAttribute("data-roamjs-discourse-augment-tag", "true");
const parent = document.createElement("span");
previewRender({
parent,
tag,
registerMouseEvents: ({ open, close }) => {
s.addEventListener("mouseenter", (e) => open(e.ctrlKey));
s.addEventListener("mouseleave", close);
},
});
s.appendChild(parent);
}
};

export const enablePageRefObserver = () =>
(pageRefObserverRef.current = createHTMLObserver({
useBody: true,
tag: "SPAN",
className: "rm-page-ref",
callback: (s: HTMLSpanElement) => {
pageRefObservers.forEach((f) => f(s));
},
}));

const disablePageRefObserver = () => {
pageRefObserverRef.current?.disconnect();
pageRefObserverRef.current = undefined;
};

export const onPageRefObserverChange =
(handler: (s: HTMLSpanElement) => void) => (b: boolean) => {
if (b) {
if (!pageRefObservers.size) enablePageRefObserver();
pageRefObservers.add(handler);
} else {
pageRefObservers.delete(handler);
if (!pageRefObservers.size) disablePageRefObserver();
}
};

export const addPageRefObserver = (handler: (s: HTMLSpanElement) => void) => {
pageRefObservers.add(handler);
if (pageRefObservers.size === 1) enablePageRefObserver();
};

export const removePageRefObserver = (
handler: (s: HTMLSpanElement) => void,
) => {
pageRefObservers.delete(handler);
if (pageRefObservers.size === 0) disablePageRefObserver();
};

export const clearPageRefObservers = () => {
disablePageRefObserver();
pageRefObservers.clear();
};

export const getPageRefObserversSize = () => pageRefObservers.size;
Loading