fix(chat): no chat field or nudge on a finished game
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 59s
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 59s
A finished game is read-only: gate the nudge behind canNudge (active game, opponent's turn) so it no longer shows on a finished (or otherwise non-active) game — where the backend rejects it anyway. The message field is already hidden off your own turn. Extend the finished-game e2e to assert neither Send nor Nudge is offered.
This commit is contained in:
@@ -116,6 +116,9 @@ test('finished game draws an inert footer and trims live-only controls', async (
|
||||
await page.getByRole('button', { name: 'Chat' }).click(); // 💬
|
||||
await expect(page.locator('.pane')).toHaveCount(1);
|
||||
await expect(page.getByRole('button', { name: 'Dictionary' })).toHaveCount(0);
|
||||
// A finished game is read-only: neither the message field nor the nudge is offered.
|
||||
await expect(page.getByRole('button', { name: 'Send' })).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: 'Nudge' })).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('lobby: hiding a finished game removes it (kebab → ❌), keeping the others', async ({ page }) => {
|
||||
|
||||
+10
-7
@@ -9,6 +9,7 @@
|
||||
busy,
|
||||
myTurn = false,
|
||||
canSend = false,
|
||||
canNudge = false,
|
||||
waiting = false,
|
||||
nudgeOnCooldown = false,
|
||||
onsend,
|
||||
@@ -17,16 +18,18 @@
|
||||
messages: ChatMessage[];
|
||||
myId: string;
|
||||
busy: boolean;
|
||||
// The input area has three turn-driven states: on your own turn the message field +
|
||||
// send show while you may still post (canSend); once the one allowed message is sent a
|
||||
// short caption replaces them until the next turn; on the opponent's turn only the
|
||||
// nudge button shows (nudging your own turn makes no sense — there is no one to hurry).
|
||||
// While the hourly nudge cooldown is active the nudge is disabled with an "awaiting
|
||||
// reply" caption.
|
||||
// The input area is turn-driven, in priority order: while you may still post (canSend)
|
||||
// the message field + send show; once your one allowed message is sent a short caption
|
||||
// replaces them until the next turn (myTurn); on the opponent's turn of an active game
|
||||
// the nudge button shows (canNudge) — disabled with an "awaiting reply" caption while the
|
||||
// hourly cooldown is active; a finished game offers nothing (it is read-only).
|
||||
myTurn?: boolean;
|
||||
// canSend is true while the player may still post this turn (own turn and the per-turn
|
||||
// limit not yet reached); it gates the message field.
|
||||
canSend?: boolean;
|
||||
// canNudge is true on the opponent's turn of an active game; it gates the nudge button
|
||||
// (nudging your own turn or a finished game makes no sense).
|
||||
canNudge?: boolean;
|
||||
// waiting is true while an auto-match game still has no opponent: both send and nudge
|
||||
// are disabled (there is no one to message or hurry yet).
|
||||
waiting?: boolean;
|
||||
@@ -71,7 +74,7 @@
|
||||
<!-- Own turn, the one allowed message already sent: a caption holds the row until the
|
||||
next turn (no nudge — there is no one to hurry on your own turn). -->
|
||||
<span class="cooldown">{t('chat.sentThisTurn')}</span>
|
||||
{:else}
|
||||
{:else if canNudge}
|
||||
<!-- A flex:1 caption keeps the nudge pinned right whether or not the cooldown text shows. -->
|
||||
<span class="cooldown">{nudgeOnCooldown ? t('chat.awaitingReply') : ''}</span>
|
||||
<button class="iconbtn" onclick={onnudge} disabled={busy || waiting || nudgeOnCooldown || !connection.online} aria-label={t('chat.nudgeAction')}>🛎️</button>
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
// the turn advances. canSend hides the field once the limit is reached (and always on
|
||||
// the opponent's turn).
|
||||
const canSend = $derived(canSendChat(isMyTurn, view ? sentThisTurn(messages, myId, view.game.lastActivityUnix) : 0));
|
||||
// The nudge is offered only on the opponent's turn of an active game (you hurry the player
|
||||
// who is to move). A finished game is read-only: neither chat nor nudge is offered.
|
||||
const canNudge = $derived(!!view && view.game.status === 'active' && view.game.toMove !== view.seat);
|
||||
// While the auto-match game still has no opponent, chat and nudge are both disabled.
|
||||
const waiting = $derived(!!view && view.game.status === 'open');
|
||||
const nudgeCooldownSecs = 3600;
|
||||
@@ -110,4 +113,4 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Chat {messages} {myId} {busy} myTurn={isMyTurn} {canSend} {waiting} {nudgeOnCooldown} onsend={sendChat} onnudge={nudge} />
|
||||
<Chat {messages} {myId} {busy} myTurn={isMyTurn} {canSend} {canNudge} {waiting} {nudgeOnCooldown} onsend={sendChat} onnudge={nudge} />
|
||||
|
||||
Reference in New Issue
Block a user