diff --git a/client/src/App.css b/client/src/App.css index 83988f5..22150fb 100755 --- a/client/src/App.css +++ b/client/src/App.css @@ -1,6 +1,5 @@ body { font-family: 'Droid Sans', 'Arial Narrow', Arial, sans-serif; - background-color: black; } #root { diff --git a/client/src/App.js b/client/src/App.js index d1d9c33..b20a8d5 100755 --- a/client/src/App.js +++ b/client/src/App.js @@ -13,10 +13,10 @@ import history from "./history.js"; import { GlobalContext } from "./GlobalContext.js"; import { PingPong } from "./PingPong.js"; import { PlayerList } from "./PlayerList.js"; -import { PlayerName } from "./PlayerName.js"; import { Chat } from "./Chat.js"; import { MediaAgent } from "./MediaControl.js"; import { Board } from "./Board.js"; +import { Actions } from "./Actions.js"; import "./App.css"; @@ -193,18 +193,19 @@ const Table = () => { console.log(`Loaded: ${loaded}`); - return + return
-
+
todo: player's hand
- { loaded && name === "" && } { name !== "" && } { name !== "" && } + { loaded && }
; diff --git a/client/src/Chat.css b/client/src/Chat.css index 3c9f0f0..20e3850 100644 --- a/client/src/Chat.css +++ b/client/src/Chat.css @@ -5,6 +5,7 @@ padding: 0.5em; position: relative; overflow: hidden; + margin: 0.25rem 0.25rem 0.25rem 0; } .ChatList { diff --git a/client/src/MediaControl.js b/client/src/MediaControl.js index 0fa3bbd..534fcec 100644 --- a/client/src/MediaControl.js +++ b/client/src/MediaControl.js @@ -304,7 +304,7 @@ const MediaAgent = () => { }, [peers, name, setPeers, stream]); useEffect(() => { - if (!ws) { + if (!ws || !name) { return; } @@ -338,7 +338,7 @@ const MediaAgent = () => { console.error(error); console.log("Access denied for audio/video"); }); - }, [ws, setStream]); + }, [ws, setStream, name]); if (!ws) { return <>; diff --git a/client/src/PlayerList.css b/client/src/PlayerList.css index 38518c9..0e72de1 100644 --- a/client/src/PlayerList.css +++ b/client/src/PlayerList.css @@ -4,6 +4,7 @@ padding: 0.5em; user-select: none; flex-direction: column; + margin: 0.25rem 0.25rem 0.25rem 0; } .PlayerList .Name { @@ -33,6 +34,11 @@ flex-direction: column; align-items: center; margin: 0.25rem; + padding: 0.25rem; +} + +.PlayerList .Unselected .Self { + background-color: rgba(255, 255, 0, 0.5); } .PlayerList .PlayerSelector .PlayerColor { diff --git a/client/src/PlayerList.js b/client/src/PlayerList.js index 2bea0a6..fa690e6 100644 --- a/client/src/PlayerList.js +++ b/client/src/PlayerList.js @@ -18,10 +18,10 @@ const PlayerList = () => { const data = JSON.parse(event.data); switch (data.type) { case 'game-update': - if (data.update.unselected) { + if ('unselected' in data.update) { setUneslected(data.update.unselected); } - if (data.update.players) { + if ('players' in data.update) { let found = false; for (let key in data.update.players) { if (data.update.players[key].name === name) { @@ -35,7 +35,7 @@ const PlayerList = () => { } setPlayers(data.update.players); } - if (data.update.state) { + if ('state' in data.update && data.update.state !== state) { setState(data.update.state); } break; @@ -100,7 +100,7 @@ const PlayerList = () => { } const waiting = unselected.map((player) => { - return
+ return
{ player }
diff --git a/client/src/PlayerName.js b/client/src/PlayerName.js index 1494a4f..00012ce 100644 --- a/client/src/PlayerName.js +++ b/client/src/PlayerName.js @@ -1,61 +1,19 @@ import React, { useState, useEffect, useContext, useRef } from "react"; import "./PlayerName.css"; -import Paper from '@material-ui/core/Paper'; import TextField from '@material-ui/core/TextField'; import Button from '@material-ui/core/Button'; -import { GlobalContext } from "./GlobalContext.js"; - -const PlayerName = () => { - const global = useContext(GlobalContext); - const [name, setName] = useState(global.name ? global.name : ""); - const [error, setError] = useState(""); - - const onWsMessage = (event) => { - const data = JSON.parse(event.data); - switch (data.type) { - case 'game-update': - if ('name' in data.update && data.update.name !== name) { - setName(data.update.name); - } - break; - - case 'player-name': - if ('error' in data) { - setError(data.error); - } - break; - - default: - break; - } - }; - const refWsMessage = useRef(onWsMessage); - - useEffect(() => { refWsMessage.current = onWsMessage; }); - - useEffect(() => { - if (!global.ws) { - return; - } - const cbMessage = e => refWsMessage.current(e); - global.ws.addEventListener('message', cbMessage); - return () => { - global.ws.removeEventListener('message', cbMessage); - } - }, [global.ws, refWsMessage]); +const PlayerName = ({ name, setName }) => { + const [edit, setEdit] = useState(name); const sendName = () => { - if (name !== global.name && name !== "") { - if (error) { - setError(""); - } - global.ws.send(JSON.stringify({ type: 'player-name', name })); + if (edit !== name) { + setName(edit); } } const nameChange = (event) => { - setName(event.target.value); + setEdit(event.target.value); } const nameKeyPress = (event) => { @@ -65,17 +23,16 @@ const PlayerName = () => { } return ( - - { error !== "" &&
Error: {error}
} +
- - + +
); }; diff --git a/server/routes/games.js b/server/routes/games.js index 78753d3..4c69451 100755 --- a/server/routes/games.js +++ b/server/routes/games.js @@ -483,7 +483,8 @@ const getSession = (game, reqSession) => { name: undefined, color: undefined, player: undefined, - lastActive: Date.now() + lastActive: Date.now(), + live: true }; } @@ -508,7 +509,9 @@ const getSession = (game, reqSession) => { } session.lastActive = Date.now(); + session.live = true; if (session.player) { + session.player.live = true; session.player.lastActive = session.lastActive; } @@ -847,7 +850,7 @@ const setPlayerName = (game, session, name) => { } } - let message; + let message, hasAudio = false; if (!session.name) { message = `A new player has entered the lobby as ${name}.`; @@ -860,7 +863,8 @@ const setPlayerName = (game, session, name) => { message = `${name} has rejoined the lobby.`; } session.name = name; - if (session.ws && id in audio) { + if (session.ws && (id in audio) && session.name in audio[id]) { + hasAudio = true; part(audio[id], session, game.id); } } else { @@ -874,14 +878,27 @@ const setPlayerName = (game, session, name) => { if (!session.color) { console.log(`Adding ${session.name} to the unselected`); - game.unselected.push(session); } - if (session.ws) { + if (session.ws && hasAudio) { join(audio[id], session, game.id); } console.log(message); addChatMessage(game, null, message); + + session.live = true; + if (session.player) { + session.player.live = true; + } + + /* Rebuild the unselected list */ + game.unselected = []; + for (let id in game.sessions) { + if (!game.sessions[id].color && game.sessions[id].name) { + game.unselected.push(game.sessions[id]); + } + } + return undefined; } @@ -957,6 +974,8 @@ const setPlayerColor = (game, session, color) => { session.player.status = `Active`; session.player.lastActive = Date.now(); session.color = color; + session.live = true; + session.player.live = true; game.players[color].name = session.name; /* Rebuild the unselected list */ @@ -2896,7 +2915,7 @@ const departLobby = (game, session, color) => { update.unselected = getFilteredUnselected(game); if (session.player) { - session.player.live = true; + session.player.live = false; update.players = game.players; } @@ -3524,6 +3543,7 @@ const filterGameForPlayer = (game, session) => { reducedGame.unselected = getFilteredUnselected(game); return Object.assign(reducedGame, { + live: true, timestamp: Date.now(), status: session.error ? session.error : "success", name: session.name,