Kaynağa Gözat

Implementing the round selection logic

Kirk Trombley 5 yıl önce
ebeveyn
işleme
b4d5c7180a

+ 53 - 12
client/src/components/screens/PlayerScores/PlayerScores.jsx

@@ -11,6 +11,7 @@ import GameCreationForm from '../../util/GameCreationForm';
 import useMap from '../../../hooks/useMap';
 import useMarkersFromGuesses from '../../../hooks/useMarkersFromGuesses';
 import { useState } from 'react';
+import { useEffect } from 'react';
 
 const Container = styled.div`
   display: flex;
@@ -60,21 +61,52 @@ const MapContainer = styled.div`
   justify-content: center;
 `;
 
+const RoundSelectContainer = styled.div`
+  display: flex;
+  flex-flow: row nowrap;
+  justify-content: space-between;
+  align-items: center;
+  width: 50%;
+  margin-bottom: 0.5em;
+`;
+
+const RoundSelectButton = styled.div`
+  background-color: ${({active}) => active ? "#777" : "#555"};
+  width: 2em;
+  height: 2em;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+`;
+
 const getUrl = gameId => {
   const u = new URL(window.location.href);
   u.searchParams.append("summary", gameId);
   return u.href;
 }
 
-const SummaryMap = ({ mapDivRef, mapRef, players, coords, roundNum }) => {
+const SummaryMap = ({ players, coords, roundActive }) => {
+  // create the map
+  const mapDivRef = useRef(null);
+  const mapRef = useMap(mapDivRef, 0, 0, 1);
+
+  console.log("SummaryMap render");
+
   // get just the relevant players to put on the map
+  // TODO this can probably go back to being shared code...
   const playersFiltered = players
-    ?.filter(({ guesses }) => guesses[roundNum] && guesses[roundNum].score !== null)
-    ?.map(({ name, totalScore, guesses }) => ({ name, totalScore, guess: guesses[roundNum] }));
-  const targetPoint = coords?.[roundNum] ?? null;
+    ?.filter(({ guesses }) => guesses[roundActive] && guesses[roundActive].score !== null)
+    ?.map(({ name, totalScore, guesses }) => ({ name, totalScore, guess: guesses[roundActive] }));
+  const targetPoint = coords?.[roundActive] ?? null;
 
   useMarkersFromGuesses(mapRef, playersFiltered, targetPoint);
 
+  useEffect(() => {
+    if (targetPoint && mapRef.current) {
+      mapRef.current.panTo(targetPoint);
+    }
+  }, [mapRef, targetPoint]);
+
   return (
     <MapContainer>
       <MapDiv ref={mapDivRef}/>
@@ -82,6 +114,17 @@ const SummaryMap = ({ mapDivRef, mapRef, players, coords, roundNum }) => {
   );
 }
 
+const RoundSelect = ({ rounds, roundNum, setRoundNum }) => (
+  <RoundSelectContainer>
+    { 
+      // fun fact: es6 doesn't have a range(x) function
+      Array.from(Array(rounds).keys())
+        .map(r => (r + 1).toString())
+        .map(r => <RoundSelectButton active={r === roundNum} key={r} onClick={() => setRoundNum(r)}>{r}</RoundSelectButton>)
+    }
+  </RoundSelectContainer>
+);
+
 const ScoreBoard = ({ players }) => (
   <ScoreBoardContainer>
     {
@@ -106,15 +149,12 @@ const LinkedGame = React.memo(({ linkedGame, gameId }) => (
 ));
 
 export default () => {
-  // create the map
-  // const mapDivRef = useRef(null);
-  // const mapRef = useMap(mapDivRef, 0, 0, 1);
-
   // poll the game state
-  const { gameId, players, coords, linkedGame }  = useGameInfo();
+  const { gameId, players, coords, rounds, linkedGame }  = useGameInfo();
 
   // set up round number selection
-  // const [roundNum, setRoundNum] = useState("0");
+  const [roundNum, setRoundNum] = useState("0");
+  const roundActive = rounds > 1 ? roundNum : "1";
 
   if (!players) {
     return <Loading/>
@@ -122,8 +162,9 @@ export default () => {
 
   return (
     <Container>
-      {/* <SummaryMap {...{ mapDivRef, mapRef, players, coords, roundNum }}/> */}
-      <ScoreBoard {...{ players }}/>
+      { rounds > 1 ? <RoundSelect {...{ rounds, roundNum, setRoundNum }} /> : null }
+      <SummaryMap {...{ players, coords, roundActive }}/>
+      <ScoreBoard {...{ players }} />
       <LinkedGame {...{ linkedGame, gameId }} />
       <Label><ClickToCopy text={getUrl(gameId)}>Click here to copy a link to this summary!</ClickToCopy></Label>
     </Container>