diff --git a/client/package-lock.json b/client/package-lock.json
index a9933a7..cfef93c 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -6888,6 +6888,19 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
},
+ "history": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
+ "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "loose-envify": "^1.2.0",
+ "resolve-pathname": "^3.0.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0",
+ "value-equal": "^1.0.1"
+ }
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -10186,6 +10199,15 @@
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz",
"integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY="
},
+ "mini-create-react-context": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
+ "integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "tiny-warning": "^1.0.3"
+ }
+ },
"mini-css-extract-plugin": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
@@ -13429,6 +13451,52 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "react-router": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
+ "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "hoist-non-react-statics": "^3.1.0",
+ "loose-envify": "^1.3.1",
+ "mini-create-react-context": "^0.4.0",
+ "path-to-regexp": "^1.7.0",
+ "prop-types": "^15.6.2",
+ "react-is": "^16.6.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ }
+ }
+ },
+ "react-router-dom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
+ "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "loose-envify": "^1.3.1",
+ "prop-types": "^15.6.2",
+ "react-router": "5.2.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ }
+ },
"react-scripts": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
@@ -14088,6 +14156,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
},
+ "resolve-pathname": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
+ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -15666,6 +15739,11 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
},
+ "tiny-invariant": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
+ "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
+ },
"tiny-warning": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
@@ -16086,6 +16164,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "value-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
+ "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/client/package.json b/client/package.json
index 8cf402f..4729dd2 100644
--- a/client/package.json
+++ b/client/package.json
@@ -14,6 +14,7 @@
"react-color": "^2.18.1",
"react-countdown-clock": "^2.7.0",
"react-dom": "^16.13.1",
+ "react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"react-window": "^1.8.5",
"socket.io-client": "^2.3.0",
diff --git a/client/src/App.css b/client/src/App.css
index 3ef5103..bbbe423 100644
--- a/client/src/App.css
+++ b/client/src/App.css
@@ -6,111 +6,9 @@ html {
--buttonColor: linear-gradient(to bottom, #d1e4f6 0%, #c5d8e9 100%);
}
-.App {
- text-align: center;
-}
-
body {
background-color: var(--backgroundColor);
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
-
-
-.App-logo {
- height: 40vmin;
- pointer-events: none;
-}
-
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
-}
-
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
-}
-
-.layoutContainer {
- width: auto;
- max-height: 100vh;
-}
-
-.userScoreGridItem {
- margin-left: auto;
- margin-right: auto;
- margin-bottom: 10px;
- margin-top: auto;
- height: 42vh;
- display: flex;
-}
-
-.userScoreContainer {
- width: 100%;
- display: flex;
-}
-
-.logWindowContainer {
- margin-left: auto;
- margin-right: auto;
- margin-top: 20px;
-}
-
-.midPane {
- margin-left: auto;
- margin-right: auto;
-}
-
-.midPaneContainer {
- margin: auto;
-}
-
-.guessBox {
- width: 100%;
- background-color: white;
- z-index: 100;
-}
-
-.canvasContainer {
- margin: auto;
-}
-
-.inputContainer {
- position: relative;
- margin: auto;
-}
-
-.canvasToolboxContainer {
- margin: auto;
-}
-
-.playersIconContainer {
- width: inherit;
- text-align: start;
- position: absolute;
- top: 10px;
- left: 10px;
-}
-
-.playersIconButton {
- position: relative;
- z-index: 100;
-}
-
-.playersIcon {
- border-radius: 50%;
- background-color: var(--primaryColor);
-}
diff --git a/client/src/App.js b/client/src/App.js
index f82346e..94cff54 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -1,490 +1,29 @@
-import React, { useState, useEffect, useRef } from 'react';
-import socket from 'socket.io-client';
-import { TextField, Hidden, IconButton, Badge, Paper, Toolbar, SvgIcon } from '@material-ui/core';
+import React from 'react';
import { StylesProvider } from '@material-ui/core/styles';
-import Grid from '@material-ui/core/Grid';
-import ElementResizeDetectorMaker from 'element-resize-detector';
-import Typography from '@material-ui/core/Typography';
-import { ReactComponent as AppLogo } from './assets/logo.svg';
-
-import AppBar from './components/appbar';
-import AddNicknameDialog from './components/dialogs/AddNicknameDialog';
-import LogWindow from './components/log-window';
-import UserScoreList from './components/player-list/UserScoreList';
-import PlayersIcon from './components/icons/PlayersIcon';
-import UserScoreListDialog from './components/dialogs/UserScoreListDialog';
-import * as GameStateConstants from './constants/AppConstants';
-import GameStateDisplay from './components/game-state-display/GameStateDisplay';
-import CanvasToolbox from './components/toolbox';
-
+import {
+ BrowserRouter as Router,
+ Switch,
+ Route
+} from 'react-router-dom';
import './App.css';
-const DEFAULT_ROOM = 'main';
-const ROUND_DURATION = 60;
+import Home from './components/home';
+import Room from './components/room';
+import { PlayerContextProvider } from './contexts/PlayerContext';
function App () {
- const [socketIO, setSocketIO] = useState(null);
- const [room, setRoom] = useState(DEFAULT_ROOM);
- const [drawWord, setDrawWord] = useState(null);
- const [playerNickname, setPlayerNickname] = useState(null);
- const [shouldShowPlayersList, setShouldShowPlayersList] = useState(false);
- const [showGuessBox, setShowGuessBox] = useState(false);
- const [disableGuessBox, setDisableGuessBox] = useState(true);
- const [guess, setGuess] = useState('');
- const [currentUser, setCurrentUser] = useState(null);
- const [userScores, setUserScores] = useState(null);
- const [previousWord, setPreviousWord] = useState(null);
- const [roundDuration, setRoundDuration] = useState(0);
- const [roundInfo, setRoundInfo] = useState({ current: 0, total: 0 });
- const [gameState, setGameState] = useState(
- GameStateConstants.GAME_STATE_IDLE
- );
- const [canvasOptions, setCanvasOptions] = useState({ color: '#000000', enabled: true });
- const [messageLog, setMessageLog] = useState([]);
- const [liveMessage, setLiveMessage] = useState('');
- const [winners, setWinners] = useState([]);
-
- const guessBoxRef = useRef(null);
- const keyboardRef = useRef();
- const canvasPaperRef = useRef(null);
-
- useEffect(() => {
- if (guessBoxRef && guessBoxRef.current) guessBoxRef.current.focus();
- }, [showGuessBox]);
-
- useEffect(() => {
- if (playerNickname) {
- const io = socket('http://localhost:3001');
- io.on('connect', () => {
- const user = {
- id: `${playerNickname}_${+new Date()}`,
- name: `${playerNickname}`,
- score: 0
- };
- console.log('Socket connected', user);
-
- io.emit('C_S_LOGIN', user, room);
-
- io.on('S_C_LOGIN', cbSCLogin);
- io.on('GE_NEW_GAME', cbNewGame);
- io.on('GE_NEW_ROUND', cbNewRound);
- io.on('GE_WAIT_FOR_NEXT_ROUND', cbWaitForNextRound);
- io.on('GE_ANNOUNCE_WINNER', cbAnnounceWinner);
- io.on('GE_NEW_WORD', cbNewWord);
- io.on('GE_UPDATE_SCORE', cbUpdateScore);
- io.on('GE_UPDATE_GUESS', cbUpdateGuess);
-
- io.on('disconnect', () => {
- console.log('Socket disconnected', user);
- io.removeEventListener('S_C_LOGIN', cbSCLogin);
- io.removeEventListener('GE_NEW_GAME', cbNewGame);
- io.removeEventListener('GE_NEW_ROUND', cbNewRound);
- io.removeEventListener('GE_WAIT_FOR_NEXT_ROUND', cbWaitForNextRound);
- io.removeEventListener('GE_ANNOUNCE_WINNER', cbAnnounceWinner);
- io.removeEventListener('GE_NEW_WORD', cbNewWord);
- io.removeEventListener('GE_UPDATE_SCORE', cbUpdateScore);
- io.removeEventListener('GE_UPDATE_GUESS', cbUpdateGuess);
- setCurrentUser(null);
- });
- });
- // Currently adding this line to prevent link check fails as setRoom is unused.
- // Once Rooms feature is implemented, this shall be used
- setRoom(room);
-
- setSocketIO(io);
- } else {
- console.log('playerNickname is null');
- }
- }, [playerNickname]);
-
- const cbNewWord = (word) => {
- console.log('EVENT GE_NEW_WORD');
- setLiveMessage('');
- setDrawWord(word);
- setShowGuessBox(false);
- setMessageLog((messageLog) => [
- ...messageLog,
- "msgSystemImp!!!It's your turn, Draw!"
- ]);
- setLiveMessage("msgSystemImp!!!It's your turn, Draw!");
- };
-
- const cbAnnounceWinner = ({ previousWord, winners }) => {
- console.log('EVENT GE_ANNOUNCE_WINNER');
- setShowGuessBox(false);
- setLiveMessage('');
- setWinners(winners);
- setPreviousWord(previousWord);
- console.log('Announce Winner');
- setShowGuessBox(false);
- setDrawWord(null);
- setGameState(GameStateConstants.GAME_STATE_ANNOUNCE_WINNER);
- if (winners) {
- if (winners.length > 1) {
- let winnersString = '';
- winnersString = winners.reduce((accumulator, winner) => {
- if (accumulator) {
- return `${accumulator}, ${winner.name}`;
- } else {
- return winner.name;
- }
- }, '');
- console.log(winnersString);
- setMessageLog((messageLog) => [
- ...messageLog,
- `msgSystemWinner!!!Game Over, And the Winners are ${winnersString}`
- ]);
- } else {
- setMessageLog((messageLog) => [
- ...messageLog,
- `msgSystemWinner!!!Game Over, And the Winner is ${winners[0].name}`
- ]);
- }
- } else {
- setMessageLog((messageLog) => [
- ...messageLog,
- 'msgSystemWinner!!!Game Over, Wait for new game!'
- ]);
- }
- };
-
- const cbWaitForNextRound = ({ previousWord, round, total }) => {
- console.log('EVENT GE_WAIT_FOR_NEW_ROUND');
- setShowGuessBox(false);
- setDrawWord(null);
- setLiveMessage('');
- setPreviousWord(previousWord);
- setRoundInfo({ current: total - round, total });
- setGameState(GameStateConstants.GAME_STATE_WAIT_FOR_NEXT_ROUND);
- setMessageLog((messageLog) => [
- ...messageLog,
- 'msgSystem!!!Round finished, Wait for next round...'
- ]);
- };
-
- const cbNewRound = ({ round, total, currentDrawingUser, startTimestamp }) => {
- console.log('EVENT GE_NEW_ROUND');
- const secondsLeft = Math.min(ROUND_DURATION - ((+new Date() - startTimestamp) / 1000), ROUND_DURATION);
- setRoundDuration(secondsLeft);
- setDrawWord(null);
- setLiveMessage('');
- setGuess('');
- setShowGuessBox(true);
- setDisableGuessBox(false);
- setPreviousWord(null);
- setRoundInfo({ current: total - round + 1, total });
- setGameState(GameStateConstants.GAME_STATE_NEW_ROUND);
- console.log(`New Round starting, Round: ${round}, Total: ${total}`);
- const innerMessage = `${currentDrawingUser.id.split('_')[0]} is drawing. Start guessing!`;
- setMessageLog((messageLog) => [
- ...messageLog,
- `msgSystem!!!New Round starting, Round: ${(total - round + 1)}, Total: ${total}`,
- `msgSystemImp!!!${innerMessage}`
- ]);
- setLiveMessage(`msgSystemImp!!!${innerMessage}`);
- };
-
- const cbNewGame = (roundDuration) => {
- console.log('EVENT GE_NEW_GAME');
- setRoundDuration(roundDuration / 1000);
- setCurrentUser((currentUser) => { return { ...currentUser, score: 0 }; });
- setLiveMessage('');
- setWinners([]);
- setGameState(GameStateConstants.GAME_STATE_NEW_GAME);
- setMessageLog((messageLog) => [
- ...messageLog,
- 'msgSystem!!!New Game starting...'
- ]);
- };
-
- const cbSCLogin = (loggedInUser) => {
- console.log('EVENT S_C_LOGIN');
- setCurrentUser(loggedInUser);
- setMessageLog((messageLog) => [
- ...messageLog,
- 'msgSystem!!!Logged in'
- ]);
- };
-
- const cbUpdateScore = (updatedUserScores) => {
- console.log('EVENT GE_UPDATE_SCORE');
- console.table(updatedUserScores);
- setUserScores(updatedUserScores);
- };
-
- const cbUpdateGuess = (liveMessage) => {
- console.log('EVENT GE_UPDATE_GUESS');
- let message = '';
- if (liveMessage.found) {
- const innerMessage = `${liveMessage.userName} has found the word!`;
- message = `msgSystemFoundWord!!!${innerMessage}`;
- setLiveMessage(message);
- } else {
- setCurrentUser(currentUser => {
- const innerMessage = `[${liveMessage.userName}]: ${liveMessage.guess}`;
- if (liveMessage.userName !== currentUser.name) { message = `msgSystemGuess!!!${innerMessage}`; }
- // The above check doesn't apply to the liveMessage area
- setLiveMessage(`msgSystemGuess!!!${innerMessage}`);
- return currentUser;
- });
- }
- setMessageLog((messageLog) => [...messageLog, message]);
- };
-
- useEffect(() => {
- if (userScores && currentUser) {
- console.log(currentUser);
- const latestUserScore = userScores.find(
- (user) => user.id === currentUser.id
- ).score;
- if (latestUserScore > currentUser.score) {
- console.log('Disable guess box');
- // disable guess box if guess is right
- setDisableGuessBox(true);
- currentUser.score = latestUserScore;
- }
- }
- }, [userScores, currentUser]);
-
- useEffect(() => {
- document.body.addEventListener('touchmove', function (e) {
- // e.preventDefault();
- });
- }, []);
-
- const erd = ElementResizeDetectorMaker();
-
- useEffect(() => {
- erd.listenTo(document.getElementById('canvasContainer'), (element) => {
- console.log('Resize', element.offsetWidth, element.offsetHeight);
- canvasPaperRef.current.style.height = `${element.offsetWidth}px`;
- });
- }, []);
-
- const guessBoxPressed = (e) => {
- if (e.keyCode === 13) {
- // Enter pressed. send it to server
- const currentGuess = e.target.value;
- sendGuessToServer();
- resetGuess();
- setMessageLog((messageLog) => [
- ...messageLog,
- `msgUserGuess!!!${currentUser.name}: ${currentGuess}`
- ]);
- }
- };
-
- const sendGuessToServer = () => {
- console.log('New guess -', currentUser.id, guess);
- socketIO.emit('GE_NEW_GUESS', {
- userId: currentUser.id,
- guess: guess
- });
- };
-
- const resetGuess = () => {
- setGuess('');
- if (keyboardRef.current) {
- keyboardRef.current.setInput('');
- }
- };
-
- const onNicknameAdded = (nickname) => {
- setPlayerNickname(nickname);
- };
-
- const handleColorChange = (color) => {
- setCanvasOptions({
- color: color,
- enabled: canvasOptions.enabled
- });
- };
-
- const handleClearCanvas = () => {
- socketIO.emit('C_S_CLEAR_CANVAS', room);
- };
-
- const renderPlayersIcon = () => {
- return (
-