Prechádzať zdrojové kódy

Splitting up the useGameInfo hook

Kirk Trombley 5 rokov pred
rodič
commit
868003b265

+ 5 - 3
client/src/components/screens/Lobby/Lobby.jsx

@@ -6,7 +6,7 @@ import ClickToCopy from "../../util/ClickToCopy";
 import { useGameId } from "../../../domain/gameStore";
 import { useGameId } from "../../../domain/gameStore";
 import JoinForm from "./JoinForm";
 import JoinForm from "./JoinForm";
 import StartGame from "./StartGame";
 import StartGame from "./StartGame";
-import useGameInfo from "../../../hooks/useGameInfo";
+import { useGameConfig, usePlayers } from "../../../hooks/useGameInfo";
 import Loading from "../../util/Loading";
 import Loading from "../../util/Loading";
 
 
 const InfoContainer = styled.div`
 const InfoContainer = styled.div`
@@ -50,7 +50,8 @@ const getUrl = gameId => {
 
 
 const Lobby = ({ onStart }) => {
 const Lobby = ({ onStart }) => {
   const gameId = useGameId();
   const gameId = useGameId();
-  const { players, rounds, timer } = useGameInfo();
+  const players = usePlayers();
+  const { rounds, timer, onlyAmerica } = useGameConfig();
   const [joined, setJoined] = useState(false);
   const [joined, setJoined] = useState(false);
 
 
   if (!players || !rounds || !timer) {
   if (!players || !rounds || !timer) {
@@ -60,7 +61,8 @@ const Lobby = ({ onStart }) => {
   return (
   return (
     <PageContainer>
     <PageContainer>
       <InfoContainer>
       <InfoContainer>
-        <Label>Game will run for {rounds} rounds, each with a {ms(timer * 1000)} time limit</Label>
+        <Label>Game will run for {rounds} round{rounds !== 1 && "s, each"} with a {ms(timer * 1000)} time limit</Label>
+        {onlyAmerica && <Label>This game will only use locations within the United States of America</Label>}
         <FormContainer>
         <FormContainer>
           {
           {
             joined
             joined

+ 7 - 3
client/src/components/screens/PlayerScores/PlayerScores.jsx

@@ -1,11 +1,12 @@
 import React from 'react';
 import React from 'react';
 import styled from "styled-components";
 import styled from "styled-components";
 import Loading from '../../util/Loading';
 import Loading from '../../util/Loading';
-import useGameInfo from '../../../hooks/useGameInfo';
+import { useGameCoords, usePlayers, useLinkedGame } from '../../../hooks/useGameInfo';
 import ClickToCopy from '../../util/ClickToCopy';
 import ClickToCopy from '../../util/ClickToCopy';
 import SummaryMap from './SummaryMap';
 import SummaryMap from './SummaryMap';
 import LinkedGame from './LinkedGame';
 import LinkedGame from './LinkedGame';
 import ScoreBoard from './ScoreBoard';
 import ScoreBoard from './ScoreBoard';
+import { useGameId } from '../../../domain/gameStore';
 
 
 const Container = styled.div`
 const Container = styled.div`
   display: flex;
   display: flex;
@@ -22,13 +23,16 @@ const Label = styled.span`
 
 
 export default () => {
 export default () => {
   // poll the game state
   // poll the game state
-  const { gameId, players, coords, linkedGame }  = useGameInfo();
+  const gameId = useGameId();
+  const coords = useGameCoords();
+  const players = usePlayers();
+  const linkedGame = useLinkedGame();
 
 
   // set up the summary URL
   // set up the summary URL
   const summaryURL = new URL(window.location.href);
   const summaryURL = new URL(window.location.href);
   summaryURL.searchParams.append("summary", gameId);
   summaryURL.searchParams.append("summary", gameId);
 
 
-  if (!players) {
+  if (!players || !coords) {
     return <Loading/>
     return <Loading/>
   }
   }
 
 

+ 2 - 2
client/src/components/screens/RoundSummary/RoundSummary.jsx

@@ -5,7 +5,7 @@ import useMarkersFromGuesses from "../../../hooks/useMarkersFromGuesses";
 import useMap from "../../../hooks/useMap";
 import useMap from "../../../hooks/useMap";
 import NextRoundButton from "./NextRoundButton";
 import NextRoundButton from "./NextRoundButton";
 import useClickToCheckScore from "./useClickToCheckScore";
 import useClickToCheckScore from "./useClickToCheckScore";
-import useGameInfo from "../../../hooks/useGameInfo";
+import { usePlayers } from "../../../hooks/useGameInfo";
 import usePreventNavigation from "../../../hooks/usePreventNavigation";
 import usePreventNavigation from "../../../hooks/usePreventNavigation";
 
 
 const SummaryDiv = styled.div`
 const SummaryDiv = styled.div`
@@ -38,7 +38,7 @@ export default () => {
   const mapRef = useMap(mapDivRef, targetPoint.lat, targetPoint.lng, 4);
   const mapRef = useMap(mapDivRef, targetPoint.lat, targetPoint.lng, 4);
 
 
   // live update with all the scores
   // live update with all the scores
-  const players = useGameInfo()?.players;
+  const players = usePlayers();
 
 
   // add the player guess markers
   // add the player guess markers
   useMarkersFromGuesses(mapRef, players, roundNum, targetPoint);
   useMarkersFromGuesses(mapRef, players, roundNum, targetPoint);

+ 24 - 7
client/src/hooks/useGameInfo.jsx

@@ -1,17 +1,30 @@
 import { useState, useEffect } from 'react';
 import { useState, useEffect } from 'react';
 import dequal from 'dequal';
 import dequal from 'dequal';
-import { gameInfo } from '../domain/apiMethods';
+import { getGameConfig, getGameCoords, getPlayers, getLinkedGame } from '../domain/apiMethods';
 import { useGameId } from '../domain/gameStore';
 import { useGameId } from '../domain/gameStore';
 
 
-export default () => {
+const useSingleCall = apiCall => {
   const gameId = useGameId();
   const gameId = useGameId();
-  const [info, setInfo] = useState({});
+  const [info, setInfo] = useState(null);
+
+  useEffect(() => { apiCall(gameId).then(setInfo) }, [gameId, apiCall]);
+
+  return info;
+}
+
+export const useGameConfig = () => useSingleCall(getGameConfig) ?? {};
+
+export const useGameCoords = () => useSingleCall(getGameCoords);
+
+const useAutoRefresh = apiCall => {
+  const gameId = useGameId();
+  const [info, setInfo] = useState(null);
 
 
   useEffect(() => {
   useEffect(() => {
-    // define how to fetch scores
+    // define how to fetch info
     const fetchInfo = async () => {
     const fetchInfo = async () => {
-      const newInfo = await gameInfo(gameId);
-      // TODO maybe have back-end provide timestamp? to avoid this check
+      const newInfo = await apiCall(gameId);
+      // TODO make equality an argument? to avoid doing dequal on deep structures?
       if (!dequal(info, newInfo)) {
       if (!dequal(info, newInfo)) {
         setInfo(newInfo);
         setInfo(newInfo);
       }
       }
@@ -22,7 +35,11 @@ export default () => {
     const interval = setInterval(() => fetchInfo(), 5000);
     const interval = setInterval(() => fetchInfo(), 5000);
     // and return a clean-up callback
     // and return a clean-up callback
     return () => { clearInterval(interval) };
     return () => { clearInterval(interval) };
-  }, [gameId, info]);
+  }, [gameId, apiCall, info]);
 
 
   return info;
   return info;
 }
 }
+
+export const usePlayers = () => useAutoRefresh(getPlayers);
+
+export const useLinkedGame = () => useAutoRefresh(getLinkedGame);