feat(ui): explicit offline state inside an online game (+ offline word check)
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Failing after 12s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Failing after 1s
CI / deploy (pull_request) Has been skipped
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Failing after 12s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Failing after 1s
CI / deploy (pull_request) Has been skipped
When an online game loses the connection the game screen now says so and freezes instead of silently greying out: a "connection lost" banner appears and the rack, the move controls, the add-friend/block controls and the chat/dictionary entry all disable (a started move stays a draft, committed by the player on reconnect). It is driven off the net-state machine (netState.offline), so it also covers the Telegram/VK mini-apps, where a lost connection was previously mute in-game. If the player is already in the dictionary when the drop happens, the word check falls back to the game's pinned on-device dictionary (exact when that dawg is cached; "unavailable offline" otherwise) and the network-only complaint + external look-up hide. Chat, when already open, keeps its existing read-only degrade (send/nudge disable). New pure helper localWordCheck is unit-tested; the in-game gating gets an e2e.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
shuffling = false,
|
||||
draggingId = null,
|
||||
dropIndex = null,
|
||||
frozen = false,
|
||||
confirm,
|
||||
ondown,
|
||||
}: {
|
||||
@@ -26,6 +27,10 @@
|
||||
// the drag ghost stands in) and dropIndex is the slot where a gap opens.
|
||||
draggingId?: number | null;
|
||||
dropIndex?: number | null;
|
||||
/** frozen disables tile interaction (offline in an online game): tiles cannot be picked up to
|
||||
* compose or reorder a move until the connection returns. The confirm control is gated
|
||||
* separately by the parent. */
|
||||
frozen?: boolean;
|
||||
/** The confirm-move control, rendered as the fixed 7th slot of the rack while a play is staged
|
||||
* (the parent owns the button and its enablement; the rack only positions it). */
|
||||
confirm?: Snippet;
|
||||
@@ -65,6 +70,7 @@
|
||||
class:selected={selected === slot.index}
|
||||
class:shift={dropIndex != null && i >= dropIndex}
|
||||
data-rack-index={slot.index}
|
||||
disabled={frozen}
|
||||
animate:hop={shuffling}
|
||||
onpointerdown={(e) => ondown(e, slot.index)}
|
||||
>
|
||||
@@ -114,6 +120,10 @@
|
||||
outline: 3px solid var(--accent);
|
||||
outline-offset: -3px;
|
||||
}
|
||||
/* Frozen (offline in an online game): the tray is inert until the connection returns. */
|
||||
.tile:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
/* While reordering, tiles at/after the drop slot slide right to open a gap there (one
|
||||
tile width plus the rack gap), so the drop position is visible. */
|
||||
.rack.reordering .tile {
|
||||
|
||||
Reference in New Issue
Block a user