Procházet zdrojové kódy

Moving a lot of domain logic into hooks and moving those into the hooks dir

Kirk Trombley před 5 roky
rodič
revize
acb3d7000b

+ 9 - 16
client/src/components/screens/GamePanel/GamePanel.jsx

@@ -1,28 +1,21 @@
-import React, { useState, useEffect } from 'react';
-import { gameInfo, getGuesses, sendGuess } from "../../../domain/GGSHService";
+import React, { useState } from 'react';
+import { sendGuess } from "../../../domain/GGSHService";
 import Loading from '../../util/Loading';
 import GuessPane from "./GuessPane";
 import PositionedStreetView from "./PositionedStreetView";
+import useRoundInfo from "../../../hooks/useRoundInfo";
 
 const GamePanelContainer = ({ gameId, playerName, onRoundEnd, onGameEnd }) => {
-  const [{ currentRound, targetPoint, roundSeconds }, setRoundInfo] = useState({currentRound: null, targetPoint: null, roundSeconds: null});
   const [submitDisabled, setSubmitDisabled] = useState(false);
   const [selectedPoint, setSelectedPoint] = useState(null);
+  const [finished, roundInfo] = useRoundInfo(gameId, playerName);
 
-  useEffect(() => {
-    const setup = async () => {
-      const { currentRound } = await getGuesses(gameId, playerName);
-      if (currentRound) {
-        const { coords, timer } = await gameInfo(gameId);
-        const targetPoint = coords[currentRound];
-        setRoundInfo({ currentRound, targetPoint, roundSeconds: timer });
-      } else {
-        onGameEnd();
-      }
-    }
-    setup();
-  }, [gameId, playerName, onGameEnd]);
+  if (finished) {
+    onGameEnd();
+    return <Loading/>
+  }
 
+  const { currentRound, targetPoint, roundSeconds } = roundInfo;
   if (!currentRound || !targetPoint || !roundSeconds) {
     return <Loading/>
   }

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

@@ -1,25 +1,11 @@
-import React, { useState, useEffect } from 'react';
-import { gameInfo } from '../../../domain/GGSHService';
+import React from 'react';
 import Loading from '../../util/Loading';
 import Button from "../../util/Button";
 import PlayerScoresList from "./PlayerScoresList";
+import usePlayerScores from '../../../hooks/usePlayerScores';
 
 const PlayerScoresContainer = ({ gameId, onReturnToStart }) => {
-  const [scores, setScores] = useState(null);
-
-  useEffect(() => {
-    // define how to fetch scores
-    const fetchInfo = async () => {
-      const { players } = await gameInfo(gameId);
-      setScores(players);
-    };
-    // when the component renders, fetch the game info
-    fetchInfo();
-    // and do it again every 5 seconds after
-    const interval = setInterval(() => fetchInfo(), 5000);
-    // and return a clean-up callback
-    return () => { clearInterval(interval) };
-  }, [gameId]);
+  const scores = usePlayerScores(gameId);
 
   if (!scores) {
     return <Loading/>

+ 3 - 9
client/src/components/util/ApiInfo.jsx

@@ -1,14 +1,8 @@
-import React, { useState, useEffect } from "react";
-import { getStatus } from "../../domain/GGSHService";
-
-const useApiHeath = () => {
-  const [data, setData] = useState(null);
-  useEffect(() => { getStatus().then(setData) }, []);
-  return data;
-}
+import React from "react";
+import useApiHealth from "../../hooks/useApiHealth";
 
 export default () => {
-  const data = useApiHeath();
+  const data = useApiHealth();
   
   if (data === null) {
     return <p>Connecting to back-end...</p>

+ 2 - 21
client/src/components/util/Timer.jsx

@@ -1,25 +1,6 @@
-import React, { useEffect, useState, useRef } from "react";
+import React from "react";
 import ms from "pretty-ms";
-
-const useCountdown = (seconds, onEnd) => {
-  const [finished, setFinished] = useState(false);
-  const [remaining, setRemaining] = useState(seconds);
-  const remainingMut = useRef(seconds);
-
-  useEffect(() => {
-    const timer = setInterval(() => setRemaining(remainingMut.current -= 1), 1000);
-    return () => clearInterval(timer);
-  }, []);
-
-  useEffect(() => {
-    if (!finished && remaining <= 0) {
-      onEnd();
-      setFinished(true);
-    }
-  }, [finished, remaining, onEnd])
-
-  return remaining;
-}
+import useCountdown from "../../hooks/useCountdown";
 
 export default ({ seconds, onTimeout }) => {
   const remaining = useCountdown(seconds, onTimeout);

+ 8 - 0
client/src/hooks/useApiHealth.jsx

@@ -0,0 +1,8 @@
+import { useState, useEffect } from "react";
+import { getStatus } from "../domain/GGSHService";
+
+export default () => {
+  const [data, setData] = useState(null);
+  useEffect(() => { getStatus().then(setData) }, []);
+  return data;
+}

+ 21 - 0
client/src/hooks/useCountdown.jsx

@@ -0,0 +1,21 @@
+import { useEffect, useState, useRef } from "react";
+
+export default (seconds, onEnd) => {
+  const [finished, setFinished] = useState(false);
+  const [remaining, setRemaining] = useState(seconds);
+  const remainingMut = useRef(seconds);
+
+  useEffect(() => {
+    const timer = setInterval(() => setRemaining(remainingMut.current -= 1), 1000);
+    return () => clearInterval(timer);
+  }, []);
+
+  useEffect(() => {
+    if (!finished && remaining <= 0) {
+      onEnd();
+      setFinished(true);
+    }
+  }, [finished, remaining, onEnd])
+
+  return remaining;
+}

+ 22 - 0
client/src/hooks/usePlayerScores.jsx

@@ -0,0 +1,22 @@
+import { useState, useEffect } from 'react';
+import { gameInfo } from '../domain/GGSHService';
+
+export default gameId => {
+  const [scores, setScores] = useState(null);
+
+  useEffect(() => {
+    // define how to fetch scores
+    const fetchInfo = async () => {
+      const { players } = await gameInfo(gameId);
+      setScores(players);
+    };
+    // when the hook triggers, fetch the game info
+    fetchInfo();
+    // and do it again every 5 seconds after
+    const interval = setInterval(() => fetchInfo(), 5000);
+    // and return a clean-up callback
+    return () => { clearInterval(interval) };
+  }, [gameId]);
+
+  return scores;
+}

+ 23 - 0
client/src/hooks/useRoundInfo.jsx

@@ -0,0 +1,23 @@
+import { useState, useEffect } from 'react';
+import { gameInfo, getGuesses } from "../domain/GGSHService";
+
+export default (gameId, playerName) => {
+  const [finished, setFinished] = useState(false);
+  const [roundInfo, setRoundInfo] = useState({currentRound: null, targetPoint: null, roundSeconds: null});
+
+  useEffect(() => {
+    const setup = async () => {
+      const { currentRound } = await getGuesses(gameId, playerName);
+      if (currentRound) {
+        const { coords, timer } = await gameInfo(gameId);
+        const targetPoint = coords[currentRound];
+        setRoundInfo({ currentRound, targetPoint, roundSeconds: timer });
+      } else {
+        setFinished(true);
+      }
+    }
+    setup();
+  }, [gameId, playerName]);
+
+  return [finished, roundInfo];
+}