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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ dist
out
.env
extension.js
extension.css
extension.js.LICENSE.txt
31 changes: 29 additions & 2 deletions scripts/dev.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import esbuild from "esbuild";
import dotenv from "dotenv";
import fs from "fs";
import path from "path";
import { compile, args } from "./compile";

dotenv.config();
Expand All @@ -9,8 +11,33 @@ const dev = () => {
return new Promise<number>((resolve) => {
compile({
opts: args,
builder: (opts: esbuild.BuildOptions) =>
esbuild.context(opts).then((esb) => esb.watch()),
builder: (opts: esbuild.BuildOptions) => {
const outFile = path.join(process.cwd(), "dist", "extension.js");
const rootFile = path.join(process.cwd(), "extension.js");
const outCssFile = path.join(process.cwd(), "dist", "extension.css");
const rootCssFile = path.join(process.cwd(), "extension.css");
// Keep a root extension.js so Roam dev loading can target tldraw/ instead of tldraw/dist/.
const copyOutputPlugin: esbuild.Plugin = {
name: "copy-output-to-root",
setup(build) {
build.onEnd((result) => {
if (result.errors.length) return;
if (fs.existsSync(outFile)) {
fs.cpSync(outFile, rootFile);
}
if (fs.existsSync(outCssFile)) {
fs.cpSync(outCssFile, rootCssFile);
}
});
},
};
return esbuild
.context({
...opts,
plugins: [...(opts.plugins || []), copyOutputPlugin],
})
.then((esb) => esb.watch());
},
});
process.on("exit", resolve);
});
Expand Down
29 changes: 27 additions & 2 deletions src/components/canvas/Tldraw.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useMemo, useState, useRef } from "react";
import { OnloadArgs } from "roamjs-components/types";
import renderWithUnmount from "roamjs-components/util/renderWithUnmount";
import renderToast from "roamjs-components/components/Toast";
import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle";
import getUids from "roamjs-components/dom/getUids";
import {
Expand Down Expand Up @@ -662,8 +663,32 @@ const renderTldrawCanvasHelper = ({
if (!childFromRoot?.parentElement) return () => {};

const parentEl = childFromRoot.parentElement;
if (parentEl.querySelector(".roamjs-tldraw-canvas-container"))
return () => {};
const hasExistingCanvasByClass = !!parentEl.querySelector(
".roamjs-tldraw-canvas-container",
);
// Query Builder uses this id for the canvas mount.
const hasExistingCanvasById = !!parentEl.querySelector(
"#roamjs-tldraw-canvas-container",
);
const hasExistingCanvas = hasExistingCanvasByClass || hasExistingCanvasById;
// Query Builder tags rm-block-children with this attribute when it owns the canvas mount.
const hasQueryBuilderCanvasOwner = childFromRoot.hasAttribute(
"data-roamjs-discourse-playground",
);
if (
hasQueryBuilderCanvasOwner &&
!parentEl.hasAttribute("data-roamjs-tldraw-qb-warning-shown")
) {
parentEl.setAttribute("data-roamjs-tldraw-qb-warning-shown", "true");
renderToast({
id: "tldraw-query-builder-canvas-conflict",
intent: "warning",
content: `Multiple canvases have been detected on this page. This may cause unexpected behavior.

Either disable the tldraw extension or disable the Query Builder Discourse Graph flag.`,
});
}
if (hasExistingCanvas || hasQueryBuilderCanvasOwner) return () => {};

const canvasWrapperEl = document.createElement("div");
parentEl.appendChild(canvasWrapperEl);
Expand Down
Loading