Skip to content

Conversation

@trangdoan982
Copy link
Collaborator

@trangdoan982 trangdoan982 commented Nov 28, 2025

https://www.loom.com/share/28cc2d9a82aa4cc495504f780066479a

Summary by CodeRabbit

  • New Features

    • Added keyboard shortcut (Meta+Alt+Enter) to open linked files in a new leaf.
  • Bug Fixes

    • Enhanced error handling with improved messaging when opening linked files.
    • Streamlined file resolution logic for more reliable file opening behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@linear
Copy link

linear bot commented Nov 28, 2025

@supabase
Copy link

supabase bot commented Nov 28, 2025

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@trangdoan982
Copy link
Collaborator Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

📝 Walkthrough

Walkthrough

Refactors the TldrawViewComponent file opening logic to use resolveDiscourseNodeFile for linked file resolution, replacing block-ref based paths. Adds a Meta+Alt+Enter keyboard shortcut to open linked files in a new leaf. Introduces utility functions resolveDiscourseNodeFile and openFileInNewLeaf in openFileUtils.

Changes

Cohort / File(s) Change Summary
Tldraw Canvas Component
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx
Added isEditorMounted state to gate keyboard handlers after editor mount. Introduced Meta+Alt+Enter keyboard shortcut for opening hovered discourse-node linked files in new leaf. Replaced block-ref based link resolution with resolveDiscourseNodeFile flow. Simplified pointer event handling and centralized LinkedFile opening logic, removing error-toast branches tied to block references and canvas file cache.
Canvas File Utilities
apps/obsidian/src/components/canvas/utils/openFileUtils.ts
Added resolveDiscourseNodeFile() utility to extract block references, validate cache, resolve linked TFiles, and return results with toast error handling. Added openFileInNewLeaf() helper to open files in new split leaf. Expanded imports for DiscourseNodeShape, block-ref resolution, and toast utilities.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review the new isEditorMounted state logic and keyboard handler lifecycle in TldrawViewComponent to ensure proper timing and no memory leaks
  • Verify error handling and toast notifications in resolveDiscourseNodeFile() cover all failure paths (missing block refs, cache unavailability, resolution failures)
  • Confirm the Meta+Alt+Enter keyboard shortcut doesn't conflict with existing Obsidian or plugin keybindings
  • Validate async/await handling in the file opening flow and ensure proper guards prevent race conditions

Possibly related PRs

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: implementing a keyboard shortcut (Cmd + Alt + Enter) to open files in a new leaf, which aligns with the core functionality added across both modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx (2)

16-16: Unused import: TLKeyboardEventInfo

This type is imported but never used. The keyboard handling at lines 116-146 uses the native DOM KeyboardEvent type, not tldraw's TLKeyboardEventInfo.

-  TLKeyboardEventInfo,

148-148: Consider adding the listener to the container instead of window.

Attaching to window with capture phase could intercept this shortcut globally, even when focus is elsewhere. Binding to container (line 114) would scope the shortcut to the tldraw editor only.

-    window.addEventListener("keydown", handleKeyDown, true);
+    container.addEventListener("keydown", handleKeyDown, true);

     return () => {
-      window.removeEventListener("keydown", handleKeyDown, true);
+      container.removeEventListener("keydown", handleKeyDown, true);
     };
apps/obsidian/src/components/canvas/utils/openFileUtils.ts (1)

15-20: Unused parameter: plugin

The plugin parameter is declared but never used in the function body. Consider removing it to simplify the API.

 export const resolveDiscourseNodeFile = async (
   shape: DiscourseNodeShape,
   canvasFile: TFile,
   app: App,
-  plugin: DiscourseGraphPlugin,
 ): Promise<TFile | null> => {

Note: This would require updating the call sites in TldrawViewComponent.tsx (lines 133-138 and 318-323).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20199dc and 1d271e6.

📒 Files selected for processing (2)
  • apps/obsidian/src/components/canvas/TldrawViewComponent.tsx (7 hunks)
  • apps/obsidian/src/components/canvas/utils/openFileUtils.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/main.mdc)

