The host-control desync dialog and the "watching on your own" badge were
hardcoded English — content.js has no i18n loader. Background does, so it now
resolves the strings (GET_HCM_STRINGS: loadLocale + getMessage) and content
fetches them on init with English fallbacks, re-rendering the badge if it was
already shown. The dialog body is now generic (dropped the paused/jumped verb)
to keep translation clean across languages.
Adds 6 keys (HCM_DIALOG_TITLE/BODY/STAY/SOLO, HCM_BADGE_SOLO/RESYNC) translated
across all 15 popup locales.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bis auf peerId-Auth (akzeptiert) alle Audit-Findings behoben:
- Snap-back spielt nicht mehr blind ab, wenn Host-Status unbekannt
- Teardown-Pfade broadcasten jetzt CONTROL_MODE → kein verwaistes Badge/Dialog
- Dialog-Timer bei Ersetzung sauber gecleart
- Server re-synchronisiert Sender bei nicht-Host-Reject
- Popup-Toggle revertiert bei Server-Ablehnung
- Desync-Zweig sendet keine Phantom-ACKs mehr an Host
- Toggle-Debouncing serverseitig (500ms pro Raum)
- Button-Text auf Unlock zurückgesetzt
- Live-Erkennung defensiver, Resync-Retry bei fehlendem Target, Badge-Retry
Neu: Host sieht 'Solo'-Badge für desyncte Gäste via PEER_STATUS-Heartbeat
(16 Sprachen, neuer i18n-Key BADGE_DESYNCED/TOOLTIP_PEER_DESYNCED)
Tests: H-5-Reject-Unicast, M-4-Debounce, Desync-Heartbeat-Relay
Final wiring of host control mode — the user-facing UI:
- Active-room section gains a Host Control card: a Host/Guest role badge, a
host-only toggle ("Only I can control playback") shown to the host, and a
guest notice when the room is host-only.
- Toggle sends SET_CONTROL_MODE; UI refreshes from the server's CONTROL_MODE
broadcast (with optimistic revert on failure). Card updates on GET_STATUS,
CONTROL_MODE, and reconnect.
- i18n: 6 new keys (LABEL_HOST_CONTROL[_TOOLTIP], LABEL_HOST_ONLY_TOGGLE,
NOTICE_HOST_CONTROLS, BADGE_HOST, BADGE_GUEST) translated across all 15
popup locales.
Completes the feature end to end (server + background + content + popup).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add two new languages (uk, zh / zh_CN) across the extension and website:
register them in SUPPORTED_LANGUAGES, the Chrome _locales map, the website
build/lang-init/app routing, hreflang/og/schema tags and language selectors.
Fix systematic machine-translation word-sense errors in the new zh/uk
locales (e.g. zh "Status"=地位→状态, "Leave Room"=留出空间→离开房间,
"Play"=玩→播放, "Seek"=寻找→跳转, audio Attack/Release/Knee; uk "Play"=Грати
→Відтворити, "Clear"=ЯСНО→Очистити, "Open"=ВІДЧИНЕНО→Відкрити, peers
"Однолітки"→"Учасники"), translate remaining English leftovers (Room ID,
Custom) and normalise terminology. All 15 locales pass test-locales.cjs.
Note: popup.html and website/template.html also carry the language-selector
additions here; their Ko-Fi→Support label text is part of the branding change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Fix: CONNECT/RETRY_CONNECT always force-disconnect before reconnecting
(prevents JOIN_ROOM going to official server when custom is selected)
- Add forceDisconnect() helper: clears socket, eventQueue, episodeLobby,
expectedAcksCount, broadcast status, persists cleanup to storage
- Fix: save useCustomServer to storage on Join Room click (no race condition)
- Fix: trigger RETRY_CONNECT on server mode toggle and custom URL change
- Fix: show error when Custom selected but no URL entered (no silent fallback)
- Fix: button label changed to 'Join / Create Room' in all 6 locales
- Rewrite scheduleReconnect() for two-phase strategy:
Phase 1 (aggressive): 500ms-5s backoff, max 20 attempts or 5 minutes
Phase 2 (slow): retry every 5 minutes indefinitely, never give up
- Persist reconnectAttempts/reconnectStartTime/reconnectFailed to session storage
- Remove 'reconnect_failed' status; slow mode shows as 'reconnecting' with retry button
- Add scheduleReconnect() call on offline path to continue retry cycle