Skip to content

Commit c649cf4

Browse files
committed
shift click to open file on the right split
1 parent b1d15d0 commit c649cf4

File tree

1 file changed

+98
-2
lines changed

1 file changed

+98
-2
lines changed

apps/obsidian/src/components/canvas/TldrawViewComponent.tsx

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,15 @@ import {
3030
WHITE_LOGO_SVG,
3131
} from "~/constants";
3232
import { TFile } from "obsidian";
33-
import { ObsidianTLAssetStore } from "~/components/canvas/stores/assetStore";
34-
import { createDiscourseNodeUtil } from "~/components/canvas/shapes/DiscourseNodeShape";
33+
import {
34+
ObsidianTLAssetStore,
35+
resolveLinkedTFileByBlockRef,
36+
extractBlockRefId,
37+
} from "~/components/canvas/stores/assetStore";
38+
import {
39+
createDiscourseNodeUtil,
40+
DiscourseNodeShape,
41+
} from "~/components/canvas/shapes/DiscourseNodeShape";
3542
import { DiscourseNodeTool } from "./DiscourseNodeTool";
3643
import { DiscourseToolPanel } from "./DiscourseToolPanel";
3744
import { usePlugin } from "~/components/PluginContext";
@@ -43,6 +50,7 @@ import {
4350
} from "~/components/canvas/shapes/DiscourseRelationBinding";
4451
import ToastListener from "./ToastListener";
4552
import { RelationsOverlay } from "./overlays/RelationOverlay";
53+
import { showToast } from "./utils/toastUtils";
4654

4755
type TldrawPreviewProps = {
4856
store: TLStore;
@@ -60,6 +68,8 @@ export const TldrawPreviewComponent = ({
6068
const [isReady, setIsReady] = useState(false);
6169
const isCreatingRelationRef = useRef(false);
6270
const saveTimeoutRef = useRef<NodeJS.Timeout>(null);
71+
const lastShiftClickRef = useRef<number>(0);
72+
const SHIFT_CLICK_DEBOUNCE_MS = 300; // Prevent double clicks within 300ms
6373
const lastSavedDataRef = useRef<string>("");
6474
const editorRef = useRef<Editor>(null);
6575
const plugin = usePlugin();
@@ -189,6 +199,92 @@ export const TldrawPreviewComponent = ({
189199
BaseRelationBindingUtil.checkAndReifyRelation(editor);
190200
isCreatingRelationRef.current = false;
191201
}
202+
203+
if (e.shiftKey) {
204+
const now = Date.now();
205+
206+
// Debounce to prevent double opening
207+
if (now - lastShiftClickRef.current < SHIFT_CLICK_DEBOUNCE_MS) {
208+
return;
209+
}
210+
lastShiftClickRef.current = now;
211+
212+
const shape = editor.getShapeAtPoint(
213+
editor.inputs.currentPagePoint,
214+
) as DiscourseNodeShape;
215+
216+
if (!shape || shape.type !== "discourse-node") return;
217+
const selectedShapes = editor.getSelectedShapes();
218+
const selectedDiscourseNodes = selectedShapes.filter(
219+
(s) => s.type === "discourse-node",
220+
);
221+
222+
if (selectedDiscourseNodes.length > 1) {
223+
return;
224+
}
225+
226+
const blockRefId = extractBlockRefId(shape.props.src ?? undefined);
227+
if (!blockRefId) {
228+
showToast({
229+
severity: "warning",
230+
title: "Cannot open node",
231+
description: "No valid block reference found",
232+
});
233+
return;
234+
}
235+
236+
const canvasFileCache = plugin.app.metadataCache.getFileCache(file);
237+
if (!canvasFileCache) {
238+
showToast({
239+
severity: "error",
240+
title: "Error",
241+
description: "Could not read canvas file",
242+
});
243+
return;
244+
}
245+
246+
void resolveLinkedTFileByBlockRef({
247+
app: plugin.app,
248+
canvasFile: file,
249+
blockRefId,
250+
canvasFileCache,
251+
})
252+
.then(async (linkedFile) => {
253+
if (!linkedFile) {
254+
showToast({
255+
severity: "warning",
256+
title: "Cannot open node",
257+
description: "Linked file not found",
258+
});
259+
return;
260+
}
261+
262+
const rightSplit = plugin.app.workspace.rightSplit;
263+
const rightLeaf = plugin.app.workspace.getRightLeaf(false);
264+
265+
if (rightLeaf) {
266+
if (rightSplit && rightSplit.collapsed) {
267+
rightSplit.expand();
268+
}
269+
await rightLeaf.openFile(linkedFile);
270+
plugin.app.workspace.setActiveLeaf(rightLeaf);
271+
} else {
272+
const leaf = plugin.app.workspace.getLeaf("split", "vertical");
273+
await leaf.openFile(linkedFile);
274+
plugin.app.workspace.setActiveLeaf(leaf);
275+
}
276+
277+
editor.selectNone();
278+
})
279+
.catch((error) => {
280+
console.error("Error opening linked file:", error);
281+
showToast({
282+
severity: "error",
283+
title: "Error",
284+
description: "Failed to open linked file",
285+
});
286+
});
287+
}
192288
}
193289
});
194290
};

0 commit comments

Comments
 (0)