fix(game): clear nudges on game completion
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Has been skipped
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m19s
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Has been skipped
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m19s
Nudge badges lingered in the lobby on games that ended by turn-timeout, resignation or forfeit: those paths commit the finish directly, bypassing the move path's per-mover NudgeClearer, so the awaited seat's nudge was never marked read. A finished game's nudges are stale, so clear them all. Add a wired NudgeExpirer (social.ExpireNudges) called from the shared commit finish block — covering every completion path — and from the voidGame recovery path. It clears every seat's nudge bits for the game and leaves chat messages unread; unlike ClearNudges it records no publish-to-read latency, since a completion is an expiry, not a read. An integration test reproduces the timeout case (nudge cleared, chat kept). Docs: ARCHITECTURE §9.1, FUNCTIONAL (+_ru), backend/README.
This commit is contained in:
@@ -646,7 +646,11 @@ in either direction (the enqueue excludes the caller's `BlockedWith` set);
|
||||
robot instead clears when the robot answers by moving, as for a human. A seat's bit clears when that player **opens the move history or the chat**
|
||||
(`POST /games/:id/chat/read`, which the client sends only when it holds unread, so a
|
||||
history open is not a constant backend call), and a **nudge additionally clears when its
|
||||
recipient answers by moving** (the move path calls a wired `NudgeClearer`). The mask is
|
||||
recipient answers by moving** (the move path calls a wired `NudgeClearer`); and **every nudge in
|
||||
a game is marked read when that game finishes** — on any completion path (a closing move, a
|
||||
resignation, a forfeit or a turn-timeout, all funnelling through the shared `commit`), since the
|
||||
nudge badge is stale once the game is over (a wired `NudgeExpirer`; chat messages stay unread and
|
||||
this expiry records no read latency). The mask is
|
||||
inverted so "anything unread" is a plain `unread_seats <> 0`, which the per-viewer
|
||||
`unread_chat` game-view flag (seeding the lobby and in-game unread **dot**), the admin
|
||||
unread filter and the unread gauge all use. A second per-viewer flag, **`unread_messages`**
|
||||
@@ -656,8 +660,9 @@ in either direction (the enqueue excludes the caller's `BlockedWith` set);
|
||||
REST-seed-then-event-bump lifecycle (the live-event game-view leaves them false; a nudge
|
||||
event raises only `unread_chat`, a message event raises both). The lobby additionally
|
||||
**floats games with any unread entry to the top** of the your-turn and opponent-turn
|
||||
sections (the finished section keeps its activity order). On each clear the publish-to-read
|
||||
latency is recorded; the read time itself is not retained.
|
||||
sections (the finished section keeps its activity order). On each player-driven clear the
|
||||
publish-to-read latency is recorded — the completion expiry records none (it is not a read);
|
||||
the read time itself is not retained.
|
||||
- **Profile**: `preferred_language` (en/ru; tracks the interface language — §4), display name, email
|
||||
(confirm-code binding, see §4), **timezone**, the daily **away window**, the
|
||||
**variant preferences** (`variant_preferences`, the matchable-variant set that gates New
|
||||
|
||||
+2
-1
@@ -260,7 +260,8 @@ entry — a message **or a nudge** from an opponent — raises a small **dot** n
|
||||
in the **lobby** and on the game's **score bar**, **red when an unread message is waiting and a
|
||||
softer amber when only nudges are**. Opening the **move history** counts as reading
|
||||
the chat, even without entering it: the dot clears and the 💬 icon **fade-blinks twice**. A nudge
|
||||
also clears the moment its recipient **takes their move**.
|
||||
also clears the moment its recipient **takes their move**, and **all of a game's nudges clear once
|
||||
the game finishes** (the badge is stale once the game is over) — but unread chat messages stay unread.
|
||||
|
||||
### Profile & settings
|
||||
Edit the display name (letters joined by a single space / "." / "_" separator, with an
|
||||
|
||||
@@ -269,7 +269,8 @@ _Вход сейчас только через провайдера, поэто
|
||||
**лобби** и на **строке счёта** партии, **красную при непрочитанном сообщении и мягкую жёлтую,
|
||||
когда непрочитаны только nudge'и**. Открытие **истории ходов** считается прочтением чата, даже
|
||||
без захода в него: точка гаснет, а значок 💬 **дважды мигает**. Nudge также гаснет в момент, когда
|
||||
его получатель **делает ход**.
|
||||
его получатель **делает ход**, и **все nudge'и партии гаснут по её завершении** (после конца
|
||||
партии бейдж неактуален) — но непрочитанные сообщения чата остаются непрочитанными.
|
||||
|
||||
### Профиль и настройки
|
||||
Редактирование отображаемого имени (буквы, разделённые одиночным пробелом / «.» /
|
||||
|
||||
Reference in New Issue
Block a user