1
0
Fork 0

fix(poker): keep the lobby list stable across background polls

Background polls no longer flip the lobby into its scanning state, so the empty window and table rows stop blinking every three seconds; the refresh spinner is reserved for manual refreshes and the error line only clears on a successful load.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Jason Fraley 2026-09-11 17:07:37 -04:00
parent 16a44d3fc5
commit 71e9f3e9e0

View file

@ -49,8 +49,8 @@ function createdLabel(createdAt: string): string {
}
export function PokerLobby({ refreshKey, onOpenTable, isSuperuser = false }: PokerLobbyProps) {
const [tables, setTables] = useState<readonly PokerTableSummary[]>([]);
const [loading, setLoading] = useState(true);
const [tables, setTables] = useState<readonly PokerTableSummary[] | null>(null);
const [refreshing, setRefreshing] = useState(false);
const [pendingTable, setPendingTable] = useState<string | null>(null);
const [forceEndingTable, setForceEndingTable] = useState<string | null>(null);
const [creating, setCreating] = useState(false);
@ -58,22 +58,28 @@ export function PokerLobby({ refreshKey, onOpenTable, isSuperuser = false }: Pok
const [error, setError] = useState<string | null>(null);
const loadTables = useCallback(async () => {
setLoading(true);
setError(null);
try {
const result = await listPokerTables();
if (!result.success) {
setError(result.error ?? "Could not load poker tables.");
return;
}
setError(null);
setTables(result.data ?? []);
} catch (caught) {
setError(caught instanceof Error ? caught.message : "Could not load poker tables.");
} finally {
setLoading(false);
}
}, []);
const manualRefresh = useCallback(async () => {
setRefreshing(true);
try {
await loadTables();
} finally {
setRefreshing(false);
}
}, [loadTables]);
useEffect(() => {
void loadTables();
}, [loadTables, refreshKey]);
@ -172,12 +178,12 @@ export function PokerLobby({ refreshKey, onOpenTable, isSuperuser = false }: Pok
type="button"
variant="outline"
size="icon"
onClick={() => void loadTables()}
disabled={loading}
onClick={() => void manualRefresh()}
disabled={refreshing}
aria-label="Refresh poker tables"
title="Refresh tables"
>
<RefreshCw className={cn(loading && "animate-spin motion-reduce:animate-none")} />
<RefreshCw className={cn(refreshing && "animate-spin motion-reduce:animate-none")} />
</Button>
<Button type="button" onClick={() => void create()} disabled={creating}>
{creating ? (
@ -193,7 +199,7 @@ export function PokerLobby({ refreshKey, onOpenTable, isSuperuser = false }: Pok
{error && (
<p className="border-b border-border px-4 py-3 text-sm text-destructive">{error}</p>
)}
{loading && tables.length === 0 ? (
{tables === null ? (
<p className="px-4 py-8 text-center text-sm text-muted-foreground">
Scanning for open tables...
</p>