**/*.{ts,tsx}: Use Tailwind CSS for styling where possible
When refactoring inline styles, use tailwind classes
Prefer type over interface in TypeScript
Use explicit return types for functions
Avoid any types when possible
Prefer arrow functions over regular function declarations
Use named parameters (object destructuring) when a function has more than 2 parameters
Use PascalCase for components and types
Use camelCase for variables and functions
Use UPPERCASE for constants
Function names should describe their purpose clearly
Prefer early returns over nested conditionals for better readability

Files:

  • apps/obsidian/src/components/canvas/TldrawViewComponent.tsx
  • apps/obsidian/src/components/canvas/utils/openFileUtils.ts
apps/obsidian/**

📄 CodeRabbit inference engine (.cursor/rules/obsidian.mdc)

apps/obsidian/**: Prefer existing dependencies from apps/obsidian/package.json when adding dependencies to the Obsidian plugin
Follow the Obsidian style guide from help.obsidian.md/style-guide and docs.obsidian.md/Developer+policies for UI and code styling
Use Lucide and custom Obsidian icons alongside detailed elements to provide visual representation of features in platform-native UI

Files:

  • apps/obsidian/src/components/canvas/TldrawViewComponent.tsx
  • apps/obsidian/src/components/canvas/utils/openFileUtils.ts
🧬 Code graph analysis (2)
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx (2)
apps/obsidian/src/components/canvas/shapes/DiscourseNodeShape.tsx (1)
  • DiscourseNodeShape (25-37)
apps/obsidian/src/components/canvas/utils/openFileUtils.ts (4)
  • resolveDiscourseNodeFile (15-68)
  • openFileInNewLeaf (99-106)
  • openFileInNewTab (90-97)
  • openFileInSidebar (70-88)
apps/obsidian/src/components/canvas/utils/openFileUtils.ts (3)
apps/obsidian/src/components/canvas/shapes/DiscourseNodeShape.tsx (1)
  • DiscourseNodeShape (25-37)
apps/obsidian/src/components/canvas/stores/assetStore.ts (2)
  • extractBlockRefId (58-71)
  • resolveLinkedTFileByBlockRef (77-112)
apps/obsidian/src/components/canvas/utils/toastUtils.ts (1)
  • showToast (4-23)
🔇 Additional comments (5)
apps/obsidian/src/components/canvas/TldrawViewComponent.tsx (3)

109-153: Cross-platform keyboard shortcut consideration.

The shortcut uses e.metaKey which maps to the Command key on macOS but the Windows key on Windows/Linux. Users on non-Mac platforms typically expect Ctrl+Alt+Enter rather than Win+Alt+Enter.

Consider adding ctrlKey support for Windows/Linux users:

       if (
         e.key === "Enter" &&
-        e.metaKey &&
+        (e.metaKey || e.ctrlKey) &&
         e.altKey &&
-        !e.shiftKey &&
-        !e.ctrlKey
+        !e.shiftKey
       ) {

Alternatively, if Mac-only behavior is intentional, please verify this aligns with the product requirements and document it accordingly.


273-274: Good simplification of the event handler guard.

The early return for non-pointer events cleans up the control flow.


317-334: Clean refactoring to use centralized utility functions.

The async file resolution and opening logic is now properly delegated to the shared utilities, improving consistency and reducing duplication.

apps/obsidian/src/components/canvas/utils/openFileUtils.ts (2)

10-68: Well-structured utility with comprehensive error handling.

The function properly encapsulates block reference resolution with clear toast messages for each failure mode. The JSDoc comment accurately describes the behavior.


99-106: LGTM!

Clean implementation following the same pattern as openFileInNewTab. Using "split" for a new leaf is the correct Obsidian workspace API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants