|
@@ -1,10 +1,16 @@
|
|
|
-import React from "react";
|
|
|
+import React, { useState } from "react";
|
|
|
import styled from "styled-components";
|
|
|
import ClickToCopy from "../util/ClickToCopy";
|
|
|
import Button from "../util/Button";
|
|
|
+import Loading from "../util/Loading";
|
|
|
+import PlayerNameInput from "../screens/PreGame/PlayerNameInput";
|
|
|
+import usePlayerScores from "../../hooks/usePlayerScores";
|
|
|
+import { joinGame } from "../../domain/GGSHService";
|
|
|
+
|
|
|
+const InfoContainer = styled.div`
|
|
|
+ flex: 3;
|
|
|
+ align-self: center;
|
|
|
|
|
|
-const Container = styled.div`
|
|
|
- flex: 1;
|
|
|
display: flex;
|
|
|
flex-flow: column nowrap;
|
|
|
justify-content: center;
|
|
@@ -15,26 +21,108 @@ const Label = styled.span`
|
|
|
padding: 0.2em;
|
|
|
`
|
|
|
|
|
|
-const StartButton = styled(Button)`
|
|
|
+const FormButton = styled(Button)`
|
|
|
padding: 1em;
|
|
|
margin: 0.2em;
|
|
|
margin-top: 0.3em;
|
|
|
`
|
|
|
|
|
|
+const PlayerListContainer = styled.div`
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ display: flex;
|
|
|
+ flex-flow: column nowrap;
|
|
|
+ justify-content: flex-start;
|
|
|
+ align-items: flex-start;
|
|
|
+
|
|
|
+ border-left: 2px solid #777;
|
|
|
+ height: 100%;
|
|
|
+ padding-left: 1rem;
|
|
|
+`
|
|
|
+
|
|
|
+const PlayerList = styled.ul`
|
|
|
+`
|
|
|
+
|
|
|
+const PlayerName = styled.li`
|
|
|
+`
|
|
|
+
|
|
|
+const PageContainer = styled.div`
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-flow: row nowrap;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-start;
|
|
|
+`
|
|
|
+
|
|
|
const getUrl = gameId => {
|
|
|
const u = new URL(window.location.href);
|
|
|
u.searchParams.append("join", gameId);
|
|
|
return u.href;
|
|
|
}
|
|
|
|
|
|
-const PreRound = ({ gameId, playerName, onStart }) => (
|
|
|
- <Container>
|
|
|
+const JoinedInfo = ({ gameId, playerName, onStart }) => (
|
|
|
+ <InfoContainer>
|
|
|
<Label>Playing as {playerName}</Label>
|
|
|
<Label>Game Code: <ClickToCopy text={gameId} /></Label>
|
|
|
<Label>Or, send the following link:</Label>
|
|
|
<Label><ClickToCopy text={getUrl(gameId)} /></Label>
|
|
|
- <StartButton onClick={onStart}>Start Game</StartButton>
|
|
|
- </Container>
|
|
|
+ <FormButton onClick={onStart}>Start Game</FormButton>
|
|
|
+ </InfoContainer>
|
|
|
+);
|
|
|
+
|
|
|
+const UnjoinedInfo = ({ gameId, onGameJoined }) => {
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
+ const [failed, setFailed] = useState(false);
|
|
|
+ const [playerName, setPlayerName] = useState(null);
|
|
|
+
|
|
|
+ if (loading) {
|
|
|
+ return <InfoContainer><Loading/></InfoContainer>
|
|
|
+ }
|
|
|
+
|
|
|
+ const onJoinGame = async () => {
|
|
|
+ // TODO would like to support re-joining a game you left
|
|
|
+ setLoading(true);
|
|
|
+ try {
|
|
|
+ await joinGame(gameId, playerName);
|
|
|
+ } catch (err) {
|
|
|
+ // failed to join the game
|
|
|
+ setFailed(true);
|
|
|
+ setLoading(false);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ setFailed(false);
|
|
|
+ onGameJoined({ gameId, playerName });
|
|
|
+ };
|
|
|
+ const cannotJoinGame = !playerName || playerName.length === 0;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <InfoContainer>
|
|
|
+ {failed && <Label>Failed to join the game! Maybe try a different name?</Label>}
|
|
|
+ <Label>Joining {gameId}...</Label>
|
|
|
+ <PlayerNameInput playerName={playerName} onChangePlayerName={({ target }) => setPlayerName(target.value)}/>
|
|
|
+ <FormButton onClick={onJoinGame} disabled={cannotJoinGame}>Join Game</FormButton>
|
|
|
+ </InfoContainer>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const PreRound = ({ gameId, playerName, joined, onGameJoined, onStart }) => (
|
|
|
+ <PageContainer>
|
|
|
+ {
|
|
|
+ joined
|
|
|
+ ? <JoinedInfo gameId={gameId} playerName={playerName} onStart={onStart}/>
|
|
|
+ : <UnjoinedInfo gameId={gameId} onGameJoined={onGameJoined}/>
|
|
|
+ }
|
|
|
+ <PlayerListContainer>
|
|
|
+ <Label>Players</Label>
|
|
|
+ <PlayerList>
|
|
|
+ {
|
|
|
+ usePlayerScores(gameId)?.map(({ name }) => (
|
|
|
+ <PlayerName key={name}>{name}</PlayerName>
|
|
|
+ ))
|
|
|
+ }
|
|
|
+ </PlayerList>
|
|
|
+ </PlayerListContainer>
|
|
|
+ </PageContainer>
|
|
|
);
|
|
|
|
|
|
export default PreRound;
|