feat: AI-game & resign UX cleanup (lobby drop, board reveal, GCG share fix, hide AI export) #80

Merged
developer merged 4 commits from feature/lobby-drop-left-ai-games into development 2026-06-17 12:11:24 +00:00
Owner

A batch of AI-game / resign UX changes (agreed with the owner to land together; one test-contour deploy).

1 — Drop left honest-AI games from the lobby finished list (backend)

A finished vs_ai game the player left — resign or 7-day inactivity timeout (end_reason resign/timeout) — no longer appears in that player's lobby finished list. New game.Service.ListForLobby filters ListForAccount for the lobby handler only; admin console and account-merge keep the full set; nothing is deleted from the DB. Keys on the game's end reason, not the seat. aborted is intentionally not matched. Test: TestListForLobbyDropsLeftAIGames.

2 — Reveal the full board on resign (UI)

After confirming a resign, Game.svelte closes the move-history drawer (portrait) and zooms the board out, so the resigned game shows its full final board. Test: game.spec.ts › "resigning reveals the full board".

3 — Don't strand the Mini App on a cancelled GCG share (UI bug fix)

Reported, reproducible iOS bug: resign → open history → Export GCG → the iOS share sheet appears → tap outside to cancel → the app is replaced by the raw GCG text in the WKWebView, unrecoverable (force-quit only). Root cause: cancelling Web Share fell through to the Blob <a download> fallback, and iOS ignores the download attribute, so the anchor click navigates the webview to the blob: URL. Fix: the share path no longer falls back to a download (Web Share is available there; a cancel/fail is a no-op, the user can retry). The download stays the desktop-only path. Test: share.test.ts › cancelled share never downloads.

4 — Hide GCG export in AI games (UI)

A vs_ai game is throwaway practice, so its finished history header no longer offers the 📤 export. Test: quickmatch.spec.ts › "no GCG export offered after it ends".

Verification

Backend: gofmt/vet/unit/integration green. UI: svelte-check (0), unit (274), e2e (144, Chromium + WebKit), build — all green locally. No migration / wire / gateway change; no contour wipe needed. Docs updated: FUNCTIONAL.md (+_ru), ARCHITECTURE.md, UI_DESIGN.md, Go Doc.

A batch of AI-game / resign UX changes (agreed with the owner to land together; one test-contour deploy). ## 1 — Drop left honest-AI games from the lobby finished list (backend) A finished `vs_ai` game the player left — **resign** or **7-day inactivity timeout** (`end_reason` `resign`/`timeout`) — no longer appears in that player's lobby **finished** list. New `game.Service.ListForLobby` filters `ListForAccount` for the lobby handler only; admin console and account-merge keep the full set; nothing is deleted from the DB. Keys on the game's end reason, not the seat. `aborted` is intentionally not matched. Test: `TestListForLobbyDropsLeftAIGames`. ## 2 — Reveal the full board on resign (UI) After confirming a resign, `Game.svelte` closes the move-history drawer (portrait) and zooms the board out, so the resigned game shows its full final board. Test: `game.spec.ts` › "resigning reveals the full board". ## 3 — Don't strand the Mini App on a cancelled GCG share (UI bug fix) **Reported, reproducible iOS bug:** resign → open history → Export GCG → the iOS share sheet appears → tap outside to cancel → the app is replaced by the raw GCG text in the WKWebView, unrecoverable (force-quit only). Root cause: cancelling Web Share fell through to the Blob `<a download>` fallback, and iOS ignores the `download` attribute, so the anchor click **navigates the webview to the blob: URL**. Fix: the share path no longer falls back to a download (Web Share is available there; a cancel/fail is a no-op, the user can retry). The download stays the desktop-only path. Test: `share.test.ts` › cancelled share never downloads. ## 4 — Hide GCG export in AI games (UI) A `vs_ai` game is throwaway practice, so its finished history header no longer offers the 📤 export. Test: `quickmatch.spec.ts` › "no GCG export offered after it ends". ## Verification Backend: `gofmt`/`vet`/unit/integration green. UI: svelte-check (0), unit (274), e2e (144, Chromium + WebKit), build — all green locally. No migration / wire / gateway change; no contour wipe needed. Docs updated: `FUNCTIONAL.md` (+`_ru`), `ARCHITECTURE.md`, `UI_DESIGN.md`, Go Doc.
developer added 1 commit 2026-06-17 11:04:09 +00:00
feat(lobby): drop left honest-AI games from the finished list
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Has been skipped
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m4s
2f4aa1b75b
A finished honest-AI (vs_ai) game the player left — by resigning or by
abandoning it to the 7-day inactivity timeout (end_reason 'resign'/'timeout')
— no longer appears in that player's own lobby finished list.

The new game.Service.ListForLobby filters ListForAccount for the lobby
endpoint only; the admin console and the account-merge count keep the full
set. The filter keys on the game's end reason, not on which seat left, so it
extends to any player should the robot ever resign.
developer added 1 commit 2026-06-17 11:33:35 +00:00
feat(ui): reveal the full board on resign (close history, zoom out)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 50s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 58s
2c24d54047
After the player confirms a resign, close the move-history drawer (portrait;
the landscape dock is unaffected) and zoom the board out if it was magnified,
so the resigned game shows its full final board.
developer changed title from feat(lobby): drop left honest-AI games from the finished list to feat: drop left AI games from the lobby list; reveal full board on resign 2026-06-17 11:34:07 +00:00
developer added 2 commits 2026-06-17 12:01:22 +00:00
On iOS WKWebView (the Telegram Mini App), cancelling the Web Share sheet fell
through to the Blob <a download> fallback. iOS ignores the download attribute,
so clicking the anchor navigated the webview to the blob: URL — replacing the
SPA with the raw GCG file, with no way back (force-quit only).

The share path no longer falls back to a download: Web Share is available on
that platform, so a cancelled or failed share is a no-op and the user can
retry. The Blob download stays the desktop-only path (no Web Share).
feat(ui): hide GCG export in honest-AI games
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 51s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m1s
fb0ddab0f1
A vs_ai game is throwaway practice, so its finished history header no longer
offers the 📤 GCG export (an empty slot keeps the comms icon pinned right).
Docs note the AI exclusion; UI_DESIGN also records that confirming a resign
reveals the full board (closes the history drawer, zooms out).
developer changed title from feat: drop left AI games from the lobby list; reveal full board on resign to feat: AI-game & resign UX cleanup (lobby drop, board reveal, GCG share fix, hide AI export) 2026-06-17 12:01:44 +00:00
owner approved these changes 2026-06-17 12:10:47 +00:00
developer merged commit 5a3f0951ae into development 2026-06-17 12:11:24 +00:00
developer deleted branch feature/lobby-drop-left-ai-games 2026-06-17 12:11:24 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#80