125 lines
3.3 KiB
JavaScript
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 }; |