123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import React from 'react';
- import { getGoogleApiKey, createGame, gameInfo, joinGame, getGuesses, sendGuess } from "./services/ggsh.service";
- import GamePanel from "./components/game-panel.component";
- import ApiInfo from "./components/api-info.component";
- import PlayerScores from "./components/player-scores.component";
- import RoundSummary from './components/round-summary.component';
- import PreGame from './components/pre-game.component';
- import PreRound from './components/pre-round.component';
- import './App.css';
- const LOADING = "LOADING"; // Application is loading
- const PRE_GAME = "PREGAME"; // Game is not yet started
- const PRE_ROUND = "PREROUND"; // Game is started or joined, but not playing yet
- const IN_ROUND = "INROUND"; // Actively playing
- const POST_ROUND = "POSTROUND"; // Round has finished
- const POST_GAME = "POSTGAME"; // Game has finished
- const ERROR = "ERROR"; // Error state
- class Game extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- googleApiKey: null,
- gameState: LOADING,
- playerName: null,
- gameId: null,
- currentRound: null,
- targetPoint: null,
- selectedPoint: null,
- lastScore: null,
- totalScore: null,
- players: null,
- roundTimer: null,
- }
- }
- // TODO error handling throughout - at the moment it assumes all calls always succeed
- async componentDidMount() {
- const googleApiKey = await getGoogleApiKey();
- this.setState({ googleApiKey, gameState: PRE_GAME });
- }
- async handleCreateGame() {
- this.setState({ gameState: LOADING });
- const { playerName } = this.state;
- const gameId = await createGame(playerName, 300);
- this.setState({ gameState: PRE_ROUND, gameId });
- }
- async handleJoinGame() {
- this.setState({ gameState: LOADING });
- const { gameId, playerName } = this.state;
- await joinGame(gameId, playerName);
- this.setState({ gameState: PRE_ROUND });
- }
- async updateRoundState() {
- this.setState({ gameState: LOADING })
- const { gameId, playerName } = this.state;
- const { currentRound } = await getGuesses(gameId, playerName);
- const { coords, players, timer } = await gameInfo(gameId);
- if (currentRound) {
- const targetPoint = coords[currentRound];
- this.setState({
- gameState: IN_ROUND,
- currentRound,
- targetPoint,
- selectedPoint: null,
- players,
- roundTimer: timer,
- });
- } else {
- this.setState({ gameState: POST_GAME, players });
- }
- }
- async handleSubmitGuess() {
- this.setState({ gameState: LOADING });
- const {
- gameId,
- playerName,
- currentRound,
- selectedPoint
- } = this.state;
- if (selectedPoint) {
- const { score, totalScore } = await sendGuess(gameId, playerName, currentRound, selectedPoint);
- this.setState({
- gameState: POST_ROUND,
- lastScore: score,
- totalScore
- });
- } else {
- const { score, totalScore } = await sendGuess(gameId, playerName, currentRound, { timeout: true });
- this.setState({
- gameState: POST_ROUND,
- lastScore: score,
- totalScore
- });
- }
- }
- render() {
- const {
- googleApiKey,
- gameState,
- gameId,
- playerName,
- targetPoint,
- selectedPoint,
- } = this.state;
- switch (gameState) {
- case LOADING:
- return <p>Loading...</p>
- case PRE_GAME:
- return <PreGame
- onCreateGame={() => this.handleCreateGame()}
- onJoinGame={() => this.handleJoinGame()}
- onChangeGameId={({ target }) => this.setState({gameId: target.value.trim()})}
- onChangePlayerName={({ target }) => this.setState({playerName: target.value.trim()})}
- gameId={gameId || ""}
- playerName={playerName || ""}
- />
- case PRE_ROUND:
- return <PreRound
- gameId={gameId}
- playerName={playerName}
- onStart={() => this.updateRoundState()}
- />
- case IN_ROUND:
- const { roundTimer } = this.state;
- return <GamePanel
- googleApiKey={googleApiKey}
- onSelectPoint={latLng => this.setState({selectedPoint: latLng})}
- onSubmitGuess={() => this.handleSubmitGuess()}
- streetViewPoint={targetPoint}
- selectedPoint={selectedPoint}
- roundSeconds={roundTimer}
- onTimeout={() => this.handleSubmitGuess()}
- />
- case POST_ROUND:
- const { currentRound, lastScore, totalScore } = this.state;
- return <RoundSummary
- googleApiKey={googleApiKey}
- roundNum={currentRound}
- score={lastScore}
- totalScore={totalScore}
- onAdvanceState={() => this.updateRoundState()}
- buttonText={currentRound === "5" ? "View Summary" : "Next Round"}
- selectedPoint={selectedPoint}
- targetPoint={targetPoint}
- />
- case POST_GAME:
- const { players } = this.state;
- return <PlayerScores
- players={players}
- onReturnToStart={() => this.setState({ gameState: PRE_GAME })}
- />
- case ERROR:
- return <p>Application encountered unrecoverable error, please refresh the page.</p>
- default:
- this.setState({ gameState: ERROR });
- return <p>Application state is inconsistent, please refresh and rejoin your previous game.</p>
- }
- }
- }
- const App = () => {
- return (
- <div className="App" style={{
- display: "flex",
- flexDirection: "column",
- justifyContent: "space-between",
- height: "100vh",
- }}>
- <div>
- <p>TerrAssumptions!</p>
- <hr/>
- </div>
- <Game style={{flex: 1}}/>
- <div>
- <hr/>
- <ApiInfo/>
- </div>
- </div>
- );
- }
- export default App;
|