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:
parent
16a44d3fc5
commit
71e9f3e9e0
1 changed files with 16 additions and 10 deletions
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue