What problem does this address?
If a single WordPress user has the same post open in two (or more) tabs simultaneously, they appear as multiple separate entries in the collaborators list, each with its own avatar and color. This is misleading — other collaborators perceive more concurrent editors than there actually are, and the user themselves sees their own avatar duplicated.
#76145 and #75648 addressed the related ghost-session-after-refresh issue (closed via #75883, which added pagehide-based clean disconnects). Those fixes do not cover the deliberate multi-tab case, because both tabs are genuinely live Yjs awareness clients.
Root cause
The presence list is keyed by Yjs clientId, which is per-connection, not by WordPress user ID:
awareness-state.ts:284-290 — builds the state map keyed by clientId.
collaborators-presence/index.tsx:105 and list.tsx:78 — render with key={collaboratorState.clientId}.
There is no dedup on collaboratorInfo.id (the WordPress user ID) before rendering.
Proposed solution
When rendering the collaborators list (header avatars and popover list), group awareness states by WordPress user ID and render one entry per user. Pick a canonical session for display (e.g. most recently active).
This is a render-layer change only. The underlying awareness state stays per-clientId so cursor/selection rendering for each individual session continues exactly as it does today.
What problem does this address?
If a single WordPress user has the same post open in two (or more) tabs simultaneously, they appear as multiple separate entries in the collaborators list, each with its own avatar and color. This is misleading — other collaborators perceive more concurrent editors than there actually are, and the user themselves sees their own avatar duplicated.
#76145 and #75648 addressed the related ghost-session-after-refresh issue (closed via #75883, which added
pagehide-based clean disconnects). Those fixes do not cover the deliberate multi-tab case, because both tabs are genuinely live Yjs awareness clients.Root cause
The presence list is keyed by Yjs
clientId, which is per-connection, not by WordPress user ID:awareness-state.ts:284-290— builds the state map keyed byclientId.collaborators-presence/index.tsx:105andlist.tsx:78— render withkey={collaboratorState.clientId}.There is no dedup on
collaboratorInfo.id(the WordPress user ID) before rendering.Proposed solution
When rendering the collaborators list (header avatars and popover list), group awareness states by WordPress user ID and render one entry per user. Pick a canonical session for display (e.g. most recently active).
This is a render-layer change only. The underlying awareness state stays per-clientId so cursor/selection rendering for each individual session continues exactly as it does today.