Live location tracking and playback for the game "manhunt"
at ben/frontend 97 lines 3.5 kB view raw
1import React from "react"; 2import { commands } from "@/bindings"; 3import { sharedSwrConfig, useTauriEvent } from "@/lib/hooks"; 4import useSWR from "swr"; 5 6export default function GameScreen() { 7 const { data: profiles } = useSWR("game-get-profiles", commands.getProfiles); 8 9 const { data: gameState, mutate } = useSWR( 10 "fetch-game-state", 11 commands.getGameState, 12 sharedSwrConfig 13 ); 14 15 useTauriEvent("gameStateUpdate", () => { 16 mutate(); 17 }); 18 19 const isSeeker = gameState.caught_state[gameState.my_id]; 20 21 const markCaught = async () => { 22 if (!isSeeker) { 23 await commands.markCaught(); 24 } 25 }; 26 27 const grabPowerup = async () => { 28 if (gameState.available_powerup !== null) { 29 await commands.grabPowerup(); 30 } 31 }; 32 33 const activatePowerup = async () => { 34 if (gameState.held_powerup !== null && gameState.held_powerup !== "PingSeeker") { 35 await commands.activatePowerup(); 36 } 37 }; 38 39 const quitToMenu = async () => { 40 await commands.quitToMenu(); 41 }; 42 43 if (gameState.game_ended) { 44 return <h2>Game Over! Syncing histories...</h2>; 45 } else if (isSeeker && gameState.seekers_started === null) { 46 return <h2>Waiting for hiders to hide...</h2>; 47 } else { 48 return ( 49 <> 50 <h2>Hiders Left</h2> 51 {Object.keys(gameState.caught_state) 52 .filter((k) => !gameState.caught_state[k]) 53 .map((key) => ( 54 <li key={key}>{profiles?.[key]?.display_name ?? key}</li> 55 ))} 56 {!isSeeker && <button onClick={markCaught}>I got caught!</button>} 57 <h2>Pings</h2> 58 {gameState.last_global_ping !== null ? ( 59 <> 60 <p>Last Ping: {gameState.last_global_ping}</p> 61 {Object.entries(gameState.pings) 62 .filter(([key, v]) => key && v !== undefined) 63 .map(([k, v]) => ( 64 <li key={k}> 65 {profiles?.[v!.display_player]?.display_name ?? 66 v!.display_player} 67 : {v && JSON.stringify(v.loc)} 68 </li> 69 ))} 70 </> 71 ) : ( 72 <small>Pings haven&apos;t started yet</small> 73 )} 74 <h2>Powerups</h2> 75 {gameState.last_powerup_spawn === null && ( 76 <small>Powerups haven&apos;t started yet</small> 77 )} 78 {gameState.available_powerup && ( 79 <p> 80 Powerup Available: {JSON.stringify(gameState.available_powerup)}{" "} 81 <button onClick={grabPowerup}>Grab!</button> 82 </p> 83 )} 84 {gameState.held_powerup && ( 85 <p> 86 Held Powerup: {gameState.held_powerup} 87 {(gameState.held_powerup === "PingSeeker" && ( 88 <small>(Will be used next ping)</small> 89 )) || <button onClick={activatePowerup}>Use</button>} 90 </p> 91 )} 92 <h2>Quit</h2> 93 <button onClick={quitToMenu}>Quit To Menu</button> 94 </> 95 ); 96 } 97}