1
0
peddlers-of-ketran/client/src/PlayersStatus.js
James Ketrenos 7bb7c74234 Lots of bug fixes
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
2022-03-15 14:38:57 -07:00

175 lines
5.1 KiB
JavaScript

import React, { useContext, useState, useMemo, useRef, useEffect } from "react";
import equal from "fast-deep-equal";
import "./PlayersStatus.css";
import { BoardPieces } from './BoardPieces.js';
import { Resource } from './Resource.js';
import { PlayerColor } from './PlayerColor.js';
import { Placard } from './Placard.js';
import { GlobalContext } from './GlobalContext.js';
const Player = ({ player, onClick, reverse, color,
largestArmy, isSelf, longestRoad }) => {
if (!player) {
return <></>;
}
const developmentCards = player.unplayed
? <Resource label={true} type={'progress-back'}
count={player.unplayed} disabled/>
: undefined;
const resourceCards = player.resources
? <Resource label={true} type={'resource-back'}
count={player.resources} disabled/>
: undefined;
const armyCards = player.army
? <Resource label={true} type={'army-1'} count={player.army} disabled/>
: undefined;
let points = <></>;
if (player.points && reverse) {
points = <><b>{player.points}</b><Resource type={'progress-back'}
count={player.points} disabled/></>;
} else if (player.points) {
points = <><Resource type={'progress-back'} count={player.points}
disabled/><b>{player.points}</b></>;
}
const longestRoadPlacard = longestRoad && longestRoad === color ?
<Placard
disabled
active={false}
type='longest-road'
count={player.longestRoad}
/> : undefined;
const largestArmyPlacard = largestArmy && largestArmy === color ?
<Placard
disabled
active={false}
type='largest-army'
count={player.army}
/> : undefined;
return <div className="Player">
<div className="Who">
<PlayerColor color={color}/>{player.name}
</div>
<div className="What">
{ isSelf &&
<div className="LongestRoad">
Longest road: {player.longestRoad ? player.longestRoad : 0}
</div>
}
<div className="Points">{points}</div>
{ (largestArmy || longestRoad || armyCards || resourceCards || developmentCards) && <>
<div className="Has">
{ !reverse && <>
{ largestArmyPlacard }
{ longestRoadPlacard }
{ !largestArmyPlacard && armyCards }
{ developmentCards }
{ resourceCards }
</> }
{ reverse && <>
{ resourceCards }
{ developmentCards }
{ !largestArmyPlacard && armyCards }
{ longestRoadPlacard }
{ largestArmyPlacard }
</> }
</div>
</> }
</div>
<div className={`${onClick ? 'Normal' : 'Shrunken'}`}>
<BoardPieces onClick={onClick} player={player}/>
</div>
</div>
};
const PlayersStatus = ({ active }) => {
const { ws } = useContext(GlobalContext);
const [players, setPlayers] = useState(undefined);
const [color, setColor] = useState(undefined);
const [largestArmy, setLargestArmy] = useState(undefined);
const [longestRoad, setLongestRoad] = useState(undefined);
const fields = useMemo(() => [
'players', 'color', 'longestRoad', 'largestArmy'
], []);
const onWsMessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'game-update':
console.log(`players-status - game-update: `, data.update);
if ('players' in data.update && !equal(players, data.update.players)) {
setPlayers(data.update.players);
}
if ('color' in data.update && data.update.color !== color) {
setColor(data.update.color);
}
if ('longestRoad' in data.update && data.update.longestRoad !== longestRoad) {
setLongestRoad(data.update.longestRoad);
}
if ('largestArmy' in data.update && data.update.largestArmy !== largestArmy) {
setLargestArmy(data.update.largestArmy);
}
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
}));
}, [ws, fields]);
if (!players) {
return <></>;
}
const buildItem = () => {
console.log(`player-status - build-item`);
}
let elements;
if (active) {
elements = <Player
player={players[color]}
onClick={buildItem}
reverse
largestArmy={largestArmy}
longestRoad={longestRoad}
isSelf={active}
key={`PlayerStatus-${color}`}
color={color}/>;
} else {
elements = Object.getOwnPropertyNames(players)
.filter(key => color !== key)
.map(key => {
return <Player
player={players[key]}
largestArmy={largestArmy}
longestRoad={longestRoad}
key={`PlayerStatus-${key}}`}
color={key}/>;
});
}
return (
<div className={`PlayersStatus ${active ? 'ActivePlayer' : ''}`}>
{ elements }
</div>
);
}
export { PlayersStatus };