feat: sparser robot nudges, typed unread badge, lobby unread bump
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 53s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m26s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 53s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m26s
Three owner-requested polish changes: - robot: replace the lengthening 60-90 min -> 6 h proactive-nudge ramp with a flat uniform 9-12 h wait before every nudge; the existing sleep-window gate still skips and defers a nudge that would land in the robot's night. - ui: colour the lobby/in-game unread dot by type -- the regular danger colour when a chat message is unread, a softer amber (--warn) when only nudges are. Adds a per-viewer unread_messages flag (chat_messages.kind='message') across the backend DTO, FlatBuffers wire, gateway transcode and the UI store. - ui: float games with any unread notification to the top of the lobby's your-turn and opponent-turn sections (finished keeps its order), reusing the existing unread_chat flag. Docs (ARCHITECTURE 7, FUNCTIONAL + _ru) updated. No DB migration; the new wire field is backward-compatible.
This commit is contained in:
+10
-4
@@ -14,6 +14,7 @@
|
||||
import { t, type MessageKey } from '../lib/i18n/index.svelte';
|
||||
import type { EvalResult, MoveRecord, MoveResult, StateView, Tile } from '../lib/model';
|
||||
import { lastMoveCells, replay } from '../lib/board';
|
||||
import { badgeKind } from '../lib/unread';
|
||||
import { historyGrid } from '../lib/history';
|
||||
import { centre, premiumGrid } from '../lib/premiums';
|
||||
import { variantNameKey } from '../lib/variants';
|
||||
@@ -183,7 +184,7 @@
|
||||
view = st;
|
||||
syncWallet(st.walletBalance);
|
||||
// Seed the unread flag from the authoritative state (the live stream only raises it).
|
||||
seedChatUnread(id, st.game.unreadChat);
|
||||
seedChatUnread(id, st.game.unreadChat, st.game.unreadMessages);
|
||||
moves = hist.moves;
|
||||
setCachedGame(id, st, hist.moves, draft);
|
||||
// Mirror the fresh status into the lobby snapshot so returning there shows it without a
|
||||
@@ -670,7 +671,7 @@
|
||||
};
|
||||
// The move result is an authoritative per-viewer view: a nudge the actor just answered by
|
||||
// moving is already cleared server-side, so reconcile the unread flag from it.
|
||||
seedChatUnread(id, r.game.unreadChat);
|
||||
seedChatUnread(id, r.game.unreadChat, r.game.unreadMessages);
|
||||
moves = [...moves, r.move];
|
||||
// A committed move clears the actor's draft on the server, so clear the cached draft too;
|
||||
// otherwise a same-session re-entry would briefly re-apply the now-stale composition.
|
||||
@@ -1091,10 +1092,11 @@
|
||||
above so the markup and logic stay single-sourced (see the {#if landscape} split). -->
|
||||
{#snippet scoreboardBlock()}
|
||||
{#if view}
|
||||
{@const badge = badgeKind(app.chatUnread[id] ?? false, app.messageUnread[id] ?? false)}
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div class="scoreboard" class:flat={landscape} onclick={landscape ? undefined : toggleHistory}>
|
||||
{#if app.chatUnread[id]}<span class="unread-dot sbadge-dot"></span>{/if}
|
||||
{#if badge}<span class="unread-dot sbadge-dot" class:nudge={badge === 'nudge'}></span>{/if}
|
||||
{#each view.game.seats as s (s.seat)}
|
||||
<div class="seat" class:turn={view.game.toMove === s.seat && !gameOver} class:win={s.isWinner}>
|
||||
<div class="nm" class:struck={seatBlocked(s)}>{seatName(s)}</div>
|
||||
@@ -1582,13 +1584,17 @@
|
||||
color: var(--danger);
|
||||
}
|
||||
/* The unread-chat dot on the score bar's corner; the history's 💬 icon fade-blinks (two cycles)
|
||||
when the history is opened with unread present, rather than carrying a count badge. */
|
||||
when the history is opened with unread present, rather than carrying a count badge. Red for an
|
||||
unread message, a softer amber when only nudges are unread. */
|
||||
.unread-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--danger);
|
||||
}
|
||||
.unread-dot.nudge {
|
||||
background: var(--warn);
|
||||
}
|
||||
.sbadge-dot {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
|
||||
Reference in New Issue
Block a user