Browse Source

CSS module for GamePanel, may want to split it a little further

Kirk Trombley 5 years ago
parent
commit
bf3212deab

+ 6 - 11
client/src/components/screens/GamePanel/ClickMarkerMap.jsx

@@ -1,16 +1,11 @@
-import React, { useRef } from "react";
-import styled from "styled-components";
-import useMap from "../../../hooks/useMap";
-import useClickMarker from "../../../hooks/useClickMarker";
-
-const MapDiv = styled.div`
-  height: 100%;
-  width: 100%;
-`
+import React, { useRef } from 'react';
+import useClickMarker from '../../../hooks/useClickMarker';
+import useMap from '../../../hooks/useMap';
+import styles from './GamePanel.module.css';
 
 export default ({ onMarkerMoved }) => {
   const mapDivRef = useRef(null);
   const mapRef = useMap(mapDivRef);
   useClickMarker(mapRef, onMarkerMoved);
-  return <MapDiv ref={mapDivRef} />
-}
+  return <div className={styles.fullsize} ref={mapDivRef} />;
+};

+ 23 - 43
client/src/components/screens/GamePanel/GamePanel.jsx

@@ -1,52 +1,32 @@
 import React, { useEffect } from 'react';
-import styled from 'styled-components';
-import Loading from '../../util/Loading';
-import GuessPane from "./GuessPane";
-import PositionedStreetView from "./PositionedStreetView";
 import { dispatch, useCurrentRound } from '../../../domain/gameStore';
 import usePreventNavigation from '../../../hooks/usePreventNavigation';
-
-const Container = styled.div`
-  height: 100%;
-  width: 100%;
-  display: flex;
-  flex-flow: column nowrap;
-  justify-content: space-between;
-  align-items: center;
-
-  @media only screen and (min-width: 600px) and (min-height: 600px) {
-    display: block;
-    position: relative;
-    margin-bottom: 2px;
-    margin-right: 2px;
-  }
-`
-
-const StreetViewWrapper = styled.div`
-  height: 100%;
-  width: 100%;
-  margin-bottom: 2px;
-  flex: 3;
-`
+import Loading from '../../util/Loading';
+import styles from './GamePanel.module.css';
+import GuessPane from './GuessPane';
+import PositionedStreetView from './PositionedStreetView';
 
 export default () => {
   // warn the user if they navigate away
   usePreventNavigation();
   const finished = useCurrentRound() === null;
-  useEffect(() => { 
-    if (finished) {
-      dispatch.goToSummary();
-    }
-  }, [finished]);
+  useEffect(
+    () => {
+      if (finished) {
+        dispatch.goToSummary();
+      }
+    },
+    [ finished ]
+  );
 
-  return finished
-    ? <Loading />
-    : (
-      <Container>
-        <StreetViewWrapper>
-          <PositionedStreetView />
-        </StreetViewWrapper>
-        <GuessPane />
-      </Container>
-    );
-}
+  return finished ? (
+    <Loading />
+  ) : (
+    <div className={styles.page}>
+      <div className={styles.streetview}>
+        <PositionedStreetView />
+      </div>
+      <GuessPane />
+    </div>
+  );
+};

+ 141 - 0
client/src/components/screens/GamePanel/GamePanel.module.css

