1
0
James Ketrenos b66e1fb6e5 Font tweaks and Trade layout
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
2022-03-16 17:13:59 -07:00

196 lines
6.3 KiB
JavaScript

import React, { useState, useEffect, useContext, useRef, useMemo, useCallback } from "react";
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import equal from "fast-deep-equal";
import "./Actions.css";
import { PlayerName } from './PlayerName.js';
import { GlobalContext } from "./GlobalContext.js";
const Actions = ({tradeActive, setTradeActive, buildActive, setBuildActive}) => {
const { ws, gameId, name } = useContext(GlobalContext);
const [state, setState] = useState('lobby');
const [color, setColor] = useState(undefined);
const [priv, setPriv] = useState(undefined);
const [turn, setTurn] = useState({});
const [edit, setEdit] = useState(name);
const [active, setActive] = useState(0);
const fields = useMemo(() => [
'state', 'turn', 'private', 'active', 'color'
], []);
const onWsMessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'game-update':
console.log(`actions - game update`, data.update);
if ('private' in data.update && !equal(data.update.private, priv)) {
setPriv(data.update.private);
}
if ('state' in data.update && data.update.state !== state) {
setState(data.update.state);
}
if ('color' in data.update && data.update.color !== color) {
setColor(data.update.color);
}
if ('name' in data.update && data.update.name !== edit) {
setEdit(data.update.name);
}
if ('turn' in data.update && !equal(data.update.turn, turn)) {
setTurn(data.update.turn);
}
if ('active' in data.update && data.update.active !== active) {
setActive(data.update.active);
}
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]);
const sendMessage = useCallback((data) => {
if (!ws) {
console.warn(`No socket`);
} else {
ws.send(JSON.stringify(data));
}
}, [ws]);
const buildClicked = () => {
setBuildActive(!buildActive);
};
const setName = (update) => {
if (update !== name) {
sendMessage({ type: 'player-name', name: update });
}
setEdit(name);
if (buildActive) setBuildActive(false);
}
const changeNameClick = () => {
setEdit("");
if (buildActive) setBuildActive(false);
}
const discardClick = () => {
const nodes = document.querySelectorAll('.Hand .Resource.Selected'),
discards = { wheat: 0, brick: 0, sheep: 0, stone: 0, wood: 0 };
for (let i = 0; i < nodes.length; i++) {
discards[nodes[i].getAttribute("data-type")]++;
nodes[i].classList.remove('Selected');
}
sendMessage({ type: 'discard', discards });
if (buildActive) setBuildActive(false);
}
const newTableClick = () => {
sendMessage({ type: 'shuffle' });
if (buildActive) setBuildActive(false);
};
const tradeClick = () => {
if (!tradeActive) {
setTradeActive(true);
sendMessage({ type: 'trade' });
} else {
setTradeActive(false);
sendMessage({ type: 'trade', action: 'cancel', offer: undefined });
}
if (buildActive) setBuildActive(false);
}
const rollClick = () => {
sendMessage({ type: 'roll' });
if (buildActive) setBuildActive(false);
}
const passClick = () => {
sendMessage({ type: 'pass' });
if (buildActive) setBuildActive(false);
}
const startClick = () => {
sendMessage({
type: 'set',
field: 'state',
value: 'game-order'
});
if (buildActive) setBuildActive(false);
};
if (!gameId) {
return (<Paper className="Actions"/>);
}
const inLobby = state === 'lobby',
inGame = state === 'normal',
inGameOrder = state === 'game-order',
hasGameOrderRolled = (priv && priv.orderRoll) ? true : false,
hasRolled = (turn && turn.roll) ? true : false,
isTurn = (turn && turn.color === color) ? true : false,
robberActions = (turn && turn.robberInAction),
haveResources = priv ? priv.resources !== 0 : false,
placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')),
placeRoad = placement && turn && turn.actions &&
(turn.actions.indexOf('place-road') !== -1
|| turn.actions.indexOf('place-city') !== -1
|| turn.actions.indexOf('place-settlement') !== -1);
if (tradeActive && (!turn || !turn.actions || turn.actions.indexOf('trade'))) {
setTradeActive(false);
} else if (!tradeActive && turn && turn.actions && turn.actions.indexOf('trade') !== -1) {
setTradeActive(true);
}
return (
<Paper className="Actions">
{ edit === "" && <PlayerName name={name} setName={setName}/> }
<div className="Buttons">
{ name && inLobby && <>
<Button disabled={(color && active >= 2) ? false : true } onClick={startClick}>Start game</Button>
<Button disabled={color ? false : true} onClick={newTableClick}>New table</Button>
<Button disabled={color ? true : false} onClick={changeNameClick}>Change name</Button>
</> }
{ name && !inLobby && <>
<Button disabled={
robberActions ||
(inGame && (!isTurn || hasRolled)) ||
(inGameOrder && hasGameOrderRolled) ||
(!inGame && !inGameOrder)
} onClick={rollClick}>Roll Dice</Button>
<Button disabled={placeRoad || robberActions || !isTurn || !hasRolled || !haveResources} onClick={tradeClick}>Trade</Button>
<Button disabled={placeRoad || robberActions || !isTurn || !hasRolled || !haveResources} onClick={buildClicked}>Build</Button>
<Button disabled={!(turn && turn.roll === 7 && priv && priv.mustDiscard > 0)}onClick={discardClick}>Discard</Button>
<Button disabled={placeRoad || robberActions || !isTurn || !hasRolled} onClick={passClick}>Done</Button>
</> }
{ /* inLobby &&
<Button onClick={quitClick}>Quit</Button>
*/ }
</div>
</Paper>
);
}
export { Actions };