extremely claude-assisted go game based on atproto! working on cleaning up and giving a more unique design, still has a bit of a slop vibe to it.

Fix server/client filtering mismatch

- Server now returns pre-filtered activeGames, waitingGames, completedGames
- Removed double filtering (server filtered, then client re-filtered)
- Client now uses server's pre-filtered arrays directly
- Keeps player_two inference from moves for backward compatibility

This fixes games showing in wrong sections due to filtering mismatch.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

+22 -23
.syncthing.bun.lock.tmp

This is a binary file and will not be displayed.

+18 -7
src/routes/+page.server.ts
··· 1 1 import type { PageServerLoad } from './$types'; 2 2 import { getSession } from '$lib/server/auth'; 3 + import { getDb } from '$lib/server/db'; 3 4 import { gameTitle } from '$lib/game-titles'; 4 5 5 6 interface UfosRecord { ··· 33 34 34 35 if (!gamesResponse.ok) { 35 36 console.error('[Homepage] Failed to fetch games from UFOs:', gamesResponse.status); 36 - return { session: session ? { did: session.did } : null, games: [] }; 37 + return { session: session ? { did: session.did } : null, activeGames: [], waitingGames: [], completedGames: [] }; 37 38 } 38 39 39 40 const gamesData: UfosResponse = await gamesResponse.json(); 40 41 41 42 if (!Array.isArray(gamesData)) { 42 43 console.error('[Homepage] UFOs games response is not an array'); 43 - return { session: session ? { did: session.did } : null, games: [] }; 44 + return { session: session ? { did: session.did } : null, activeGames: [], waitingGames: [], completedGames: [] }; 44 45 } 45 46 46 47 // Fetch backlinks from Constellation for each game to count moves and detect activity ··· 271 272 .sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()) 272 273 .slice(0, 10); 273 274 274 - // Combine all games 275 - const games = [...activeGames, ...waitingGames, ...completedGames]; 275 + // Add titles to each category 276 + const activeGamesWithTitles = activeGames.map((game) => ({ 277 + ...game, 278 + title: gameTitle(game.rkey), 279 + })); 276 280 277 - const gamesWithTitles = games.map((game) => ({ 281 + const waitingGamesWithTitles = waitingGames.map((game) => ({ 282 + ...game, 283 + title: gameTitle(game.rkey), 284 + })); 285 + 286 + const completedGamesWithTitles = completedGames.map((game) => ({ 278 287 ...game, 279 288 title: gameTitle(game.rkey), 280 289 })); 281 290 282 291 return { 283 292 session: session ? { did: session.did } : null, 284 - games: gamesWithTitles, 293 + activeGames: activeGamesWithTitles, 294 + waitingGames: waitingGamesWithTitles, 295 + completedGames: completedGamesWithTitles, 285 296 }; 286 297 } catch (err) { 287 298 console.error('Failed to load games from UFOs:', err); 288 - return { session: session ? { did: session.did } : null, games: [] }; 299 + return { session: session ? { did: session.did } : null, activeGames: [], waitingGames: [], completedGames: [] }; 289 300 } 290 301 };
+4 -16
src/routes/+page.svelte
··· 110 110 } 111 111 }); 112 112 113 - // Split games by status 114 - // TODO: Change to 'status === active' once migration to on-protocol is complete 115 - // Currently showing all non-completed games since many active games lack complete atproto data 113 + // Use pre-filtered games from server (already sorted and limited) 116 114 const currentGames = $derived( 117 - (data.games || []) 118 - .filter((g) => g.status !== 'completed') 115 + (data.activeGames || []) 119 116 .filter((g) => !showMyGamesOnly || isMyGame(g)) 120 117 .filter((g) => !showMyTurnOnly || isMyTurn(g)) 121 - .sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()) 122 118 ); 123 119 124 - const waitingGames = $derived( 125 - (data.games || []) 126 - .filter((g) => g.status === 'waiting') 127 - .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()) 128 - ); 120 + const waitingGames = $derived(data.waitingGames || []); 129 121 130 - const archivedGames = $derived( 131 - (data.games || []) 132 - .filter((g) => g.status === 'completed') 133 - .sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()) 134 - ); 122 + const archivedGames = $derived(data.completedGames || []); 135 123 136 124 const activeTotalPages = $derived(Math.ceil(currentGames.length / ACTIVE_PAGE_SIZE)); 137 125