1
0
peddlers-of-ketran/client/src/PlayerList.js
James Ketrenos 222ca2d3c3 Board rendering only occurs once per signature
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
2022-03-12 00:19:54 -08:00

125 lines
3.3 KiB
JavaScript

import React, { useState, useEffect, useContext, useRef } from "react";
import Paper from '@material-ui/core/Paper';
import List from '@material-ui/core/List';
import "./PlayerList.css";
import { PlayerColor } from './PlayerColor.js';
import { MediaControl } from "./MediaControl.js";
import { GlobalContext } from "./GlobalContext.js";
const PlayerList = () => {
const { ws, name } = useContext(GlobalContext);
const [players, setPlayers] = useState({});
const [unselected, setUneslected] = useState([]);
const [state, setState] = useState('lobby');
const [color, setColor] = useState(undefined);
const onWsMessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'game-update':
console.log(`player-list - game update`, data.update);
if ('unselected' in data.update) {
setUneslected(data.update.unselected);
}
if ('players' in data.update) {
let found = false;
for (let key in data.update.players) {
if (data.update.players[key].name === name) {
found = true;
setColor(key);
break;
}
}
if (!found) {
setColor(undefined);
}
setPlayers(data.update.players);
}
if ('state' in data.update && data.update.state !== state) {
setState(data.update.state);
}
break;
default:
break;
}
};
const refWsMessage = useRef(onWsMessage);
useEffect(() => { refWsMessage.current = onWsMessage; });
useEffect(() => {
if (!ws) {
return;
}
const cbMessage = e => refWsMessage.current(e);
ws.addEventListener('message', cbMessage);
return () => {
ws.removeEventListener('message', cbMessage);
}
}, [ws, refWsMessage]);
useEffect(() => {
if (!ws) {
return;
}
ws.send(JSON.stringify({
type: 'get',
fields: [ 'state', 'players', 'unselected' ]
}));
}, [ws]);
const toggleSelected = (key) => {
ws.send(JSON.stringify({
type: 'set',
field: 'color',
value: color === key ? "" : key
}));
}
const playerElements = [];
const inLobby = state === 'lobby';
for (let key in players) {
const item = players[key];
const name = item.name;
const selectable = inLobby && (item.status === 'Not active' || color === key);
playerElements.push(
<div
data-selectable={selectable}
data-selected={key === color}
className="PlayerEntry"
onClick={() => { inLobby && selectable && toggleSelected(key) }}
key={`player-${key}`}>
<PlayerColor color={key}/>
<div className="Name">{name ? name : 'Available' }</div>
{ name && !item.live && <div className="NoNetwork"></div> }
{ name && item.live && <MediaControl peer={name} isSelf={key === color}/> }
{ !name && <div></div> }
</div>
);
}
const waiting = unselected.map((player) => {
return <div className={player === name ? 'Self' : ''} key={player}>
<div>{ player }</div>
<MediaControl peer={player} isSelf={name === player}/>
</div>
})
return (
<Paper className="PlayerList">
<List className="PlayerSelector">
{ playerElements }
</List>
<div className="Unselected">
{ waiting }
</div>
</Paper>
);
}
export { PlayerList };