Commit graph

6 commits

Author SHA1 Message Date
AyoubBenziza
e0ba4c2e23 feat(web): "What's new" patch notes modal
- curated, bilingual player-facing notes (lib/patch-notes.ts) — a public subset
  of CHANGELOG.md (which stays the technical source of truth)
- "Nouveautés" button on home with a dot badge when the app version changed
  since last seen (localStorage); opening marks the version seen
- app version injected at build via Vite define (__APP_VERSION__)
- add shadcn Dialog component (@workspace/ui, via radix-ui)

Verified: notes + version baked into the build; typecheck/lint/build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 09:17:52 +02:00
AyoubBenziza
7a41bbf8c1 feat: DJ can be contributor, volume, theme switch, clock sync, 90s blindtest
Playtest feedback round 2:
- blindtest DJ can now be anyone incl. the track's contributor (pickDj only
  excludes bots) — no more "immunity" for whoever isn't picked
- blindtest rounds last 90s (longer listen + typing)
- per-player volume slider (persisted), YT player setVolume + origin/enablejsapi
- theme switcher (light/dark/system) on home + room header
- clock sync: clients estimate the server-clock offset (time:sync) so the
  countdown is identical across devices (was off by each device's clock skew);
  also used for blindtest media sync

Note on duplicates: anti-repeat is per room code (quiz_played) — it works when
you replay in the SAME room, but a new room starts fresh. Verified e2e: two
chained games in one room share 0 questions.

Verified: typecheck 4/4, lint 4/4, 24 server tests, web build; e2e dedup (0
overlap) and clock/DJ behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 00:39:02 +02:00
AyoubBenziza
1e5ef2be90 feat(web): i18n (FR/EN) — homemade typed dictionary
- lightweight, dependency-free i18n: typed fr/en dictionaries (fr is the source
  of truth, en must match its shape → compile error on drift), I18nProvider +
  useI18n hook, browser detection + localStorage persistence
- FR/EN language switcher (home + room header)
- translated the whole player-facing flow: home, join, pseudo, room shell,
  lobby (incl. settings, categories, bots, track submission, history),
  quiz, blindtest, player-cards, round transitions, end screen (podium, awards,
  tracks, rounds recap), and server-error messages (mapped by code)
- history dates localized to the active language

Content (questions/categories) intentionally left as-is. Back-office (admin)
not translated yet — internal, token-gated tool.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 19:03:28 +02:00
AyoubBenziza
3f0cab8f5f feat: end-of-game track recap, no self-vote in who_added, festive home + icons
- game:end now carries the played blindtest tracks (title/artist/youtubeId/
  url/submittedByName); the end screen lists them as cards with a YouTube
  open link so players can recover/export the songs
- who_added vote no longer lets you pick yourself (filtered out)
- home page: animated halo, floating geek emojis, springy gradient title,
  hover/tap on buttons (Framer Motion) + Lucide icons
- lobby settings get Lucide icons (game type, quiz, blindtest mode, tracks,
  start)

Verified e2e: game:end includes the track list with links.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 16:04:14 +02:00
AyoubBenziza
1071a59b68 feat: pick pseudo inside the room + shareable invite link
Restructure onboarding (option B):
- home is just Create / Join (code) — no name field
- name is chosen in the room: room:create/join no longer require a name;
  new player:setName event. Nameless players are hidden from the snapshot
  (players/scores/submissions) and excluded from eligible voters and the
  3-player blindtest gate until they pick a pseudo.
- PseudoScreen with live DiceBear avatar preview gates RoomPage until set
- /join/:code auto-joins then redirects to the room (seamless invite links)
- RoomCode gains a "copier le lien" button (origin/join/CODE)

Verified e2e: nameless players excluded from the room until setName.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 15:32:24 +02:00
AyoubBenziza
29faa18731 feat(server,web): first real-time cycle — room create/join + lobby
Server (@nerdware/server):
- RoomManager: in-memory rooms (Map), code generation, create/join,
  disconnect handling, public snapshot projection (no secrets)
- Socket.IO handlers: room:create / room:join with typed acks,
  room:state broadcast on every change, lobby:updateSettings (host-only),
  player:left on disconnect

Web (web):
- typed Socket.IO client + Zustand store mirroring room:state
- wouter routing: home (create/join) + minimal lobby (live player list)
- @nerdware/shared wired into the client

Roadmap V1 step 2. Verified end-to-end (create/join/broadcast/disconnect).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:16:26 +02:00