feat(ui): vs-AI comms trim, overlay confirm button, recall-to-slot drag
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 10s
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 1m8s

- vs-AI: the comms hub drops the Chat tab (Dictionary only); a finished AI
  game has no comms at all, so its 💬 history-header entry is hidden too.
- Confirm-move : redone as an absolute overlay pinned to the right edge (its
  right edge sits under the preview caption), so the rack keeps a fixed tile
  size — this reverts the tile-shrink that resized the letters at 6 tiles.
- Recall: dragging a placed tile back to the rack now drops it at the slot the
  pointer is over (drag-to-position, a gap opens), instead of snapping to its
  original slot; double-tap still recalls to the origin. New pure recallToSlot.

Tests: placement recallToSlot units; e2e recall-to-position; vs-AI comms e2e
updated. Docs: UI_DESIGN + FUNCTIONAL (+ru).
This commit is contained in:
Ilia Denisov
2026-06-19 09:54:30 +02:00
parent b5688d4848
commit 4adb608ad1
10 changed files with 179 additions and 45 deletions
+9 -6
View File
@@ -32,7 +32,8 @@ except Login uses `Screen`.
bottom tab bar whose tabs switch its body **in place** (state, not navigation), so the
back control always returns to the hub's parent (Settings → lobby, comms → game). Settings
hub tabs: ⚙️ Settings / 👤 Profile / 🤝 Friends / ️ About (Friends hidden for guests);
comms hub tabs: 💬 Chat / 🔎 Dictionary (Dictionary only while the game is active). The
comms hub tabs: 💬 Chat / 🔎 Dictionary (Dictionary only while the game is active; an
honest-AI game has no Chat, so it shows the Dictionary alone). The
routes `/settings|/profile|/friends|/about` and `/game/:id/{chat,check}` survive as hub
entry points (so a Telegram friend-code deep-link still lands on the Friends tab). The
**Feedback** screen is its own deeper route `/feedback` (back → `/about`, the Info tab), so
@@ -110,8 +111,9 @@ except Login uses `Screen`.
dragging it onto a cell; while a dragged tile is carried over the board, the aimed-at empty
cell is **highlighted as a drop target** (an accent ring). A pending tile is taken back by a
**double-tap** or by **dragging it back onto the rack** (unzoomed board only — when zoomed
the one-finger gesture scrolls). A single tap no longer recalls (too easy to trigger); a
recalled tile returns to its original rack slot.
the one-finger gesture scrolls). A single tap no longer recalls (too easy to trigger). A
**double-tap** returns the tile to its original rack slot; **dragging it back** drops it at the
rack slot the pointer is over (a gap opens there), the same drag-to-position as a rack reorder.
- **Players plaque & history** (`Game.svelte`): the seats above the board share
the width evenly; the seat whose turn it is is **raised** (a drop shadow on its sides)
while the others read **sunk in** (an inset shadow). A tap on the plaque toggles
@@ -284,8 +286,9 @@ enabled on the first, uncached load) and flip in place when an event refreshes t
under Start game notes the wait can take a while (the app may be closed meanwhile). With **AI**
selected there is no wait: the move-clock line instead reads **"Loss after 7 days of inactivity"**
and the "searching" hint is hidden; the game starts already seated, the opponent shows as **🤖**
everywhere (score card, lobby row, turn line), the add-friend 🤝 is never drawn, and the chat's
send field and 🛎️ nudge stay **disabled** while the 🔎 dictionary word-check keeps working.
everywhere (score card, lobby row, turn line), the add-friend 🤝 is never drawn, and there is
**no chat at all**: the comms hub drops the 💬 Chat tab and offers only the 🔎 dictionary
word-check (the 🛎️ nudge is likewise gone).
- **Statistics** (`screens/Stats.svelte`, the lobby ✏️ tab): a 2-column grid of stat
cards (games / wins / draws / losses / moves / hint-share / best game / win-rate) —
pure numbers, no charts; hint-share is a one-decimal percentage in the active locale's
@@ -318,7 +321,7 @@ enabled on the first, uncached load) and flip in place when an event refreshes t
never in an honest-AI game (throwaway practice). Confirming a resign reveals the full board:
it closes the history drawer (portrait) and zooms the board out.
- **Finished game**: the board keeps no last-word highlight and no zoom; the history header
offers *Export GCG* (not *Drop game*; an AI game offers neither) and the comms hub hides the 🔎 *Dictionary* tab; and
offers *Export GCG* (not *Drop game*; an AI game offers neither) and the comms hub hides the 🔎 *Dictionary* tab — and a **finished AI game has no comms at all** (no chat, dictionary closed), so its 💬 entry is dropped from the header too; and
the footer (rack + tab bar) is **drawn but inert** (greyed, non-interactive) rather than
hidden, so the layout does not jump. Chat send / nudge are the ⬆️ / 🛎️ icons. The input
row is turn-driven: on your turn the message field shows until your one allowed message is