Procházet zdrojové kódy

Moving round timer into the store so it can be easily persisted by it later

Kirk Trombley před 5 roky
rodič
revize
d62a61581e

+ 2 - 3
client/src/components/screens/GamePanel/GamePanel.jsx

@@ -43,8 +43,8 @@ export default () => {
     return <Loading/>
   }
 
-  const { currentRound, targetPoint, roundSeconds } = roundInfo;
-  if (!currentRound || !targetPoint || !roundSeconds) {
+  const { currentRound, targetPoint } = roundInfo;
+  if (!currentRound || !targetPoint) {
     return <Loading/>
   }
 
@@ -59,7 +59,6 @@ export default () => {
         <PositionedStreetView position={targetPoint} resetPosition={targetPoint} />
       </StreetViewWrapper>
       <GuessPane
-        roundSeconds={roundSeconds}
         onTimeout={handleSubmitGuess}
         onSelectPoint={setSelectedPoint}
         onSubmitGuess={handleSubmitGuess}

+ 1 - 2
client/src/components/screens/GamePanel/GuessPane.jsx

@@ -88,7 +88,6 @@ const SubmitButton = styled(Button)`
 `
 
 export default ({
-  roundSeconds,
   onTimeout,
   onSelectPoint,
   onSubmitGuess,
@@ -99,7 +98,7 @@ export default ({
       <ClickMarkerMap onMarkerMoved={onSelectPoint} />
     </MapWrapper>
     <SubmitWrapper>
-      <RoundTimer seconds={roundSeconds} onTimeout={onTimeout} />
+      <RoundTimer onTimeout={onTimeout} />
       <SubmitButton onClick={onSubmitGuess} disabled={submitDisabled}>
         Submit Guess
       </SubmitButton>

+ 22 - 11
client/src/components/screens/GamePanel/RoundTimer.jsx

@@ -1,8 +1,7 @@
-import React, { useEffect } from "react";
+import React, { useEffect, useState } from "react";
 import styled from "styled-components";
 import ms from "pretty-ms";
-import useCountdown from "../../../hooks/useCountdown";
-import { saveTimerToLocalStorage } from "../../../domain/localStorageMethods";
+import { useRoundSeconds, dispatch } from "../../../domain/gameStore";
 
 const TimerSpan = styled.span`
   padding: 1px;
@@ -13,17 +12,29 @@ const TimedOut = styled(TimerSpan)`
   color: red;
 `
 
-export default ({ seconds, onTimeout }) => {
-  const [remaining] = useCountdown(seconds, () => onTimeout());
+const useRoundTimer = onTimeout => {
+  const remaining = useRoundSeconds();
   useEffect(() => {
     if (remaining > 0) {
-      saveTimerToLocalStorage(remaining);
+      const timeout = setTimeout(() => { dispatch.setRoundSeconds(remaining - 1); }, 1000);
+      return () => clearTimeout(timeout);
     }
   }, [remaining]);
-  
-  if (remaining > 0) {
-    return <TimerSpan>Time: {ms(remaining * 1000)}</TimerSpan>;
-  }
+  const [called, setCalled] = useState(false);
+  useEffect(() => {
+    if (!called && remaining <= 0) {
+      onTimeout();
+      setCalled(true);
+    }
+  }, [onTimeout, remaining, called]);
+  return remaining;
+}
 
-  return <TimedOut>Time's up!</TimedOut>;
+export default ({ onTimeout }) => {
+  const remaining = useRoundTimer(onTimeout);
+  return (
+    remaining > 0
+      ? <TimerSpan>Time: {ms(remaining * 1000)}</TimerSpan>
+      : <TimedOut>Time's up!</TimedOut>
+  );
 }

+ 3 - 0
client/src/domain/gameStore.js

@@ -15,6 +15,7 @@ export const [
     useLastRound,
     usePlayerId,
     useGameState,
+    useRoundSeconds,
   },
   dispatch,
 ] = createStore({
@@ -31,6 +32,7 @@ export const [
   },
   playerId: null,
   gameState: PRE_GAME,
+  roundSeconds: 0,
 }, {
   setPlayerName: ([set], playerName) => set({ playerName }),
   goToLobby: ([set], gameId) => set({ 
@@ -84,4 +86,5 @@ export const [
       clearGameInfoFromLocalStorage();
     }
   },
+  setRoundSeconds: ([set], roundSeconds) => set({ roundSeconds }),
 });

+ 4 - 3
client/src/hooks/useRoundInfo.jsx

@@ -1,18 +1,19 @@
 import { useState, useEffect } from 'react';
 import { getCurrentRound } from "../domain/apiMethods";
-import { useGameId, usePlayerId } from '../domain/gameStore';
+import { useGameId, usePlayerId, dispatch } from '../domain/gameStore';
 
 export default () => {
   const gameId = useGameId();
   const playerId = usePlayerId();
   const [finished, setFinished] = useState(false);
-  const [roundInfo, setRoundInfo] = useState({currentRound: null, targetPoint: null, roundSeconds: null});
+  const [roundInfo, setRoundInfo] = useState({currentRound: null, targetPoint: null});
 
   useEffect(() => {
     const setup = async () => {
       const { currentRound, coord, timer } = await getCurrentRound(gameId, playerId);
       if (currentRound) {
-        setRoundInfo({ currentRound, targetPoint: coord, roundSeconds: timer });
+        dispatch.setRoundSeconds(timer);
+        setRoundInfo({ currentRound, targetPoint: coord });
       } else {
         setFinished(true);
       }