Keep room confirmations visible until acknowledged

Show confirmed create/join guidance until local Continue without polling or ordinary game actions clearing unread text. Default shared toasts to no timeout with visible Dismiss controls.

Validation: 23 focused entry/action/seat tests, types/lint/build, and original local room creation with 43-second retention through polls and a circle change, explicit dismissal and no replay. No console errors. QA room preserved. Deployed acceptance remains open. Runtime fingerprint d57fa6a34bb1738017c2690ca5ad9f04b0b99458078a60c7ddd51e2c29483301; documentation overlay a8baa23802ac1c79321d67913c27512a199699839c1932947dfa3af95434cc37.
This commit is contained in:
Quintine committed 2026-10-18 10:27:41 +11:00
1 parent 97c2b67650
commit 999edb67e6
6 files changed
+73 -6

No files matched your search

+8
View File
@@ -4,6 +4,7 @@ import { TableTalk } from '@/components/table-talk';
import { RemovedRoomNotice } from '@/components/removed-room-notice';
import { GameTable } from '@/components/game-table';
import { SeatConfirmation, type SeatConfirmationKind } from '@/components/seat-confirmation';
import { RoomEntryConfirmation } from '@/components/room-entry-confirmation';
import { RulesetControls } from '@/components/ruleset-controls';
import {
SeatHandoverSetup,
@@ -81,6 +82,7 @@ export default function Home() {
const [code, setCode] = useState('');
const [notice, setNotice] = useState('');
const [seatConfirmation, setSeatConfirmation] = useState<SeatConfirmationKind | null>(null);
const [entryConfirmation, setEntryConfirmation] = useState<{ kind: 'create' | 'join'; code: string } | null>(null);
const seatClaimUncertain = useRef(false);
const [claimUncertain, setClaimUncertain] = useState(false);
const pendingEntry = useRef<RoomEntryAttempt | null>(null);
@@ -406,6 +408,7 @@ export default function Home() {
setNeedsReconcile(false);
setShowEntryRecovery(false);
setAbandonAcknowledged(false);
setEntryConfirmation({ kind: attempt.kind, code: data.code });
setGame(data);
window.history.replaceState(null, '', `/?room=${data.code}`);
} catch (error) {
@@ -498,6 +501,7 @@ export default function Home() {
setConnection('');
setGame(null);
setSeatConfirmation(null);
setEntryConfirmation(null);
setRemovedRoom(null);
setRestoreFailed(false);
setNotice('');
@@ -639,6 +643,7 @@ export default function Home() {
)
return;
if (claim) {
setEntryConfirmation(null);
setSeatConfirmation(confirmation ?? null);
setHandoverPending(true);
setAiPermissionPending(true);
@@ -714,6 +719,9 @@ export default function Home() {
if (game)
return (
<>
{entryConfirmation?.code === game.code && !roomUnavailable && <div className="table-shell">
<RoomEntryConfirmation {...entryConfirmation} onContinue={() => setEntryConfirmation(null)} />
</div>}
{seatConfirmation && !roomUnavailable && <div className="table-shell">
<SeatConfirmation kind={seatConfirmation} onContinue={() => setSeatConfirmation(null)} />
</div>}