Keep popup instructions readable until continued

Show concise progress during first room create/join; reserve persistent recovery instructions for saved/uncertain attempts. Retain completed-action text until a local Continue button, without gating rules or AI. Preserve unread text across backgrounding, bounded summaries, mute and private-safe feedback. Fix the container QA helper path-import collision.

Verified: typecheck, lint, 5200 offline tests, 52 HTTP tests and production build. Delayed/lost-response browser checks prove progress, refresh recovery and exact retry without duplicates. Notice stayed for over 47 seconds while the QA game progressed; Continue advances only presentation. Mobile 16px/44px controls verified. Existing games preserved. Container/deployed acceptance follows publication.
This commit is contained in:
Quintine committed 2026-09-22 09:51:55 +10:00
1 parent c2d392e155
commit f29d05620c
10 files changed
+238 -115

No files matched your search

+17
View File
@@ -80,6 +80,7 @@ export default function Home() {
null,
);
const [entryProblem, setEntryProblem] = useState('');
const [initialEntryPending, setInitialEntryPending] = useState(false);
const [showEntryRecovery, setShowEntryRecovery] = useState(false);
const [showHandover, setShowHandover] = useState(false);
const [handoverPending, setHandoverPending] = useState(true);
@@ -407,6 +408,7 @@ export default function Home() {
);
}
} finally {
if (firstDispatch) setInitialEntryPending(false);
mutationPending.current = false;
setBusy(false);
}
@@ -443,6 +445,7 @@ export default function Home() {
return;
}
pendingEntry.current = attempt;
setInitialEntryPending(true);
setEntryAttempt(attempt);
setAbandonAcknowledged(false);
await dispatchEntry(attempt, true);
@@ -808,6 +811,20 @@ export default function Home() {
</section>
</main>
);
// A first request is progress, not recovery. Keep the actionable recovery
// instructions on screen only after uncertainty or a saved-request restore.
if (initialEntryPending && entryAttempt)
return (
<main className="table-shell" aria-busy="true">
<header className="masthead">
<div className="wordmark">DUNE<span>ARRAKIS TABLE</span></div>
</header>
<section className="notice">
<h1>{entryAttempt.kind === 'create' ? 'Creating your room…' : 'Joining the room…'}</h1>
<output aria-live="polite">Please wait.</output>
</section>
</main>
);
if (entryAttempt || entryProblem)
return (
<main className="table-shell" aria-busy={busy}>