Skip to content
Open
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
17 changes: 2 additions & 15 deletions apps/roam/src/components/Export.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import {
createNodeShapeUtils,
DiscourseNodeShape,
} from "~/components/canvas/DiscourseNodeUtil";
import { discourseContext, MAX_WIDTH } from "~/components/canvas/Tldraw";
import { MAX_WIDTH } from "~/components/canvas/Tldraw";
import internalError from "~/utils/internalError";
import { getSetting, setSetting } from "~/utils/extensionSettings";
import { isTLStoreSnapshot } from "./canvas/useRoamStore";
Expand All @@ -79,9 +79,7 @@ import {
createAllReferencedNodeUtils,
} from "./canvas/DiscourseRelationShape/DiscourseRelationUtil";
import getDiscourseNodes from "~/utils/getDiscourseNodes";
import getDiscourseRelations, {
DiscourseRelation,
} from "~/utils/getDiscourseRelations";
import getDiscourseRelations from "~/utils/getDiscourseRelations";
import { AddReferencedNodeType } from "./canvas/DiscourseRelationShape/DiscourseRelationTool";
import posthog from "posthog-js";

Expand Down Expand Up @@ -312,17 +310,6 @@ const ExportDialog: ExportDialogComponent = ({
// TODO lots of this is reused in tldraw.tsx, use a function to avoid duplication
if (!isTLStore) {
const relations = getDiscourseRelations();
discourseContext.relations = relations.reduce(
(acc, r) => {
Copy link
Copy Markdown
Collaborator Author

@sid597 sid597 Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutating this could effect the state for other open canvases??? we do set this up in tldraw.tsx line 455

This is for you Michael it seems correct to me but can give an authortative answer here

if (acc[r.label]) {
acc[r.label].push(r);
} else {
acc[r.label] = [r];
}
return acc;
},
{} as Record<string, DiscourseRelation[]>,
);
const allRelations = relations;
const allRelationIds = allRelations.map((r) => r.id);
const allNodes = getDiscourseNodes(allRelations);
Expand Down
63 changes: 53 additions & 10 deletions apps/roam/src/components/canvas/Tldraw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,38 @@ export type DiscourseContextType = {
nodes: Record<string, DiscourseNode & { index: number }>;
// { [Relation.Label] => DiscourseRelation[] }
relations: Record<string, DiscourseRelation[]>;
lastAppEvent: string;
lastActions: HistoryEntry<TLRecord>[];
};

export const discourseContext: DiscourseContextType = {
nodes: {},
relations: {},
lastAppEvent: "",
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surface 1 handled

lastActions: [],
};

let activeCanvasPageUid: string | null = null;
let activeCanvasEditor: Editor | null = null;

const setActiveCanvas = ({
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surface 3 handled, we track the active canvas and ensure only that canvas is focused, so only this canvas responds to the clipboard events

pageUid,
editor,
}: {
pageUid: string;
editor: Editor | null;
}) => {
if (activeCanvasPageUid === pageUid && activeCanvasEditor === editor) {
if (editor && !editor.getInstanceState().isFocused) editor.focus();
return;
}

if (activeCanvasEditor && activeCanvasEditor !== editor) {
activeCanvasEditor.blur();
}

activeCanvasPageUid = pageUid;
activeCanvasEditor = editor;

if (editor && !editor.getInstanceState().isFocused) {
editor.focus();
}
};

export const DEFAULT_WIDTH = 160;
Expand Down Expand Up @@ -358,9 +381,7 @@ const TldrawCanvasShared = ({
const appRef = useRef<Editor | null>(null);
const lastInsertRef = useRef<VecModel>();
const containerRef = useRef<HTMLDivElement>(null);
const lastActionsRef = useRef<HistoryEntry<TLRecord>[]>(
discourseContext.lastActions,
);
const lastActionsRef = useRef<HistoryEntry<TLRecord>[]>([]);

const [isConvertToDialogOpen, setConvertToDialogOpen] = useState(false);

Expand Down Expand Up @@ -725,6 +746,17 @@ const TldrawCanvasShared = ({
inSidebar: !!containerRef.current?.closest(".rm-sidebar-outline"),
});
}, [pageUid]);

useEffect(() => {
return () => {
const editor = appRef.current;
if (activeCanvasPageUid === pageUid && activeCanvasEditor === editor) {
activeCanvasEditor?.blur();
activeCanvasPageUid = null;
activeCanvasEditor = null;
}
};
}, [pageUid]);
const { store, needsUpgrade, performUpgrade, error, isLoading } =
useStoreAdapter(storeAdapterArgs);
const migratedCloudStoreRef = useRef<string | null>(null);
Expand Down Expand Up @@ -788,10 +820,14 @@ const TldrawCanvasShared = ({
uid?: string;
val?: string;
shapeId?: TLShapeId;
targetCanvasPageUid?: string;
onRefresh: () => void;
}>,
) => {
if (!/canvas/i.test(e.detail.action)) return;
const targetCanvasPageUid =
e.detail.targetCanvasPageUid ?? activeCanvasPageUid;
if (targetCanvasPageUid !== pageUid) return;
const app = appRef.current;
if (!app) return;
const { x, y } = app.getViewportScreenCenter();
Expand Down Expand Up @@ -829,7 +865,7 @@ const TldrawCanvasShared = ({
actionListener,
);
};
}, [appRef, allNodes]);
}, [appRef, allNodes, pageUid]);

// Catch a custom event we used patch-package to add
useEffect(() => {
Expand Down Expand Up @@ -917,6 +953,10 @@ const TldrawCanvasShared = ({
tabIndex={-1}
onDragOver={handleDragOver}
onDrop={handleDrop}
onPointerDownCapture={() => {
if (!appRef.current) return;
setActiveCanvas({ pageUid, editor: appRef.current });
}}
>
{isCloudflareSync && (
<div
Expand Down Expand Up @@ -987,6 +1027,7 @@ const TldrawCanvasShared = ({
<TldrawEditor
// baseUrl="https://samepage.network/assets/tldraw/"
// instanceId={initialState.instanceId}
autoFocus={false}
initialState="select"
shapeUtils={[...defaultShapeUtils, ...customShapeUtils]}
tools={[...defaultTools, ...defaultShapeTools, ...customTools]}
Expand All @@ -1002,6 +1043,10 @@ const TldrawCanvasShared = ({

appRef.current = app;

if (!activeCanvasPageUid || activeCanvasPageUid === pageUid) {
setActiveCanvas({ pageUid, editor: app });
}

void syncCanvasNodeTitlesOnLoad(
app,
allNodes.map((n) => n.type),
Expand All @@ -1022,8 +1067,6 @@ const TldrawCanvasShared = ({
app.on("event", (event) => {
const e = event as TLPointerEventInfo;

discourseContext.lastAppEvent = e.name;

// Handle relation creation on pointer_down
handleRelationCreation(app, e);

Expand Down
7 changes: 6 additions & 1 deletion apps/roam/src/components/results-view/ResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,11 @@ const ResultRow = ({
return (
<Button
{...buttonProps}
onClick={() => {
onClick={(event) => {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass this to the correct canvas

const targetCanvasPageUid =
event.currentTarget.closest<HTMLElement>(
".roamjs-tldraw-canvas-container[data-page-uid]",
)?.dataset.pageUid || undefined;
document.dispatchEvent(
new CustomEvent("roamjs:query-builder:action", {
detail: {
Expand All @@ -238,6 +242,7 @@ const ResultRow = ({
val: r["text"],
onRefresh,
queryUid: parentUid,
targetCanvasPageUid,
},
}),
);
Expand Down
Loading