123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- import React, { useState } from "react";
- import {
- PRE_GAME,
- PRE_ROUND,
- IN_ROUND,
- POST_ROUND,
- POST_GAME,
- ERROR,
- } from "./GameState";
- import HeaderAndFooter from "./HeaderAndFooter";
- import PreGame from '../screens/PreGame';
- import PreRound from '../screens/PreRound';
- import GamePanel from "../screens/GamePanel";
- import RoundSummary from '../screens/RoundSummary';
- import PlayerScores from "../screens/PlayerScores";
- const initialState = {
- gameState: PRE_GAME,
- gameId: null,
- playerName: null,
- lastRound: null,
- joined: false,
- }
- const extractAndRemoveSearchParam = param => {
- const u = new URL(window.location.href);
- const extracted = u.searchParams.get(param);
- u.searchParams.delete(param);
- window.history.replaceState({}, document.title, u.href);
- return extracted;
- }
- const Game = () => {
- const [ state, rawSetState ] = useState(initialState);
- const setGameState = gameState => rawSetState({ ...state, gameState });
- const setGameStateAnd = (gameState, updates) => rawSetState({ ...state, gameState, ...updates });
- const onGameJoined = ({ gameId, playerName }) => setGameStateAnd(PRE_ROUND, { gameId, playerName, joined: true });
-
- const joinCode = extractAndRemoveSearchParam("join");
- if (joinCode) {
- setGameStateAnd(PRE_ROUND, { gameId: joinCode, joined: false });
- }
- const summaryCode = extractAndRemoveSearchParam("summary");
- if (summaryCode) {
- setGameStateAnd(POST_GAME, { gameId: summaryCode });
- }
- switch (state.gameState) {
- case PRE_GAME:
- return (
- <HeaderAndFooter>
- <PreGame
- initPlayerName={state.playerName}
- onGameJoined={onGameJoined}
- />
- </HeaderAndFooter>
- );
- case PRE_ROUND:
- return (
- <HeaderAndFooter>
- <PreRound
- gameId={state.gameId}
- playerName={state.playerName}
- joined={state.joined}
- onGameJoined={onGameJoined}
- onStart={() => setGameState(IN_ROUND)}
- />
- </HeaderAndFooter>
- );
- case IN_ROUND:
- return <GamePanel
- gameId={state.gameId}
- playerName={state.playerName}
- onRoundEnd={lastRound => setGameStateAnd(POST_ROUND, { lastRound })}
- onGameEnd={() => setGameState(POST_GAME)}
- />
- case POST_ROUND:
- return <RoundSummary
- gameId={state.gameId}
- playerName={state.playerName}
- round={state.lastRound}
- onNext={() => setGameState(IN_ROUND)}
- />
- case POST_GAME:
- return (
- <HeaderAndFooter>
- <PlayerScores
- gameId={state.gameId}
- onReturnToStart={() => setGameStateAnd(PRE_GAME, { gameId: null, joined: false })}
- />
- </HeaderAndFooter>
- );
- case ERROR:
- // TODO - would be nice to hook this into the sub-components, maybe with a HOC?
- return <p>Application encountered unrecoverable error, please refresh the page.</p>
- default:
- setGameState(ERROR);
- return <p>Application state is inconsistent, please refresh and rejoin your previous game.</p>
- }
- }
- export default Game;
|