Skip to content

fix: propagate name changes to peers with a rename event - #12

Merged
JheisonMB merged 2 commits into
mainfrom
develop
Aug 12, 2026
Merged

fix: propagate name changes to peers with a rename event#12
JheisonMB merged 2 commits into
mainfrom
develop

Conversation

@JheisonMB

Copy link
Copy Markdown
Contributor

What

Renaming yourself in a room never reached the other players. The name changed on your own screen, but the desk kept showing the old one — including when it came time to vote.

Root cause

The rename has to travel three hops, and it broke at the second.

The wire had no rename message. protocol.js shared a name exactly once, in the join handshake. Any rename after joining had no way to reach a peer, so every other client kept the value it learned when you arrived.

The UI had a workaround for this, and the workaround was broken too:

setTimeout(() => startRoom(root, roomId, userId, newName), 600);   // room.js:538

renderWaiting(el, s, userId, protocol, force, roomId) has no root parameter and no binding for it in scope, so this threw ReferenceError inside a timer callback and vanished silently. That is why the symptom looked so strange: setUserName persisted the new name to localStorage and the peer-list row painted its , while state.participants[userId].name — the value the desk actually renders — never moved.

Even a working restart would not have fixed the remote side. Peers reject a re-join for an id that already has a live connection, so they would have kept the old name regardless.

The render layer was innocent throughout: renderVoting, renderRevealed and the reveal overlay all read p.name from participants at render time, and votes never embed a name.

The fix

A rename action on the wire, plus setName(name) which mutates self — so later join and state-sync payloads carry the new value — rewrites our own participant record, broadcasts, and emits. getRename applies the same ownership check as vote, leave and heartbeat (a peer cannot rename someone else) and passes the incoming value through cleanName.

The UI now calls protocol.setName(newName) instead of restarting the room. The 600 ms flourish stays; a done flag stops the Enter-then-blur double save.

Tests

describe('protocol — rename'), seven cases: the local record updates and broadcasts; a rename mid-round survives into the voting phase alongside the vote; later join/state-sync payloads carry the new name; an incoming rename from the owning connection is applied; a renamed peer can still vote (records are keyed by id, not name); a rename forged on another participant's behalf is rejected; oversized and blank incoming names are sanitized.

Six of the seven fail against HEAD~1, verified by swapping the old protocol.js back in. Full suite 88/88, npm run build clean.

Known issue found but not fixed here

getStateSync rebuilds state without storyIds or storyId, though createInitialState sets both. A peer that joins via state-sync therefore has state.storyIds undefined, and renderWaiting (s.storyIds[i]) and startVoting (state.storyIds[idx]) will throw for it. storyIds is also never broadcast, so per-story results cannot line up across peers. Separate bug, separate PR.

Note on CI

ci.yml triggers on pull_request, so this PR is its first automated run — the push to develop did not trigger one.

Renaming yourself in a room only wrote the new name to localStorage and
then tried to restart the room; peers were never told, so the desk kept
rendering the name from the join handshake. The restart itself was dead
code: it called startRoom(root, ...) from renderWaiting, where root is
not in scope, so it threw before doing anything.

Add a 'rename' action to the protocol plus a setName() API that updates
self (what later joins and state-syncs carry), rewrites our participant
record and broadcasts the change. Incoming renames are accepted only
from the connection that owns the identity and are name-sanitized like
any other peer string.
@JheisonMB JheisonMB added the target:main PR targets main branch label Aug 12, 2026
@JheisonMB
JheisonMB merged commit 8ab1fb9 into main Aug 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

target:main PR targets main branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant