UI: render move history as a per-seat column grid + swipe-down to open
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 42s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 58s

Replace the flat chronological move list with a ruled matrix aligned under the
score plaque: one column per seat, each seat's moves filling its column top to
bottom. A cell is the move's word(s) and its score, "WORD (12)", centred; the
player names and the running total are dropped (the plaque heads the column and
shows the live total). Non-play moves keep their dim parenthesised tag; the
awaited opponent's next cell shows a dim "thinking..." (never the viewer's own
turn). Thin 1px rules between columns and rows match the panel's separator.

Re-introduce a swipe-down-on-the-board gesture to open the history, gated to the
zoom-out board scrolled to its top so it never fights the zoomed board's pan or
the stage's own vertical scroll (the conflict that retired this gesture before).

Grid layout extracted to lib/history.ts (unit-tested); add game.thinking to the
EN/RU catalogs; e2e covers the gesture and the grid on Chromium and WebKit.
This commit is contained in:
Ilia Denisov
2026-06-11 20:18:23 +02:00
parent 4c65923544
commit e68fe61e39
8 changed files with 327 additions and 60 deletions
+15 -8
View File
@@ -79,9 +79,12 @@ Login uses `Screen`.
back near the edges. It **recentres only on a zoom-in** — placing a 2nd+ tile or
hovering a dragged tile never jumps the board. On touch the first tile placement auto-zooms
in centred on the target, and **holding a dragged tile over a cell ~1 s** auto-zooms there
the first time. The swipe-to-open-history gesture stays dropped (it fought native scroll);
history opens on a **tap of the score bar** and closes on a tap or an **upward swipe** of
the then-inert board (below). A **hint** auto-zooms centred on the hint's placement, not
the first time. A **swipe down on the zoom-out board** opens the history, but only when the
board is scrolled to its top so it never fights the stage's own vertical scroll (the conflict
that once retired this gesture) — and it is suppressed on the zoomed board, where the
one-finger drag pans. History also opens on a **tap of the score bar** and closes on a tap or
an **upward swipe** of the then-inert board (below). A **hint** auto-zooms centred on the
hint's placement, not
the top-left.
- **Placing & recall** (`Game.svelte`): a rack tile is placed by tap-then-tap or by
dragging it onto a cell; while a dragged tile is carried over the board, the aimed-at empty
@@ -94,8 +97,12 @@ Login uses `Screen`.
while the others read **sunk in** (an inset shadow). A tap on the plaque toggles
the **move history** — a fixed-height slide-down drawer whose bottom border (and its
shadow) pins to the board as the board slides down, instead of tracking the table as
moves accumulate; its scrollbar gutter is reserved so the centred word column does not
jitter. A move's row lists every word it formed (the main word first). While the history
moves accumulate; its scrollbar gutter is reserved so the centred cells do not jitter. The
history is a **ruled matrix** — one column per seat, aligned under the score plaques, each
seat's moves filling its column top to bottom: no player names (the plaque heads the column)
and no running total, just the word(s) and the move score, `WORD (12)`, centred. A non-play
move keeps its dim parenthesised tag `(pass)`; the seat whose move is awaited shows a dim
`thinking…` in its next cell (never the viewer's own). While the history
is open the **slid board is inert** and the stage cannot scroll, so the whole board reads
as a **tap-or-swipe-up-to-close** surface — closing genuinely clears the open state (it no
longer merely scrolls the board out of view, which used to leave a stale-open state that
@@ -189,9 +196,9 @@ IV 🏅; active games show Your move 🟢 / Opponent's move ⏳; invitations use
- **Friend code**: the issued code sits next to a 📋 copy control; tapping the code or
the icon copies it. Flex text inputs carry `min-width:0` so they shrink instead of
overflowing in Safari.
- **History / GCG**: the in-game slide-down history gains the running total per move;
*Export GCG* (the 📤 in the history header) shares or downloads the `.gcg` file and
appears only once the game is finished.
- **History / GCG**: the in-game slide-down history lays each move out in a per-seat grid
(the word(s) and the move score, no running total); *Export GCG* (the 📤 in the history
header) shares or downloads the `.gcg` file and appears only once the game is finished.
- **Finished game**: the board keeps no last-word highlight and no zoom; the history header
offers *Export GCG* (not *Drop game*) and the comms hub hides the 🔎 *Dictionary* tab; and
the footer (rack + tab bar) is **drawn but inert** (greyed, non-interactive) rather than