App.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import React from 'react';
  2. import { createGame, gameInfo, joinGame, getGuesses, sendGuess } from "./services/ggsh.service";
  3. import GamePanel from "./components/game-panel.component";
  4. import ApiInfo from "./components/api-info.component";
  5. import PlayerScores from "./components/player-scores.component";
  6. import RoundSummary from './components/round-summary.component';
  7. import './App.css';
  8. import PreGame from './components/pre-game.component';
  9. const LOADING = "LOADING"; // Application is loading
  10. const PRE_GAME = "PREGAME"; // Game is not yet started
  11. const PRE_ROUND = "PREROUND"; // Game is started or joined, but not playing yet
  12. const IN_ROUND = "INROUND"; // Actively playing
  13. const POST_ROUND = "POSTROUND"; // Round has finished
  14. const POST_GAME = "POSTGAME"; // Game has finished
  15. const ERROR = "ERROR"; // Error state
  16. class Game extends React.Component {
  17. constructor(props) {
  18. super(props);
  19. this.state = {
  20. gameState: PRE_GAME,
  21. playerName: null,
  22. gameId: null,
  23. currentRound: null,
  24. targetPoint: null,
  25. selectedPoint: null,
  26. lastScore: null,
  27. totalScore: null,
  28. players: null,
  29. }
  30. }
  31. async handleCreateGame() {
  32. this.setState({ gameState: LOADING });
  33. const { playerName } = this.state;
  34. const gameId = await createGame(playerName, 300);
  35. this.setState({ gameId });
  36. // TODO transition to a pre-round state
  37. await this.updateRoundState();
  38. }
  39. async handleJoinGame() {
  40. this.setState({ gameState: LOADING });
  41. const { gameId, playerName } = this.state;
  42. await joinGame(gameId, playerName);
  43. // TODO transition to a pre-round state
  44. await this.updateRoundState();
  45. }
  46. async updateRoundState() {
  47. this.setState({ gameState: LOADING })
  48. const { gameId, playerName } = this.state;
  49. const { currentRound } = await getGuesses(gameId, playerName);
  50. const { coords, players } = await gameInfo(gameId);
  51. if (currentRound) {
  52. const targetPoint = coords[currentRound];
  53. this.setState({
  54. gameState: IN_ROUND,
  55. currentRound,
  56. targetPoint,
  57. selectedPoint: null,
  58. players,
  59. });
  60. } else {
  61. this.setState({ gameState: POST_GAME, players });
  62. }
  63. }
  64. async handleSubmitGuess() {
  65. const {
  66. gameId,
  67. playerName,
  68. currentRound,
  69. selectedPoint
  70. } = this.state;
  71. this.setState({ gameState: LOADING });
  72. const { score, totalScore } = await sendGuess(gameId, playerName, currentRound, selectedPoint);
  73. this.setState({
  74. gameState: POST_ROUND,
  75. lastScore: score,
  76. totalScore
  77. });
  78. }
  79. render() {
  80. const { gameState } = this.state;
  81. switch (gameState) {
  82. case LOADING:
  83. return <p>Loading...</p>
  84. case PRE_GAME:
  85. const { gameId, playerName } = this.state;
  86. return <PreGame
  87. onCreateGame={() => this.handleCreateGame()}
  88. onJoinGame={() => this.handleJoinGame()}
  89. onChangeGameId={({ target }) => this.setState({gameId: target.value.trim()})}
  90. onChangePlayerName={({ target }) => this.setState({playerName: target.value.trim()})}
  91. gameId={gameId || ""}
  92. playerName={playerName || ""}
  93. />
  94. case PRE_ROUND:
  95. return <p>TODO!</p>
  96. case IN_ROUND:
  97. const { targetPoint, selectedPoint } = this.state;
  98. return <GamePanel
  99. onSelectPoint={latLng => this.setState({selectedPoint: latLng})}
  100. onSubmitGuess={() => this.handleSubmitGuess()}
  101. streetViewPoint={targetPoint}
  102. selectedPoint={selectedPoint}
  103. />
  104. case POST_ROUND:
  105. const { currentRound, lastScore, totalScore } = this.state;
  106. return <RoundSummary
  107. roundNum={currentRound}
  108. score={lastScore}
  109. totalScore={totalScore}
  110. onAdvanceState={() => this.updateRoundState()}
  111. buttonText={currentRound === "5" ? "View Summary" : "Next Round"}
  112. />
  113. case POST_GAME:
  114. const { players } = this.state;
  115. return <PlayerScores
  116. players={players}
  117. onReturnToStart={() => this.setState({ gameState: PRE_GAME })}
  118. />
  119. case ERROR:
  120. return <p>Application encountered unrecoverable error, please refresh the page.</p>
  121. default:
  122. this.setState({ gameState: ERROR });
  123. return <p>Application state is inconsistent, please refresh and rejoin your previous game.</p>
  124. }
  125. }
  126. }
  127. const App = () => {
  128. return (
  129. <div className="App" style={{
  130. display: "flex",
  131. flexDirection: "column",
  132. justifyContent: "space-between",
  133. height: "100vh",
  134. }}>
  135. <div>
  136. <p>TerrAssumptions!</p>
  137. <hr/>
  138. </div>
  139. <Game style={{flex: 1}}/>
  140. <div>
  141. <hr/>
  142. <ApiInfo/>
  143. </div>
  144. </div>
  145. );
  146. }
  147. export default App;