ui/phase-26: history mode (turn navigator + read-only banner)

Split GameStateStore into currentTurn (server's latest) and viewedTurn
(displayed snapshot) so history excursions don't corrupt the resume
bookmark or the live-turn bound. Add viewTurn / returnToCurrent /
historyMode rune, plus a game-history cache namespace that stores
past-turn reports for fast re-entry. OrderDraftStore.bindClient takes
a getHistoryMode getter and short-circuits add / remove / move while
the user is viewing a past turn; RenderedReportSource skips the order
overlay in the same case. Header replaces the static "turn N" with a
clickable triplet (TurnNavigator), the layout mounts HistoryBanner
under the header, and visibility-refresh is a no-op while history is
active.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-12 00:13:19 +02:00
parent 070fdc0ee5
commit 2d17760a5e
20 changed files with 1572 additions and 118 deletions
+7 -5
View File
@@ -112,11 +112,13 @@ wipes every namespace.
Namespaces in current use:
| Namespace | Key | Value type | Owner |
|-----------------|---------------------|------------------|-----------------------------|
| `session` | `device-session-id` | `string` | Phase 7+ |
| `game-prefs` | `{gameId}/wrap-mode` | `WrapMode` | Phase 11+ (`game-state.md`) |
| `order-drafts` | `{gameId}/draft` | `OrderCommand[]` | Phase 12+ (`order-composer.md`) |
| Namespace | Key | Value type | Owner |
|-----------------|--------------------------------|------------------|------------------------------------|
| `session` | `device-session-id` | `string` | Phase 7+ |
| `game-prefs` | `{gameId}/wrap-mode` | `WrapMode` | Phase 11+ (`game-state.md`) |
| `game-prefs` | `{gameId}/last-viewed-turn` | `number` | Phase 11+ (`game-state.md`) |
| `order-drafts` | `{gameId}/draft` | `OrderCommand[]` | Phase 12+ (`order-composer.md`) |
| `game-history` | `{gameId}/turn/{N}` | `GameReport` | Phase 26+ (`game-state.md`) |
Later phases will add more per-feature namespaces (fixtures, lobby
snapshot, etc.). The contract is namespace-strings stay scoped to