@@ -0,0 +1,141 @@
+.page {
+  height: 100%;
+  width: 100%;
+  display: flex;
+  flex-flow: column nowrap;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.streetview {
+  height: 100%;
+  width: 100%;
+  margin-bottom: 2px;
+  flex: 3;
+  position: relative;
+}
+
+.fullsize {
+  height: 100%;
+  width: 100%;
+}
+
+.resetButton {
+  /* TODO improve this to be less brittle */
+  display: block;
+  position: absolute;
+  z-index: 1;
+  bottom: 200px;
+  right: 9px;
+  background-color: #222;
+  color: #666;
+  padding: 5px;
+  border-radius: 2px;
+  font-weight: bold;
+  cursor: pointer;
+}
+
+.resetButton:hover {
+  color: #b1b1b1;
+}
+
+.guess {
+  height: 100%;
+  width: 100%;
+  flex: 1;
+  display: flex;
+  flex-flow: row nowrap;
+  justify-content: space-around;
+}
+
+.map {
+  flex: 3;
+  height: 100%;
+  width: 100%;
+}
+
+.submit {
+  flex: 1;
+  display: flex;
+  flex-flow: column nowrap;
+  justify-content: center;
+  text-align: center;
+}
+
+.submitButton {
+  flex: 1;
+  margin: 2px;
+}
+
+.timer {
+  padding: 1px;
+  display: inline;
+}
+
+.timer--timeout {
+  color: red;
+}
+
+@media only screen and (min-width: 600px) and (min-height: 600px) {
+  .page {
+    display: block;
+    position: relative;
+    margin-bottom: 2px;
+    margin-right: 2px;
+  }
+
+  .guess {
+    position: absolute;
+    left: 10px;
+    bottom: 10px;
+    height: 200px;
+    width: 200px;
+    flex-flow: column-reverse nowrap;
+    z-index: 1;
+    opacity: .75;
+    transition: 1s;
+  }
+
+  .guess:hover {
+    height: 400px;
+    width: 400px;
+    opacity: 1;
+    transition: 0.5s;
+  }
+
+  .map {
+    opacity: .75;
+    transition: 1s;
+  }
+
+  .map:hover {
+    opacity: 1;
+  }
+
+  .submit {
+    flex-flow: column-reverse nowrap;
+    margin-top: 4px;
+    color: #fff;
+  }
+
+  .submit>* {
+    background-color: #333;
+  }
+
+  .submitButton {
+    margin: 0px;
+    margin-bottom: 5px;
+  }
+
+  .guess .submitButton {
+    visibility: hidden;
+    opacity: 0;
+    transition: 1s;
+  }
+
+  .guess:hover .submitButton {
+    visibility: visible;
+    opacity: 1;
+    transition: 0.5s;
+  }
+}

+ 20 - 99
client/src/components/screens/GamePanel/GuessPane.jsx

@@ -1,114 +1,35 @@
-import React, { useState } from "react";
-import styled from "styled-components";
-import ClickMarkerMap from "./ClickMarkerMap";
-import RoundTimer from "./RoundTimer";
-import { dispatch } from "../../../domain/gameStore";
-
-const Container = styled.div`
-  height: 100%;
-  width: 100%;
-  flex: 1;
-  display: flex;
-  flex-flow: row nowrap;
-  justify-content: space-around;
-
-  @media only screen and (min-width: 600px) and (min-height: 600px) {
-    position: absolute;
-    left: 10px;
-    bottom: 10px;
-    height: 200px;
-    width: 200px;
-    flex-flow: column-reverse nowrap;
-    z-index: 1;
-    opacity: .75;
-    transition: 1s;
-
-    &:hover {
-      height: 400px;
-      width: 400px;
-      opacity: 1;
-      transition: 0.5s;
-    }
-  }
-`
-
-const MapWrapper = styled.div`
-  flex: 3;
-  height: 100%;
-  width: 100%;
-
-  @media only screen and (min-width: 600px) and (min-height: 600px) {
-    opacity: .75;
-    transition: 1s;
-
-    &:hover {
-      opacity: 1;
-    }
-  }
-`
-
-const SubmitWrapper = styled.div`
-  flex: 1;
-  display: flex;
-  flex-flow: column nowrap;
-  justify-content: center;
-  text-align: center;
-
-  @media only screen and (min-width: 600px) and (min-height: 600px) {
-    flex-flow: column-reverse nowrap;
-    margin-top: 4px;
-    color: #fff;
-
-    &>* {
-      background-color: #333;
-    }
-  }
-`
-
-const SubmitButton = styled.button`
-  flex: 1;
-  margin: 2px;
-
-  @media only screen and (min-width: 600px) and (min-height: 600px) {
-    margin: 0px;
-    margin-bottom: 5px;
-
-    ${Container} & {
-      visibility: hidden;
-      opacity: 0;
-      transition: 1s;
-    }
-
-    ${Container}:hover & {
-      visibility: visible;
-      opacity: 1;
-      transition: 0.5s;
-    }
-  }
-`
+import React, { useState } from 'react';
+import { dispatch } from '../../../domain/gameStore';
+import ClickMarkerMap from './ClickMarkerMap';
+import styles from './GamePanel.module.css';
+import RoundTimer from './RoundTimer';
 
 export default () => {
-  const [selectedPoint, setSelectedPoint] = useState(null);
-  const [submitted, setSubmitted] = useState(false);
+  const [ selectedPoint, setSelectedPoint ] = useState(null);
+  const [ submitted, setSubmitted ] = useState(false);
 
   const handleSubmitGuess = async () => {
     setSubmitted(true);
     if (!submitted) {
       await dispatch.submitGuess(selectedPoint);
     }
-  }
+  };
 
   return (
-    <Container>
-      <MapWrapper>
+    <div className={styles.guess}>
+      <div className={styles.map}>
         <ClickMarkerMap onMarkerMoved={setSelectedPoint} />
-      </MapWrapper>
-      <SubmitWrapper>
+      </div>
+      <div className={styles.submit}>
         <RoundTimer onTimeout={handleSubmitGuess} />
-        <SubmitButton onClick={handleSubmitGuess} disabled={submitted || selectedPoint === null}>
+        <button
+          className={styles.submitButton}
+          onClick={handleSubmitGuess}
+          disabled={submitted || selectedPoint === null}
+        >
           Submit Guess
-        </SubmitButton>
-      </SubmitWrapper>
-    </Container>
+        </button>
+      </div>
+    </div>
   );
 };

+ 25 - 52
client/src/components/screens/GamePanel/PositionedStreetView.jsx

