Skip to content

Notes: show every thread participant on the block toolbar avatar indicator - #82357

Closed
adamsilverstein wants to merge 4 commits into
trunkfrom
fix/82273-avatar-indicator-all-threads
Closed

adamsilverstein wants to merge 4 commits into
trunkfrom
fix/82273-avatar-indicator-all-threads

Conversation

@adamsilverstein

@adamsilverstein adamsilverstein commented Sep 2, 2026 •

Copy link
Copy Markdown
Member

What?

Closes #82273

Makes the block toolbar avatar indicator represent all of the block's note threads instead of a single one, so every user with a note on the block shows up.

Why?

A block can carry several threads - a block-level note plus one or more inline notes - but the indicator was wired to a single "primary" thread picked by pickPrimaryNote(). Block-level notes sort ahead of inline ones, so an unresolved block-level note always won and the other users who left inline notes on that block never got an avatar. Two inline threads by two different users had the same problem with no block-level note involved.

Per the discussion on the issue, the button was designed to hold multiple avatars, and with multiple inline notes per block landing in 7.1 the intent is to show everyone participating in unresolved threads (block level, inline, and replies), with the existing 3+ overflow behavior.

How?

NotesSidebar now passes the whole set of the block's threads to NoteAvatarIndicator rather than one picked thread, and two helpers moved into utils.js:

  • pickIndicatorNotes() keeps the previous resolved/unresolved preference - unresolved threads, falling back to all of them when none are unresolved.
  • getThreadParticipants() collects the distinct authors and repliers across those threads in chronological order. This is the same dedupe the component used to do inline, just testable on its own.

The click target is unchanged: the indicator still opens the primary thread via openNoteForBlock().

Unit tests cover both helpers, including the multi-thread case from the issue.

Testing Instructions

Test in WordPress Playground

Playground signs you in as a single user, so it won't show the two-user case below, but it is handy for checking a block-level note alongside an inline note and confirming replies still add avatars.

This needs two users to see the bug properly - eg. two browsers logged in as different users on the same post, with Notes enabled.

  1. As user A, select a paragraph block and add a block-level note.
  2. As user A, select some text in the same block and add a selection (inline) note.
  3. As user B, select different text in the same block and add another selection note.
  4. Select the block and look at the avatar indicator in the block toolbar.

Before: only user A's avatar shows. After: both avatars show.

Also worth checking:

  • A block with a single note still shows just that author, and a thread with replies still shows the repliers.
  • Resolve every note on a block - the indicator still behaves as it did before.
  • Add notes from four or more users to a block and confirm the "+n" overflow still renders.

Unit tests: npm run test:unit packages/editor/src/components/collab-sidebar/test/utils.jsdom.test.js

Testing Instructions for Keyboard

The toolbar button itself is unchanged - tab to the block toolbar and confirm the notes button is still reachable and activates with Enter or Space, and that its "View notes" label still reads correctly.

Screenshots or screencast

Use of AI Tools

The code, tests, and this description were written with 🤖 Claude Code. I will review and test.

A block can carry several note threads, but the toolbar indicator was wired
to a single "primary" thread picked by pickPrimaryNote(). Since block-level
notes sort ahead of inline ones, an unresolved block-level note always won
and other users who left inline notes on the same block never got an avatar.

Pass every thread on the block to NoteAvatarIndicator instead, and build the
participant list across all of them. pickIndicatorNotes() keeps the previous
resolved/unresolved preference (unresolved threads, falling back to all when
none are unresolved), and getThreadParticipants() moves the author + replier
dedupe out of the component so it can be tested directly.

The existing "+n" overflow handling covers the longer participant lists this
produces; the indicator's click target still opens the primary thread.

Fixes #82273
@adamsilverstein adamsilverstein added [Type] Bug An existing feature does not function as intended [Feature] Notes Phase 3 of the Gutenberg roadmap around block commenting [Package] Editor /packages/editor labels Sep 2, 2026
@coderabbitai

coderabbitai Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 35ce5816-7278-4a8d-b764-0dff3a5f0689

📥 Commits

Reviewing files that changed from the base of the PR and between 28c3d51 and 2a31ffc.

📒 Files selected for processing (4)
  • packages/editor/src/components/collab-sidebar/index.jsx
  • packages/editor/src/components/collab-sidebar/note-indicator-toolbar.jsx
  • packages/editor/src/components/collab-sidebar/test/utils.jsdom.test.js
  • packages/editor/src/components/collab-sidebar/utils.js

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The block toolbar avatar indicator now aggregates relevant note threads and participants. Shared utilities select indicator threads and deduplicate chronological participants. Tests cover unresolved-thread fallback, nested replies, ordering, deduplication, and missing data.

Changes

Collab sidebar indicator aggregation

