Skip to content

Conversation

@mdroidian
Copy link
Contributor

@mdroidian mdroidian commented Sep 29, 2025

Summary by CodeRabbit

  • New Features

    • None
  • Bug Fixes

    • Improved tag matching to ignore leading “#”, extra spaces, and case differences, ensuring tags are recognized consistently.
    • Ensures tag pop-up buttons render reliably across nodes regardless of formatting variations.
    • Corrects tag color application so styles are applied even when users enter tags with different casing or formatting.
  • Performance

    • Minor efficiency improvement by reusing a preprocessed tag during comparisons.

@linear
Copy link

linear bot commented Sep 29, 2025

@cursor

This comment was marked as resolved.

@supabase
Copy link

supabase bot commented Sep 29, 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
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 29, 2025

✅ Actions performed

Full review triggered.

@mdroidian mdroidian requested a review from sid597 September 29, 2025 19:25
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 29, 2025

📝 Walkthrough

Walkthrough

Adds a tag normalization helper and updates tag-matching logic in apps/roam/src/utils/initializeObserversAndListeners.ts to compare normalized tags (stripping leading hashes, trimming, and lowercasing) before rendering tag popup buttons and applying colors.

Changes

Cohort / File(s) Summary
Tag normalization in observer/listener utility
apps/roam/src/utils/initializeObserversAndListeners.ts
Introduced normalizeTag helper to trim, remove leading #, and lowercase; replaced direct toLowerCase comparisons with normalizedTag vs normalizedNodeTag; computes normalizedTag once per incoming tag; preserves existing rendering and color application upon match.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User/Observer
  participant M as initializeObserversAndListeners
  participant N as Discourse Nodes
  participant R as Render/Color

  U->>M: Tag input/event
  Note right of M: normalizeTag(tag)<br/>- trim<br/>- strip leading #
  M->>M: normalizedTag = toLowerCase(...)
  loop For each node
    M->>N: Access node.tag
    M->>M: normalizedNodeTag = normalizeTag(node.tag)
    alt normalizedTag == normalizedNodeTag
      M->>R: renderNodeTagPopupButton(node)
      M->>R: apply tag color
    else
      Note over M,N: No action
    end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

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 pull request title "ENG-921 - normalize tag comparison in observer" directly and accurately describes the main change in the changeset. The code introduces a normalization helper function that standardizes tag comparison by stripping leading hashes, trimming whitespace, and converting to lowercase, which is precisely what the title indicates. The title is concise, clear, and provides enough context for a teammate to understand the primary change without being overly verbose or including unnecessary details.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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
🧪 Early access (Sonnet 4.5): enabled

We are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience.

Note:

  • Public repositories are always opted into early access features.
  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/roam/src/utils/initializeObserversAndListeners.ts (1)

116-127: Guard against false positive matches when tags normalize to empty strings.

If the incoming tag is something like "#" or "##" (only hashes), it normalizes to an empty string. Similarly, if node.tag is undefined or empty, normalizedNodeTag becomes an empty string. This would result in a match between an invalid tag and a node without a tag.

Consider adding a guard to skip empty normalized tags:

         const normalizedTag = normalizeTag(tag);
+        if (!normalizedTag) return;
 
         for (const node of getDiscourseNodes()) {
           const normalizedNodeTag = node.tag ? normalizeTag(node.tag) : "";
-          if (normalizedTag === normalizedNodeTag) {
+          if (normalizedNodeTag && normalizedTag === normalizedNodeTag) {
             renderNodeTagPopupButton(s, node, onloadArgs.extensionAPI);
🧹 Nitpick comments (1)
apps/roam/src/utils/initializeObserversAndListeners.ts (1)

112-114: Consider moving the helper function outside the callback for performance.

The normalizeTag helper is redefined on every observer callback invocation. While this doesn't affect correctness, moving it to module scope or outside the callback would be more efficient and allow potential reuse.

Apply this diff to move the helper outside the callback:

+  const normalizeTag = (tag: string): string => {
+    return tag.replace(/^#+/, "").trim().toLowerCase();
+  };
+
   const nodeTagPopupButtonObserver = createHTMLObserver({
     className: "rm-page-ref--tag",
     tag: "SPAN",
     callback: (s: HTMLSpanElement) => {
       const tag = s.getAttribute("data-tag");
       if (tag) {
-        const normalizeTag = (tag: string): string => {
-          return tag.replace(/^#+/, "").trim().toLowerCase();
-        };
-
         const normalizedTag = normalizeTag(tag);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71c03e7 and 7e95cf0.

📒 Files selected for processing (1)
  • apps/roam/src/utils/initializeObserversAndListeners.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
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.
📚 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/utils/initializeObserversAndListeners.ts
🔇 Additional comments (1)
apps/roam/src/utils/initializeObserversAndListeners.ts (1)

112-127: The normalization approach correctly addresses the PR objective.

The implementation successfully normalizes tag comparison by stripping leading hashes, trimming whitespace, and converting to lowercase. This ensures tags like "#foo", "##foo", and "foo" are treated as equivalent during matching, which aligns with the PR's goal.

Note: The retrieved learning about preserving multiple hashtags in DiscourseNodeMenu.tsx relates to tag insertion/creation context, not tag comparison. In this observer context, normalizing by removing all leading hashes is the appropriate behavior for matching purposes.

Copy link
Collaborator

@sid597 sid597 left a comment

Choose a reason for hiding this comment

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

Noice

@sid597 sid597 merged commit 96e18b0 into main Oct 1, 2025
5 checks passed
@github-project-automation github-project-automation bot moved this to Done in General Oct 1, 2025
trangdoan982 pushed a commit that referenced this pull request Oct 3, 2025
* normalize tag comparison in observer

* use existing getCleanTag
@mdroidian mdroidian deleted the eng-921-when-a-nodetag-is-defined-with-a-it-isnt-recognized-by-the branch November 25, 2025 00:52
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