From 4199d7ab6ac9334db19bba216e47d58e2fd3fedb Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Wed, 5 Aug 2020 12:01:54 +1000 Subject: [PATCH] Change the timer data structure to fix network bugs and refactored shared timer functions --- src/components/party/Party.js | 10 +++++++- src/components/party/Timer.js | 43 ++++++++++++----------------------- src/helpers/timer.js | 33 +++++++++++++++++++++++++++ src/modals/StartTimerModal.js | 13 +++++++---- src/network/NetworkedParty.js | 35 ++++++++++++++-------------- 5 files changed, 83 insertions(+), 51 deletions(-) create mode 100644 src/helpers/timer.js diff --git a/src/components/party/Party.js b/src/components/party/Party.js index 6dce999..a4bee8c 100644 --- a/src/components/party/Party.js +++ b/src/components/party/Party.js @@ -58,7 +58,15 @@ function Party({ stream={partyStreams[id]} /> ))} - + {timer && } + {Object.entries(partyTimers).map(([id, partyTimer], index) => ( + + ))} diff --git a/src/components/party/Timer.js b/src/components/party/Timer.js index 983f5ec..1b1d80b 100644 --- a/src/components/party/Timer.js +++ b/src/components/party/Timer.js @@ -1,33 +1,18 @@ -import React, { useEffect, useState, useRef } from "react"; +import React, { useEffect, useRef } from "react"; import ReactDOM from "react-dom"; import { Box, Progress } from "theme-ui"; import usePortal from "../../helpers/usePortal"; -function getTimerDuration(t) { - if (!t) { - return 0; - } - return t.hour * 3600000 + t.minute * 60000 + t.second * 1000; -} - -function Timer({ timer }) { - const [maxDuration, setMaxDuration] = useState(0); - - const previousTimerRef = useRef(timer); - useEffect(() => { - if (!previousTimerRef.current && timer) { - setMaxDuration(getTimerDuration(timer)); - } - previousTimerRef.current = timer; - }); - - useEffect(() => { - progressBarRef.current.value = getTimerDuration(timer); - }, [timer]); - +function Timer({ timer, index }) { const progressBarRef = useRef(); + useEffect(() => { + if (progressBarRef.current && timer) { + progressBarRef.current.value = timer.current; + } + }, [timer]); + useEffect(() => { let request = requestAnimationFrame(animate); let previousTime = performance.now(); @@ -36,13 +21,15 @@ function Timer({ timer }) { const deltaTime = time - previousTime; previousTime = time; - progressBarRef.current.value -= deltaTime; + if (progressBarRef.current && progressBarRef.current.value > 0) { + progressBarRef.current.value -= deltaTime; + } } return () => { cancelAnimationFrame(request); }; - }, [maxDuration]); + }, []); const timerContainer = usePortal("root"); @@ -59,15 +46,15 @@ function Timer({ timer }) { borderRadius: "28px", left: "50%", maxWidth: "500px", - width: "60%", - transform: "translateX(-50%)", + width: "40%", + transform: `translate(-50%, -${index * 36}px)`, padding: "0 8px", margin: "8px", }} bg="overlay" > setHour(parseValue(e.target.value, 24))} type="number" disabled={timer} @@ -82,7 +87,7 @@ function StartTimerModal({ setMinute(parseValue(e.target.value, 59))} type="number" ref={inputRef} @@ -95,7 +100,7 @@ function StartTimerModal({ setSecond(parseValue(e.target.value, 59))} type="number" disabled={timer} diff --git a/src/network/NetworkedParty.js b/src/network/NetworkedParty.js index 0152160..522abc3 100644 --- a/src/network/NetworkedParty.js +++ b/src/network/NetworkedParty.js @@ -3,7 +3,7 @@ import React, { useContext, useState, useEffect, useCallback } from "react"; // Load session for auto complete // eslint-disable-next-line no-unused-vars import Session from "../helpers/Session"; -import { isStreamStopped, omit } from "../helpers/shared"; +import { isStreamStopped, omit, fromEntries } from "../helpers/shared"; import AuthContext from "../contexts/AuthContext"; @@ -73,23 +73,18 @@ function NetworkedParty({ gameId, session }) { useEffect(() => { function decreaseTimer(previousTimer) { - if (previousTimer.second > 0) { - return { ...previousTimer, second: previousTimer.second - 1 }; - } else if (previousTimer.minute > 0) { - return { - ...previousTimer, - minute: previousTimer.minute - 1, - second: 59, - }; - } else if (previousTimer.hour > 0) { - return { hour: previousTimer.hour - 1, minute: 59, second: 59 }; - } else return { hour: 0, minute: 0, second: 0 }; + return { ...previousTimer, current: previousTimer.current - 1000 }; } function updateTimers() { if (timer) { const newTimer = decreaseTimer(timer); - setTimer(newTimer); - session.send("timer", { [session.id]: newTimer }); + if (newTimer.current < 0) { + setTimer(null); + session.send("timer", { [session.id]: null }); + } else { + setTimer(newTimer); + session.send("timer", { [session.id]: newTimer }); + } } } const interval = setInterval(updateTimers, 1000); @@ -122,10 +117,14 @@ function NetworkedParty({ gameId, session }) { })); } if (id === "timer") { - setPartyTimers((prevTimers) => ({ - ...prevTimers, - ...data, - })); + setPartyTimers((prevTimers) => { + const newTimers = { ...prevTimers, ...data }; + // filter out timers that are null + const filtered = Object.entries(newTimers).filter( + ([, value]) => value !== null + ); + return fromEntries(filtered); + }); } }