diff --git a/crates/lanspread-tauri-deno-ts/src/hooks/useGameActions.ts b/crates/lanspread-tauri-deno-ts/src/hooks/useGameActions.ts index 65a369b..df167f3 100644 --- a/crates/lanspread-tauri-deno-ts/src/hooks/useGameActions.ts +++ b/crates/lanspread-tauri-deno-ts/src/hooks/useGameActions.ts @@ -12,9 +12,9 @@ export interface GameActions { /** * Thin wrappers over the backend `run_game` / `install_game` / `update_game` - * / `uninstall_game` commands. For install + update we mark the game as - * "checking peers" up-front through the games hook so the UI doesn't have to - * wait for the first backend event. + * / `uninstall_game` commands. We mark peer-backed downloads as "checking + * peers" and already-downloaded installs as "installing" up-front so the UI + * doesn't have to wait for the first backend event. */ export const useGameActions = (games: UseGamesResult): GameActions => { const play = useCallback(async (id: string) => { @@ -28,7 +28,14 @@ export const useGameActions = (games: UseGamesResult): GameActions => { const install = useCallback(async (id: string) => { try { const success = await invoke('install_game', { id }); - if (success) games.markChecking(id); + if (!success) return; + + const game = games.games.find(item => item.id === id); + if (game?.downloaded && !game.installed) { + games.markInstalling(id); + } else { + games.markChecking(id); + } } catch (err) { console.error('install_game failed:', err); } diff --git a/crates/lanspread-tauri-deno-ts/src/hooks/useGames.ts b/crates/lanspread-tauri-deno-ts/src/hooks/useGames.ts index 7b3b735..e01d9c9 100644 --- a/crates/lanspread-tauri-deno-ts/src/hooks/useGames.ts +++ b/crates/lanspread-tauri-deno-ts/src/hooks/useGames.ts @@ -52,6 +52,7 @@ export interface UseGamesResult { totalPeerCount: number; requestGames: () => Promise; markChecking: (id: string) => void; + markInstalling: (id: string) => void; cancelChecking: (id: string) => void; } @@ -95,6 +96,15 @@ export const useGames = (rescanGameDir: () => void): UseGamesResult => { }, CHECKING_PEERS_TIMEOUT_MS); }, [cancelChecking]); + const markInstalling = useCallback((id: string) => { + cancelChecking(id); + setGames(prev => prev.map(item => + item.id === id + ? applyPatch(item, { install_status: InstallStatus.Installing, clearStatus: true }) + : item, + )); + }, [cancelChecking]); + const requestGames = useCallback(async () => { try { await invoke('request_games'); @@ -247,6 +257,7 @@ export const useGames = (rescanGameDir: () => void): UseGamesResult => { totalPeerCount, requestGames, markChecking, + markInstalling, cancelChecking, }; };