release: promote development → master (v1.22.0) #274

Merged
developer merged 6 commits from development into master 2026-07-14 23:13:25 +00:00
6 changed files with 8 additions and 8 deletions
Showing only changes of commit 1d306ec0fc - Show all commits
+1 -1
View File
@@ -50,7 +50,7 @@ tail — at a real control, and a **tap anywhere** advances to the next; after t
overlay is gone for good. Two independent series run. The **lobby** series points at the
⚙️ settings, ✏️ statistics and 🎲 new-game tabs. The **game** series, on the player's first game
board, points at the scoreboard header (move history / chat / word-check), the 🔄 pass-and-exchange,
🛟 hints and 🔀 shuffle controls, and the rack. A series counts as seen only **after its last hint**,
hints and 🔀 shuffle controls, and the rack. A series counts as seen only **after its last hint**,
so leaving mid-way replays it from the start next time; it is remembered per device. Arriving at the
lobby is the lobby trigger, so a player who deep-links straight into Settings → Friends still gets the
lobby walk-through on their first trip back. Both series work the same in portrait and landscape (the
+1 -1
View File
@@ -52,7 +52,7 @@ Telegram-бот, который документы указывают как к
следующей; после последней подсказки оверлей убирается навсегда. Серий две. Серия **лобби**
указывает на вкладки ⚙️ настроек, ✏️ статистики и 🎲 новой игры. Серия **игры**, на первой партии
игрока, указывает на шапку со счётом (история ходов / чат / проверка слова), кнопки 🔄 пас-и-обмен,
🛟 подсказок и 🔀 перемешивания, и на стойку с фишками. Серия считается просмотренной только
подсказок и 🔀 перемешивания, и на стойку с фишками. Серия считается просмотренной только
**после последней подсказки**, поэтому выход на середине в следующий раз покажет её с начала;
запоминается она по устройству. Триггер серии лобби — попадание в лобби, так что игрок, пришедший
по deeplink сразу в Настройки → Друзья, всё равно получит проводку по лобби при первом возврате.
+2 -2
View File
@@ -53,7 +53,7 @@ dismisses as soon as the lobby is ready. The pure layout and timing live in `lib
A one-time **coachmark overlay** introduces the interface to a new player. Like the splash it is an
**App-level overlay**; it runs two independent series chosen by the route — **lobby** (⚙️ settings →
✏️ stats → 🎲 new game) and **game** (scoreboard header → 🔄 pass/exchange → 🛟 hints → 🔀 shuffle →
✏️ stats → 🎲 new game) and **game** (scoreboard header → 🔄 pass/exchange → hints → 🔀 shuffle →
rack). It draws **one bubble at a time** over a light scrim (`rgba(0,0,0,0.32)`); the whole layer
captures pointer events, so a **tap anywhere advances** and the UI underneath stays inert. After the
last hint the series is recorded done (`session.ts` `onboarding` key) and the overlay removes itself;
@@ -284,7 +284,7 @@ e2e and the screenshots.
opens a dialog — pick tiles to **Exchange N**, or pick
none to **Pass without exchanging**; pass is always available on your turn, exchange only
while the bag still holds a full rack, below which the tiles disable and only the pass
remains), 🛟 Hint (with a remaining-count badge, disabled at zero); 🔀 Shuffle (no label,
remains), Hint (with a remaining-count badge, disabled at zero); 🔀 Shuffle (no label,
no confirm), which
**animates** — tiles hop along a low parabola to their new slots (duration scaled by the
distance, the longest ≤ 0.3 s; off under reduce-motion) with a short haptic shake. A **thin strip
+2 -2
View File
@@ -1735,7 +1735,7 @@
idle gate while it is closed; tapping then only explains when it opens (doHint), and the lock
lifts live at the unlock moment. -->
<button class="tab" disabled={busy || !isMyTurn || !netReady} onclick={doHint}>
<span class="sq" data-coach="game-hints">🛟{#if hintGated}<span class="lock" aria-hidden="true">🔒</span>{/if}</span>
<span class="sq" data-coach="game-hints">{#if hintGated}<span class="lock" aria-hidden="true">🔒</span>{/if}</span>
<span class="lbl">{t('game.hint')}</span>
</button>
{:else}
@@ -1745,7 +1745,7 @@
disabled={busy || !isMyTurn || !netReady || hintCount <= 0}
onconfirm={doHint}
>
<span class="sq" data-coach="game-hints">🛟{#if hintCount > 0}<span class="badge">{hintCount}</span>{/if}</span>
<span class="sq" data-coach="game-hints">{#if hintCount > 0}<span class="badge">{hintCount}</span>{/if}</span>
<span class="lbl">{t('game.hint')}</span>
</TapConfirm>
{/if}
+1 -1
View File
@@ -91,7 +91,7 @@ export const en = {
'onboarding.lobbyNew': 'Practise against the AI', // 🎲
'onboarding.gameHeader': 'Move history, chat and word check', // scoreboard strip
'onboarding.gameTurn': 'Pass a turn, swap tiles', // 🔄
'onboarding.gameHints': 'Available hints', // 🛟
'onboarding.gameHints': 'Available hints', //
'onboarding.gameShuffle': 'Shuffle your tiles', // 🔀
'onboarding.gameRack': 'Pick a tile and place it on the board', // rack
+1 -1
View File
@@ -91,7 +91,7 @@ export const ru: Record<MessageKey, string> = {
'onboarding.lobbyNew': 'Потренируйтесь с ИИ', // 🎲
'onboarding.gameHeader': 'История ходов, чат и проверка слова', // шапка над доской
'onboarding.gameTurn': 'Пропуск хода, обмен фишек', // 🔄
'onboarding.gameHints': 'Доступные подсказки', // 🛟
'onboarding.gameHints': 'Доступные подсказки', //
'onboarding.gameShuffle': 'Встряхните фишки', // 🔀
'onboarding.gameRack': 'Выбирайте фишку и ставьте на доску', // rack