@@ -1,38 +1,8 @@
-import React, { useRef, useEffect } from "react";
-import styled from "styled-components";
-import usePano from "./usePano";
-import { useTargetPoint, usePanoStartPosition, usePanoStartPov } from "../../../domain/gameStore";
-import { savePanoPositionToLocalStorage, savePanoPovToLocalStorage } from "../../../domain/localStorageMethods";
-
-const Container = styled.div`
-  position: relative;
-  height: 100%;
-  width: 100%;
-`
-
-const Pano = styled.div`
-  height: 100%;
-  width: 100%;
-`
-
-const ResetButton = styled.div`
-  /* TODO improve this to be less brittle */
-  display: block;
-  position: absolute;
-  z-index: 1;
-  bottom: 200px;
-  right: 9px;
-  background-color: #222;
-  color: #666;
-  padding: 5px;
-  border-radius: 2px;
-  font-weight: bold;
-  cursor: pointer;
-
-  &:hover {
-    color: #b1b1b1;
-  }
-`
+import React, { useEffect, useRef } from 'react';
+import { usePanoStartPosition, usePanoStartPov, useTargetPoint } from '../../../domain/gameStore';
+import { savePanoPositionToLocalStorage, savePanoPovToLocalStorage } from '../../../domain/localStorageMethods';
+import styles from './GamePanel.module.css';
+import usePano from './usePano';
 
 export default () => {
   const startPosition = usePanoStartPosition();
@@ -40,25 +10,28 @@ export default () => {
   const resetPosition = useTargetPoint();
   const panoDivRef = useRef(null);
   const panoRef = usePano(panoDivRef, startPosition, startPov);
-  useEffect(() => {
-    if (panoRef.current) {
-      panoRef.current.addListener("position_changed", () => {
-        const { lat, lng } = panoRef.current.getPosition();
-        savePanoPositionToLocalStorage(lat(), lng());
-      });
-      panoRef.current.addListener("pov_changed", () => {
-        const { heading, pitch } = panoRef.current.getPov();
-        savePanoPovToLocalStorage(heading, pitch);
-      });
-    }
-  }, [panoRef]);
+  useEffect(
+    () => {
+      if (panoRef.current) {
+        panoRef.current.addListener('position_changed', () => {
+          const { lat, lng } = panoRef.current.getPosition();
+          savePanoPositionToLocalStorage(lat(), lng());
+        });
+        panoRef.current.addListener('pov_changed', () => {
+          const { heading, pitch } = panoRef.current.getPov();
+          savePanoPovToLocalStorage(heading, pitch);
+        });
+      }
+    },
+    [ panoRef ]
+  );
 
   return (
-    <Container>
-      <Pano ref={panoDivRef}/>
-      <ResetButton onClick={() => panoRef.current.setPosition(resetPosition)}>
+    <>
+      <div className={styles.fullsize} ref={panoDivRef} />
+      <div className={styles.resetButton} onClick={() => panoRef.current.setPosition(resetPosition)}>
         Reset
-      </ResetButton>
-    </Container>
+      </div>
+    </>
   );
 };

+ 32 - 32
client/src/components/screens/GamePanel/RoundTimer.jsx

@@ -1,40 +1,40 @@
-import React, { useEffect, useState } from "react";
-import styled from "styled-components";
-import ms from "pretty-ms";
-import { useRoundSeconds, dispatch } from "../../../domain/gameStore";
+import ms from 'pretty-ms';
+import React, { useEffect, useState } from 'react';
+import { dispatch, useRoundSeconds } from '../../../domain/gameStore';
+import styles from './GamePanel.module.css';
 
-const TimerSpan = styled.span`
-  padding: 1px;
-  display: inline;
-`
-
-const TimedOut = styled(TimerSpan)`
-  color: red;
-`
-
-const useRoundTimer = onTimeout => {
+const useRoundTimer = (onTimeout) => {
   const remaining = useRoundSeconds();
-  useEffect(() => {
-    if (remaining > 0) {
-      const timeout = setTimeout(() => { dispatch.setRoundSeconds(remaining - 1); }, 1000);
-      return () => clearTimeout(timeout);
-    }
-  }, [remaining]);
-  const [called, setCalled] = useState(false);
-  useEffect(() => {
-    if (!called && remaining <= 0) {
-      onTimeout();
-      setCalled(true);
-    }
-  }, [onTimeout, remaining, called]);
+  useEffect(
+    () => {
+      if (remaining > 0) {
+        const timeout = setTimeout(() => {
+          dispatch.setRoundSeconds(remaining - 1);
+        }, 1000);
+        return () => clearTimeout(timeout);
+      }
+    },
+    [ remaining ]
+  );
+  const [ called, setCalled ] = useState(false);
+  useEffect(
+    () => {
+      if (!called && remaining <= 0) {
+        onTimeout();
+        setCalled(true);
+      }
+    },
+    [ onTimeout, remaining, called ]
+  );
   return remaining;
-}
+};
 
 export default ({ onTimeout }) => {
   const remaining = useRoundTimer(onTimeout);
+  const out = remaining <= 0;
   return (
-    remaining > 0
-      ? <TimerSpan>Time: {ms(remaining * 1000)}</TimerSpan>
-      : <TimedOut>Time's up!</TimedOut>
+    <span className={`${styles.timer} ${out ? styles['timer--timeout'] : ''}`}>
+      {out ? "Time's up!" : `Time: ${ms(remaining * 1000)}`}
+    </span>
   );
-}
+};