1
0
peddlers-of-ketran/client/src/SelectPlayer.tsx

95 lines
2.5 KiB
TypeScript

import React, { useState, useEffect, useContext, useRef, useMemo, useCallback } from "react";
import Paper from "@mui/material/Paper";
import equal from "fast-deep-equal";
import { PlayerColor } from "./PlayerColor";
import "./SelectPlayer.css";
import { GlobalContext } from "./GlobalContext";
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
const SelectPlayer: React.FC = () => {
const { ws } = useContext(GlobalContext);
const [turn, setTurn] = useState<any>(undefined);
const [color, setColor] = useState<string | undefined>(undefined);
const fields = useMemo(() => ["turn", "color"], []);
const onWsMessage = (event: MessageEvent) => {
const data = JSON.parse(event.data);
switch (data.type) {
case "game-update":
console.log(`select-players - game-update: `, data.update);
if ("turn" in data.update && !equal(turn, data.update.turn)) {
setTurn(data.update.turn);
}
if ("color" in data.update && data.update.color !== color) {
setColor(data.update.color);
}
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 (!ws) {
return;
}
ws.send(
JSON.stringify({
type: "get",
fields,
})
);
}, [ws, fields]);
const playerClick = useCallback(
(event: React.MouseEvent<HTMLDivElement>) => {
ws!.send(
JSON.stringify({
type: "steal-resource",
color: event.currentTarget.getAttribute("data-color"),
})
);
},
[ws]
);
if (!color || !turn || turn.color !== color || !turn.limits || !turn.limits.players) {
return <></>;
}
const list = turn.limits.players.map((item: any) => (
<div className="SelectPlayerItem" onClick={playerClick} data-color={item.color} key={`player-${item.color}`}>
<PlayerColor color={item.color} />
<div>{item.name}</div>
</div>
));
return (
<div className="SelectPlayer">
<Paper>
<div className="Title">Select Player to Steal From</div>
<div className="SelectPlayerList">{list}</div>
</Paper>
</div>
);
};
export { SelectPlayer };