Skip to content

Conversation

@mdroidian
Copy link
Contributor

@mdroidian mdroidian commented Oct 3, 2025

https://www.loom.com/share/4e4518added040f4a6dc232d1a3cb996

  • fix new bug: cannot add node tag
  • fix old bug: creating node doesn't open in sidebar
  • rm body.click on escape so user can keep editing block
  • and small refactor

Summary by CodeRabbit

  • Bug Fixes

    • Resolved timing issues that occasionally caused node creation or tag insertion to fail or appear delayed.
    • Eliminated focus-related glitches when creating nodes from the menu.
    • Improved consistency of Arrow Up/Down, Enter, and Escape behavior in keyboard navigation.
    • Shortcut changes now apply immediately without requiring a reload.
  • Refactor

    • Streamlined internal timing and event handling to make actions more reliable and responsive, reducing intermittent UI hiccups during node creation and tag insertion.

…ing. Introduce early returns and arrow functions for better readability. Implement timeouts for block updates and streamline tag addition logic.
@linear
Copy link

linear bot commented Oct 3, 2025

@supabase
Copy link

supabase bot commented Oct 3, 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 ↗︎.

mdroidian

This comment was marked as resolved.

@mdroidian mdroidian requested review from sid597 and trangdoan982 and removed request for sid597 October 3, 2025 05:46
});

createDiscourseNode({
await createDiscourseNode({
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Having createDiscourseNode before update fixes the sidebar open issue. updateBlock was actually creating a page too fast, so we were getting an error saying "this page was already created", thus not able to set the pageuid for openinsidebar


// Remove focus from the block to ensure updateBlock works properly
// https://github.com/RoamJS/query-builder/issues/286
document.body.click();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved this to inside the onSelect because

  • it can be in a single place
  • let's node tags be added without removing focus from the block
  • allows us to getFocusedBlock in the future so that we can set the cursor after editing the block

@mdroidian
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

📝 Walkthrough

Walkthrough

Refactors DiscourseNodeMenu to introduce asynchronous node creation and delayed block updates via setTimeout, adds helper functions for node creation and tag insertion, consolidates keyboard navigation using getActiveIndex, updates keydown listener dependencies, and adjusts event handling to run updates after focus removal.

Changes

Cohort / File(s) Summary
Async creation and UI timing
apps/roam/src/components/DiscourseNodeMenu.tsx
Introduces async createNodeAndUpdateBlock helper with early return; defers block updates via 100ms setTimeout after removing focus; uses void on async calls; adds addTagToBlock with delayed execution; consolidates keyboard navigation with getActiveIndex; refactors Enter/Escape/shortcut handling; adds shortcuts to keydown listener deps; minor conditional simplifications and comments.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant M as DiscourseNodeMenu
  participant DG as createDiscourseNode
  participant RB as Roam Block

  U->>M: Select option (Enter/Click/Shortcut)
  M->>M: Remove focus
  Note right of M: Schedule update (setTimeout 100ms)
  M->>DG: await createDiscourseNode(pageName)
  DG-->>M: Node created
  M->>M: setTimeout(..., 100ms)
  M-->>RB: Update block text
  M->>M: posthog event

  rect rgba(230,255,230,0.4)
  note over M,RB: Tag insertion path
  U->>M: Select tag
  M->>M: setTimeout addTagToBlock (100ms)
  M-->>RB: Update block with tag
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly conveys the primary scope of the changes—fixing issues in the Node Menu—without extraneous file lists or ambiguous wording, making it clear to reviewers what the PR addresses.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed Check skipped - CodeRabbit's high-level summary is enabled.

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 (2)
apps/roam/src/components/DiscourseNodeMenu.tsx (2)

85-111: Add error handling for async operations.

The async helper createNodeAndUpdateBlock lacks error handling. If getNewDiscourseNodeText or createDiscourseNode fails, the user won't see any feedback, and the block won't be updated.

Consider wrapping the async operations in a try-catch block:

 const createNodeAndUpdateBlock = async () => {
+  try {
     const pageName = await getNewDiscourseNodeText({
       text: highlighted,
       nodeType: nodeUid,
       blockUid,
     });
     if (!pageName) return;

     const currentBlockText = getTextByBlockUid(blockUid);
     const newText = `${currentBlockText.substring(
       0,
       textarea.selectionStart,
     )}[[${pageName}]]${currentBlockText.substring(textarea.selectionEnd)}`;

     await createDiscourseNode({
       text: pageName,
       configPageUid: nodeUid,
       extensionAPI,
     });
     void updateBlock({ text: newText, uid: blockUid });
     posthog.capture("Discourse Node: Created via Node Menu", {
       nodeType: nodeUid,
       text: pageName,
     });
+  } catch (error) {
+    console.error("Failed to create discourse node:", error);
+    // Consider showing user feedback here
+  }
 };

147-149: Add null safety to getActiveIndex.

The getActiveIndex helper doesn't handle the case where menuRef.current is null, which could lead to a runtime error.

Consider adding a fallback:

 const getActiveIndex = () => {
-  return Number(menuRef.current?.getAttribute("data-active-index"));
+  return Number(menuRef.current?.getAttribute("data-active-index") ?? 0);
 };

This ensures that if menuRef.current is null, the function returns 0 instead of NaN.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ab8b30 and d37f04d.

📒 Files selected for processing (1)
  • apps/roam/src/components/DiscourseNodeMenu.tsx (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-25T15:53:21.799Z
Learnt from: sid597
PR: DiscourseGraphs/discourse-graph#372
File: apps/roam/src/components/DiscourseNodeMenu.tsx:116-116
Timestamp: 2025-08-25T15:53:21.799Z
Learning: In apps/roam/src/components/DiscourseNodeMenu.tsx, when handling tag insertion, multiple leading hashtags (like ##foo) should be preserved as they represent user intent, not normalized to a single hashtag. The current regex /^#/ is correct as it only removes one leading # before adding one back, maintaining any additional hashtags the user intended.

Applied to files:

  • apps/roam/src/components/DiscourseNodeMenu.tsx
🔇 Additional comments (2)
apps/roam/src/components/DiscourseNodeMenu.tsx (2)

81-83: Clarify focus removal behavior for tag insertion.

According to the past review comment on line 83, document.body.click() was moved inside onSelect to "let node tags be added without removing focus from the block." However, the current code removes focus for both node creation and tag insertion.

Can you clarify whether focus removal is intentional for tag insertion, or if there should be a conditional check to only remove focus for node creation?

Based on past review comments.


172-172: LGTM! Dependency array fix is correct.

Adding shortcuts to the dependency array ensures that the keydown listener updates when the available shortcuts change. This prevents stale closure issues where the handler might reference an outdated set of shortcuts.

Copy link
Collaborator

@trangdoan982 trangdoan982 left a comment

Choose a reason for hiding this comment

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

lgtm

@mdroidian mdroidian merged commit a9ff656 into main Oct 5, 2025
5 checks passed
@mdroidian mdroidian deleted the eng-931-cant-make-node-tags-with-shortcuts branch October 5, 2025 01:15
@github-project-automation github-project-automation bot moved this to Done in General Oct 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants