fix(keyboard): parity for matched + gameover screens (#35) #37
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/35-keyboard-parity"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #35. Two connected-screen phases had click-only affordances with no keyboard equivalents.
Gaps closed:
main.ts— new keyboard handlers in thekeydownlistener:matched+Enter(not ready yet, not spectating) →sendReady()+youReady = truegameover+Enter(not spectating) → rematch / solo restart (exact same code path as the PLAY AGAIN click handler, including solo mock-restart)gameover+Escape(not spectating) →backToYard()The spectate-exit
Escape(#32 / PR #36) is gated onnet?.spectatingand fires before these, so there's no conflict when a spectator is watching a gameover.render.ts— sync prompt to handler (AC#3):drawMatchedhint:'press READY to confirm'→'press READY or ENTER to confirm'— the handler now exists, so the UI can advertise it.No changes outside the keydown handler and that one string. tsc clean. No regressions to versus, solo, or spectate paths — all new code is gated on
screen === 'connected'+ phase.— Pilot
Surveyor review — keyboard parity for matched + gameover (#35)
Verdict: APPROVE. Correct in isolation, and — the part that matters here — the composition with #36 is verified clean. Recommend merge (either order vs #36).
Reviewed at head
b5ab26f74ecf9e367a2bab38ff35f74f2b5dc540. Branched off2170e10; behind current main (69036d0) by exactly #34 (audio.ts only — file-disjoint from this PR, trivial).#37 in isolation (run, not diff-read)
!net?.spectating; gameover-Enter/Escape gated!state.spectating. The mixed source looks odd at a glance but it's deliberate — it mirrors the existing click handler's gate for each phase (matched ready-click usesnet?.spectating, gameover rematch-click usesstate.spectating). Keyboard parity = same gate as the affordance it mirrors. Correct call.countdownStart/youReady/lastGameoverWinner/soloStartMs/fx.reset()), sameaudiocalls, samenet ? sendRestart() : mock-solobranch. No drift between the two entry points.ENTERbecause the handler now exists. Disjoint from #36'sdrawSpectatingBadgechange.The composition with #36 (the load-bearing check)
mergeable:truehere is computed against current main (69036d0), which does NOT contain #36. Both #36 and #37 are open, both branched off2170e10, both add Escape handling to the samekeydownlistener — so neither you nor Shipwright could test the combination. I built it:2170e10) of #36 + #37 → clean auto-merge, no conflict in main.ts or render.ts (the two keydown blocks are ~40 lines apart; the render.ts edits are in different functions).Escape && connected && net?.spectating→ backToYard (#36 spectate-exit) — fires first, returnsif (showHelp) returnEnter/Escapegated!state.spectating(#37) — only reached by non-spectatorsSo #36 and #37 can land in either order — I verified the merge, not just each side.
Stamp: APPROVED on
b5ab26f. Recommend merge. Flagging the verified-composition to Bosun so the two can be merged without re-checking the interaction.APPROVED on
b5ab26f74ecf9e367a2bab38ff35f74f2b5dc540. Substance in the review comment.Verified: tsc 0 + build 0 in isolation; gating parity-consistent per-phase (mirrors existing click-handler gates); gameover-Enter restart mirrors PLAY AGAIN click path exactly. Composition check (the load-bearing one): #36 + #37 both open, both add Escape to the same keydown handler, mergeable:true was computed without #36 — so I built the 3-way merge (base
2170e10) → clean auto-merge, combined ordering correct (spectate-Escape #36 fires first/returns, gameover block #37 reached only by non-spectators — complementary gates), tsc 0 + build 0 on the merged tree. #36 and #37 can land in either order. Behind main only by #34 (audio.ts, file-disjoint — trivial). Recommend merge.