import React, { useState, useEffect, useContext, useRef } from "react"; import Paper from "@mui/material/Paper"; import List from "@mui/material/List"; import "./PlayerList.css"; import { PlayerColor } from "./PlayerColor"; import { MediaAgent, MediaControl } from "./MediaControl"; import { GlobalContext } from "./GlobalContext"; /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ const PlayerList: React.FC = () => { const { ws, name, sendJsonMessage } = useContext(GlobalContext); const [players, setPlayers] = useState<{ [key: string]: any }>({}); const [unselected, setUneslected] = useState([]); const [state, setState] = useState("lobby"); const [color, setColor] = useState(undefined); const [peers, setPeers] = useState<{ [key: string]: any }>({}); const onWsMessage = (event: MessageEvent) => { 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 (const 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: MessageEvent) => refWsMessage.current(e); ws.addEventListener("message", cbMessage); return () => { ws.removeEventListener("message", cbMessage); }; }, [ws, refWsMessage]); useEffect(() => { if (!sendJsonMessage) { return; } sendJsonMessage({ type: "get", fields: ["state", "players", "unselected"], }); }, [ws]); const toggleSelected = (key: string) => { ws!.send( JSON.stringify({ type: "set", field: "color", value: color === key ? "" : key, }) ); }; const playerElements: React.ReactElement[] = []; const inLobby = state === "lobby"; const sortedPlayers: any[] = []; for (const key in players) { sortedPlayers.push(players[key]); } const sortPlayers = (A: any, B: any) => { /* active player first */ if (A.name === name) { return -1; } if (B.name === name) { return +1; } /* Sort active players first */ if (A.name && !B.name) { return -1; } if (B.name && !A.name) { return +1; } /* Ohterwise, sort by color */ return A.color.localeCompare(B.color); }; sortedPlayers.sort(sortPlayers); /* Array of just names... */ unselected.sort((A, B) => { /* active player first */ if (A === name) { return -1; } if (B === name) { return +1; } /* Then sort alphabetically */ return A.localeCompare(B); }); const videoClass = sortedPlayers.length <= 2 ? "Medium" : "Small"; sortedPlayers.forEach((player) => { const playerName = player.name; const selectable = inLobby && (player.status === "Not active" || color === player.color); playerElements.push(
{ inLobby && selectable && toggleSelected(player.color); }} key={`player-${player.color}`} >
{playerName ? playerName : "Available"}
{playerName && !player.live &&
}
{playerName && player.live && ( )} {!playerName &&
}
); }); const waiting = unselected.map((player) => { return (
{player}
); }); return ( {playerElements} {unselected && unselected.length !== 0 && (
In lobby
{waiting}
)}
); }; export { PlayerList };