mirror of
https://github.com/tiennm99/noitu.git
synced 2026-10-11 03:13:45 +00:00
feat(web): take the quick-match wait's seconds out of the live region
The waiting panel's whole role="status" region re-announced itself every second because the seconds counter lived inside it; the counter now sits outside the live text, which only changes (and is only spoken) once. The nudge that offers a bot game while waiting now says it leaves the queue, and its link keeps the difficulty last picked rather than resetting to the ladder's default. The two ways into an online game get sub-labels saying what each actually starts.
This commit is contained in:
1 parent
a95938d611
commit
2a7a2a7d53
1 file changed
+66
-24
@@ -54,6 +54,12 @@
|
||||
*/
|
||||
const QUICK_MATCH_NUDGE_S = 20;
|
||||
|
||||
// The rung last played, if this browser has one, so the nudge's bot game
|
||||
// resumes it rather than opening back on the ladder's own default.
|
||||
const quickMatchNudgeHref = $derived(
|
||||
settings.state.lastDifficulty != null ? `/play?difficulty=${settings.state.lastDifficulty}` : '/play'
|
||||
);
|
||||
|
||||
/**
|
||||
* How long a held request waits before the screen stops saying "connecting"
|
||||
* and starts saying something the player can act on. The backoff is capped
|
||||
@@ -539,14 +545,18 @@
|
||||
{#if game.state.queued}
|
||||
<!-- The wait itself. Ends on its own — RoomState replaces this whole
|
||||
branch the moment a match is found — so the only button here is
|
||||
the way out. -->
|
||||
<div class="waiting" role="status">
|
||||
<p>{fill(t.quickMatchWaiting, { n: session.state.queuedForS })}</p>
|
||||
the way out. The running seconds sit outside the live region:
|
||||
inside it, a screen reader announced "n giây" on every tick. -->
|
||||
<div class="waiting">
|
||||
<p role="status" aria-live="polite">{t.quickMatchWaiting}</p>
|
||||
<p class="counter" aria-hidden="true">
|
||||
{fill(t.secondsLeft, { n: session.state.queuedForS })}
|
||||
</p>
|
||||
<button type="button" onclick={cancelQueue}>{t.quickMatchCancel}</button>
|
||||
{#if session.state.queuedForS >= QUICK_MATCH_NUDGE_S}
|
||||
<p class="hint">
|
||||
{t.quickMatchNudge}
|
||||
<a href="/play">{t.quickMatchNudgeLink}</a>
|
||||
<a href={quickMatchNudgeHref}>{t.quickMatchNudgeLink}</a>
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -555,18 +565,24 @@
|
||||
send a real CreateRoom, and the fifth one came back as "you are
|
||||
creating rooms too quickly" to a player who thought they had tapped
|
||||
nothing at all. -->
|
||||
<button
|
||||
type="button"
|
||||
class="primary"
|
||||
disabled={!!session.state.pending}
|
||||
onclick={playQuickMatch}
|
||||
>
|
||||
{session.state.pending?.kind === 'quickMatch' ? t.connecting : t.quickMatch}
|
||||
</button>
|
||||
<div class="choice">
|
||||
<button
|
||||
type="button"
|
||||
class="primary"
|
||||
disabled={!!session.state.pending}
|
||||
onclick={playQuickMatch}
|
||||
>
|
||||
{session.state.pending?.kind === 'quickMatch' ? t.connecting : t.quickMatch}
|
||||
</button>
|
||||
<p class="choice-hint">{t.quickMatchHint}</p>
|
||||
</div>
|
||||
|
||||
<button type="button" class="primary" disabled={!!session.state.pending} onclick={create}>
|
||||
{session.state.pending?.kind === 'create' ? t.connecting : t.createRoom}
|
||||
</button>
|
||||
<div class="choice">
|
||||
<button type="button" class="primary" disabled={!!session.state.pending} onclick={create}>
|
||||
{session.state.pending?.kind === 'create' ? t.connecting : t.createRoom}
|
||||
</button>
|
||||
<p class="choice-hint">{t.createRoomHint}</p>
|
||||
</div>
|
||||
|
||||
<form
|
||||
class="join"
|
||||
@@ -695,14 +711,35 @@
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.choice {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.choice-hint {
|
||||
margin: 0;
|
||||
color: var(--text-muted);
|
||||
font-size: var(--text-1);
|
||||
}
|
||||
|
||||
.primary {
|
||||
min-height: 44px;
|
||||
padding: 14px;
|
||||
padding: var(--space-4);
|
||||
border: 0;
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--accent);
|
||||
color: var(--accent-text);
|
||||
font-weight: 600;
|
||||
transition: background-color 150ms ease-out;
|
||||
}
|
||||
|
||||
.primary:hover:not(:disabled) {
|
||||
background: var(--accent-hover);
|
||||
}
|
||||
|
||||
.primary:active:not(:disabled) {
|
||||
background: var(--accent-pressed);
|
||||
}
|
||||
|
||||
.primary:disabled {
|
||||
@@ -713,7 +750,7 @@
|
||||
.join {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.waiting {
|
||||
@@ -731,6 +768,11 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.waiting .counter {
|
||||
color: var(--text-muted);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.waiting button {
|
||||
min-height: 44px;
|
||||
padding: var(--space-3) var(--space-4);
|
||||
@@ -742,7 +784,7 @@
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-size: var(--text-5);
|
||||
font-size: var(--text-2);
|
||||
}
|
||||
|
||||
.row {
|
||||
@@ -753,11 +795,11 @@
|
||||
input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: var(--space-3) 14px;
|
||||
padding: var(--space-3) var(--space-4);
|
||||
border: 1px solid var(--border-strong);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--surface);
|
||||
font-size: var(--text-6);
|
||||
font-size: var(--text-3);
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -778,7 +820,7 @@
|
||||
.hint {
|
||||
margin: 0;
|
||||
color: var(--text-muted);
|
||||
font-size: var(--text-3);
|
||||
font-size: var(--text-2);
|
||||
}
|
||||
|
||||
.hint.invalid {
|
||||
@@ -788,9 +830,9 @@
|
||||
.error,
|
||||
.notice {
|
||||
margin: 0;
|
||||
padding: 10px var(--space-3);
|
||||
padding: var(--space-3) var(--space-3);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: var(--text-5);
|
||||
font-size: var(--text-2);
|
||||
}
|
||||
|
||||
.error {
|
||||
@@ -806,6 +848,6 @@
|
||||
.back {
|
||||
align-self: flex-start;
|
||||
color: var(--text-muted);
|
||||
font-size: var(--text-5);
|
||||
font-size: var(--text-2);
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user