Commit graph

3 commits

Author SHA1 Message Date
f0d08f3b50 feat(frontend): add private room UI flow (create/join/repeat)
- frontend/src/ui/privateRoomFlow.ts: create-room sub-flow (time/theme
  mode form, large shareable code, copy-to-clipboard with graceful
  no-op fallback, waiting-for-opponent state) and enter-code sub-flow
  (numeric input + inline room:error retry, no dead end). Handles
  room:joined for both themeMode:'random' (straight into the live
  match) and 'chosen' (vote-wait placeholder, TODO(#16) for the real
  vote modal). Listens for round:nextMatch to show a brief 'Match N of
  5' transition, and room:closed to show the reason and return to the
  main menu. A room with no active session yet (waiting alone, or
  mid-vote) is abandoned via a socket disconnect/reconnect cycle, since
  player:quit is a no-op server-side without a session to attach to.
- frontend/src/game/multiplayerMatch.ts: MultiplayerMatch now owns
  #split-view visibility (shown in startRound, hidden in
  teardownRound), mirroring botMatch.ts's existing convention — nothing
  previously made the opponent pane visible for a real multiplayer
  match.
- frontend/src/net/client.ts: exports a shared `client` GameClient
  singleton (connects on import) so private rooms and matchmaking use
  one socket instead of each constructing their own.
- frontend/index.html: adds the #private-room-mount overlay container.
- frontend/src/style.css: private-room-* styles for the code display,
  join form, and error/status text.
- frontend/src/main.ts: replaces only the enterCodeBtn/createRoomBtn
  TODO stubs with real privateRoomFlow wiring; findMatchBtn line
  untouched.
2026-09-10 14:07:20 -03:00
12423cec1d feat(frontend): add quit button and matchmaking ban UX
- index.html/style.css: destructive-styled #match-quit-btn in the in-match
  HUD row, two-click arm/confirm (no heavyweight modal).
- multiplayerMatch.ts: wires the button (send player:quit, tear down
  timer/listeners/opponent pane immediately, no server reply awaited),
  adds an optional onQuit constructor callback for a future host
  (#14/#15) to route back to the main menu -- nothing mounts
  MultiplayerMatch yet, so this ticket's own quit-button wiring is what
  exercises it.
- ui/banBanner.ts (new): standalone renderBanBanner(container,
  bannedUntil) countdown, ready for #14 to mount into #menu-matchmaking.
  Not wired anywhere yet: per session.js/queue.js, quitting a
  matchmaking match pushes nothing to the quitter directly -- the only
  wire message carrying ban info is queue:banned, sent in reply to a
  later queue:join while banned.

Verified against a real backend + real browser tab driving
MultiplayerMatch through an actual matchmaking match (paired against a
raw ws opponent): quit sends player:quit, opponent gets
room:playerLeft + room:closed(reason:quit) with no ban message; a
follow-up queue:join from the quitter correctly receives queue:banned
(bannedUntil ~120s out) and renderBanBanner counts it down live.
Repeated via room:create/room:join (private room): identical
teardown/onQuit behavior, opponent gets zero ban-related messages, and
the quitter's earlier matchmaking ban is left completely unchanged.
2026-09-10 12:40:50 -03:00
5190ec19a3 feat(frontend): add in-match orchestrator and multiplayer scoreboard
New multiplayerMatch.ts (MultiplayerMatch class) drives one round: syncs
ThemeGuessGame/OpponentView to a round:start payload, relays local
category assignments as round:progress, forwards opponent round:progress
to OpponentView, drives timerHud's countdown (submitting the local color
map as round:submit at expiry), and renders a two-column scoreboard on
round:reveal via computeMatchResult.

ThemeGuessGame gains an optional onCategoryAssigned?(id, hex) constructor
callback, invoked as the last step of applyColor.

timerHud's TimerHudOptions gains an optional onExpire?() callback on the
countdown variant, fired once when endsAt passes.

resultView.ts gains renderMultiplayerResult() for the two-column
you/opponent scoreboard + winner banner (equal overall -> explicit draw).

index.html/style.css: additive #mp-scoreboard/#mp-winner-banner/#mp-you-*/
#mp-opponent-* markup and .mp-* styles; existing single-player result
markup untouched aside from adding id="solo-score-meter-wrap" so it can
be toggled off during a multiplayer reveal.
2026-09-10 12:16:15 -03:00