Layer / File(s) Summary
Thread selection and participant utilities
packages/editor/src/components/collab-sidebar/utils.js, packages/editor/src/components/collab-sidebar/test/utils.jsdom.test.js
pickIndicatorNotes returns unresolved threads or all threads. getThreadParticipants combines authors and replies, orders them chronologically, and removes duplicate or unnamed participants.
Sidebar thread aggregation
packages/editor/src/components/collab-sidebar/index.jsx
The sidebar memoizes metadata-referenced threads and passes all selected threads to NoteAvatarIndicator.
Indicator participant rendering
packages/editor/src/components/collab-sidebar/note-indicator-toolbar.jsx
NoteAvatarIndicator uses getThreadParticipants for the aggregated notes prop.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 2a31f

This PR updates the block toolbar indicator to show participants from all relevant note threads while preserving existing thread-opening and overflow behavior; no actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant NotesSidebar
  participant CollabSidebarUtils
  participant NoteAvatarIndicator
  NotesSidebar->>NotesSidebar: Read note IDs from block metadata
  NotesSidebar->>CollabSidebarUtils: Select indicator threads
  CollabSidebarUtils-->>NotesSidebar: Return unresolved or all threads
  NotesSidebar->>NoteAvatarIndicator: Pass selected notes
  NoteAvatarIndicator->>CollabSidebarUtils: Extract thread participants
  CollabSidebarUtils-->>NoteAvatarIndicator: Return ordered unique participants
Loading

Suggested reviewers: ciampo

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The implementation satisfies issue #82273 by aggregating distinct authors and repliers across relevant block threads, preserving unresolved-thread preference, fallback behavior, primary-thread interac…
Out of Scope Changes check ✅ Passed All changes are related to issue #82273. The component updates, shared utilities, and tests directly support multi-thread participant aggregation and do not introduce unrelated scope.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: showing participants from every note thread in the block toolbar avatar indicator.
Full details: Linked Issues check

Explanation

The implementation satisfies issue #82273 by aggregating distinct authors and repliers across relevant block threads, preserving unresolved-thread preference, fallback behavior, primary-thread interaction, and overflow handling. Tests cover the new helper behavior.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/82273-avatar-indicator-all-threads

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

@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: adamsilverstein <adamsilverstein@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

📦 Bundle size

Size Change: -40 B (0%)

Total Size: 8.25 MB

📦 View Changed
Filename Size Change
build/scripts/editor/index.min.js 616 kB -40 B (-0.01%)

06988b4 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric d93b0c6 trunk % Change
timeToFirstByte 52.75 ms +9.57% -4.17% 54.9 ms +8.56% -8.29% -3.92%
largestContentfulPaint 84 ms +16.67% -2.38% 92 ms +4.35% -8.7% -8.7%
lcpMinusTtfb 32 ms +5.62% -6.87% 33.7 ms +15.88% -9.79% -5.04%
wpBeforeTemplate 27.13 ms +5.97% -4.68% 27.35 ms +15.65% -6.73% -0.8%
wpTemplate 22.62 ms +5.13% -5.08% 22.97 ms +4.79% -5.96% -1.52%
wpTotal 49.47 ms +8.93% -4.04% 51.08 ms +8.38% -7.5% -3.15%
wpMemoryUsage 7.62 MB +0% -0% 7.59 MB +0% -0% 0.46%
wpDbQueries 17 +0% -0% 17 +0% -0% 0%

front-end-classic-theme

Metric d93b0c6 trunk % Change
timeToFirstByte 39.35 ms +6.86% -1.78% 42.8 ms +5.84% -0.58% -8.06%
largestContentfulPaint 84 ms +4.76% -0% 92 ms +4.35% -0% -8.7%
lcpMinusTtfb 44.95 ms +1.33% -0.89% 49.55 ms +2.32% -0.5% -9.28%
wpBeforeTemplate 24.3 ms +3.83% -2.63% 23.83 ms +4.41% -0.84% 1.97%
wpTemplate 12.38 ms +4.77% -0.89% 16.3 ms +1.47% -0.98% -24.05%
wpTotal 36.83 ms +6.71% -1.71% 40.09 ms +5.96% -0.5% -8.13%
wpMemoryUsage 6.11 MB +0% -0% 6.20 MB +0% -0% -1.57%
wpDbQueries 10 +0% -0% 14 +0% -0% -28.57%

media-processing

Metric d93b0c6 trunk % Change
mediaProcessingJpeg 376.56 ms +3.14% -0.86% 375.16 ms +2.7% -1.82% 0.37%
mediaProcessingAvif 5608.67 ms +0.35% -0.45% 5618.59 ms +0.41% -0.14% -0.18%
mediaProcessingJpegToAvif 3870.25 ms +0.2% -0.61% 3863.26 ms +0.53% -0.43% 0.18%

media-upload

Metric d93b0c6 trunk % Change
jpegUploadProcessing 1403.96 ms +1.61% -0.18% 1402.27 ms +0.28% -0.53% 0.12%
pngUploadProcessing 206.32 ms +20.75% -18.64% 177.07 ms +22.7% -7.16% 16.52%
largeJpegUploadProcessing 1392.06 ms +1.52% -0.47% 1392.51 ms +0.39% -0.39% -0.03%
multipleImageUploadProcessing 1491.48 ms +1.29% -0.41% 1514.21 ms +2.79% -0.57% -1.5%

post-editor

Metric d93b0c6 trunk % Change
serverResponse 393.86 ms +8.16% -4.93% 411.74 ms +2.1% -5.28% -4.34%
firstPaint 278.86 ms +48.09% -20.78% 178.1 ms +20.01% -11.2% 56.57%
domContentLoaded 985.77 ms +2.47% -3.8% 957.86 ms +1.22% -1.78% 2.91%
loaded 986.86 ms +2.49% -3.76% 959.04 ms +1.21% -1.77% 2.9%
firstContentfulPaint 419.64 ms +6.35% -1.59% 407.08 ms +1.55% -6.93% 3.09%
firstBlock 2838.87 ms +1.48% -0.72% 2780.62 ms +0.88% -0.52% 2.09%
type 17.15 ms +4.61% -1.63% 17.96 ms +2.34% -3.12% -4.51%
typeWithoutInspector 17 ms +2% -4.47% 17.08 ms +1.7% -4.68% -0.47%
typeWithTopToolbar 21.94 ms +8.61% -0.96% 21.59 ms +3.29% -1.44% 1.62%
typeContainer 8.62 ms +6.5% -4.52% 7.96 ms +4.65% -3.77% 8.29%
focus 67.35 ms +8.11% -5.7% 69.45 ms +11.19% -5.2% -3.02%
firstFocus 177.06 ms +0% -0% 183.33 ms +0% -0% -3.42%
selectAll 405.9 ms +6.58% -1.73% 394.37 ms +0.76% -5.35% 2.92%
listViewOpen 57.85 ms +1.57% -4.06% 56 ms +6.71% -7.91% 3.3%
inserterOpen 21.48 ms +9.87% -4.38% 21.57 ms +5.42% -2.87% -0.42%
inserterHover 2.14 ms +11.21% -5.14% 2.17 ms +9.68% -11.06% -1.38%
inserterSearch 7.99 ms +10.89% -6.38% 7.9 ms +14.3% -1.65% 1.14%
loadPatterns 635.69 ms +5.04% -4.86% 669.85 ms +3.83% -3.51% -5.1%
wpTotal 384.04 ms +8.26% -5.07% 401.94 ms +1.97% -5.37% -4.45%
wpMemoryUsage 13.17 MB +0% -0% 13.13 MB +0% -0% 0.28%
wpDbQueries 54 +0% -0% 54 +0% -0% 0%

site-editor

Metric d93b0c6 trunk % Change
serverResponse 249.26 ms +2.08% -10.34% 229.89 ms +6.02% -4.52% 8.43%
firstPaint 183.9 ms +56.84% -14.74% 154.49 ms +10.06% -6.63% 19.04%
domContentLoaded 673.88 ms +2.94% -2.12% 660.65 ms +2.06% -0.88% 2%
loaded 674.75 ms +2.96% -2.12% 661.45 ms +2.09% -0.83% 2.01%
firstContentfulPaint 288.93 ms +1.07% -1.52% 293.13 ms +2.66% -5.58% -1.43%
firstBlock 2402.97 ms +2.65% -1.04% 2298.93 ms +1.23% -0.73% 4.53%
type 13.68 ms +3.14% -5.7% 12.04 ms +4.98% -3.82% 13.62%
navigate 76.73 ms +8.46% -12.9% 72.03 ms +4.44% -5.76% 6.53%
loadPatterns 862.15 ms +1.88% -3.12% 824.2 ms +2.2% -1.85% 4.6%
loadPages 1046.89 ms +1.46% -2.4% 1056.39 ms +1.38% -0.6% -0.9%
wpTotal 242.97 ms +1.95% -10.74% 223.35 ms +6.41% -4.58% 8.78%
wpMemoryUsage 12.14 MB +0% -0% 12.09 MB +0% -0% 0.41%
wpDbQueries 44 +0% -0% 44 +0% -2.27% 0%

06988b4 Run

adamsilverstein and others added 2 commits September 30, 2026 22:44
…icator-all-threads

# Conflicts:
#	packages/editor/src/components/collab-sidebar/index.jsx
@Mamaduka

Mamaduka commented Oct 1, 2026

Copy link
Copy Markdown
Member

Thanks, @adamsilverstein!

I pushed a few simplifications:

  • Inlined pickIndicatorNotes. It had a single caller.
  • Threads are matched by blockClientId, the same as openNoteForBlock. This drops the extra noteId select and fixes a mismatch when a note ID ends up on two blocks, e.g. after copy/paste.
  • Participants are now computed in the parent, and only when a block is selected. NoteAvatarIndicator just renders them.
  • Removed the reply ?? [] fallback (and its test); useNoteThreads always sets reply.

@Mamaduka

Copy link
Copy Markdown
Member

Closing, since this is no longer applicable after #84635.

@Mamaduka Mamaduka closed this Oct 19, 2026
@Mamaduka
Mamaduka deleted the fix/82273-avatar-indicator-all-threads branch October 19, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Notes Phase 3 of the Gutenberg roadmap around block commenting [Package] Editor /packages/editor [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Notes: toolbar avatar indicator only shows one thread's participants when a block has multiple notes

2 participants