Added missing files
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
42d076f216
commit
6e281991b4
73
client/src/Hand.css
Normal file
73
client/src/Hand.css
Normal file
@ -0,0 +1,73 @@
|
||||
.Hand {
|
||||
display: flex;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
height: 10.5rem;
|
||||
max-height: 10.5;
|
||||
overflow: visible;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.Hand .CardGroup {
|
||||
display: flex;
|
||||
min-height: calc(7.2em + 0.5em);
|
||||
justify-items: space-between;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.Hand .Cards {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
vertical-align: bottom;
|
||||
padding: 0.5em;
|
||||
box-sizing: border-box;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.Hand .Stack {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Hand .Stack:not(:first-child) {
|
||||
margin-left: -3.5em;
|
||||
transition: margin-left 1s ease-in-out 0.25s;
|
||||
}
|
||||
|
||||
.Hand .Stack > * {
|
||||
transition: margin-left 1s ease-in-out 0.25s, margin-right 1s ease-in-out 0.25s;
|
||||
}
|
||||
|
||||
.Hand .Stack > *:not(:first-child) {
|
||||
margin-left: -4em;
|
||||
}
|
||||
|
||||
.Hand .Placard:hover {
|
||||
filter: brightness(105%);
|
||||
}
|
||||
|
||||
.Hand .Development:hover {
|
||||
filter: brightness(150%);
|
||||
}
|
||||
|
||||
.Hand .Development.Selected {
|
||||
filter: brightness(150%);
|
||||
top: -1em;
|
||||
}
|
||||
|
||||
.Hand .Development {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 4.9em;
|
||||
height: 7.2em;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
margin: 0.25em;
|
||||
cursor: pointer;
|
||||
}
|
141
client/src/Hand.js
Normal file
141
client/src/Hand.js
Normal file
@ -0,0 +1,141 @@
|
||||
import React, { useContext, useState, useMemo, useRef, useEffect } from "react";
|
||||
import equal from "fast-deep-equal";
|
||||
|
||||
import { Resource } from './Resource.js';
|
||||
import { Placard } from './Placard.js';
|
||||
import { GlobalContext } from './GlobalContext.js';
|
||||
import { assetsPath } from "./Common.js";
|
||||
import "./Hand.css";
|
||||
|
||||
const Development = ({type, card, onClick}) => {
|
||||
return (
|
||||
<div className={`Development ${card.played ? 'Selected' : ''}`}
|
||||
onClick={onClick}
|
||||
style={{
|
||||
backgroundImage:`url(${assetsPath}/gfx/card-${type}.png)`
|
||||
}}/>
|
||||
);
|
||||
};
|
||||
|
||||
const Hand = ({buildActive, setBuildActive, setCardActive}) => {
|
||||
const { ws } = useContext(GlobalContext);
|
||||
const [priv, setPriv] = useState(undefined);
|
||||
const [color, setColor] = useState(undefined);
|
||||
const [turn, setTurn] = useState(undefined);
|
||||
const [longestRoad, setLongestRoad] = useState(undefined);
|
||||
const [largestArmy, setLargestArmy] = useState(undefined);
|
||||
const [development, setDevelopment] = useState([]);
|
||||
|
||||
const fields = useMemo(() => [
|
||||
'private', 'turn', 'color', 'longestRoad', 'largestArmy'
|
||||
], []);
|
||||
const onWsMessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
switch (data.type) {
|
||||
case 'game-update':
|
||||
console.log(`hand - game-update: `, data.update);
|
||||
if ('private' in data.update && !equal(priv, data.update.private)) {
|
||||
setPriv(data.update.private);
|
||||
}
|
||||
if ('turn' in data.update && !equal(turn, data.update.turn)) {
|
||||
setTurn(data.update.turn);
|
||||
}
|
||||
if ('color' in data.update && color !== data.update.color) {
|
||||
setColor(data.update.color);
|
||||
}
|
||||
if ('longestRoad' in data.update && longestRoad !== data.update.longestRoad) {
|
||||
setLongestRoad(data.update.longestRoad);
|
||||
}
|
||||
if ('largestArmy' in data.update && largestArmy !== data.update.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]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!priv) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cardClicked = (card) => {
|
||||
setCardActive(card);
|
||||
}
|
||||
|
||||
const stacks = {};
|
||||
priv.development.forEach(card =>
|
||||
(card.type in stacks)
|
||||
? stacks[card.type].push(card)
|
||||
: stacks[card.type] = [card]);
|
||||
|
||||
const development = [];
|
||||
for (let type in stacks) {
|
||||
const cards = stacks[type]
|
||||
.sort((A, B) => {
|
||||
if (A.played) {
|
||||
return -1;
|
||||
}
|
||||
if (B.played) {
|
||||
return +1;
|
||||
}
|
||||
return 0;
|
||||
}).map(card => <Development
|
||||
onClick={() => cardClicked(card)}
|
||||
card={card}
|
||||
key={`${type}-${card.card}`}
|
||||
type={`${type}-${card.card}`}/>);
|
||||
development.push(<div key={type} className="Stack">{ cards }</div>);
|
||||
}
|
||||
setDevelopment(development);
|
||||
}, [priv, setDevelopment, setCardActive]);
|
||||
|
||||
if (!priv) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return <div className="Hand">
|
||||
<div className="CardGroup">
|
||||
<Resource type="wood" count={priv.wood}/>
|
||||
<Resource type="wheat" count={priv.wheat}/>
|
||||
<Resource type="stone" count={priv.stone}/>
|
||||
<Resource type="brick" count={priv.brick}/>
|
||||
<Resource type="sheep" count={priv.sheep}/>
|
||||
</div>
|
||||
<div className="CardGroup">
|
||||
{ development }
|
||||
</div>
|
||||
{ longestRoad && longestRoad === color &&
|
||||
<Placard
|
||||
type='longest-road'
|
||||
/>
|
||||
}
|
||||
{ largestArmy && largestArmy === color &&
|
||||
<Placard
|
||||
type='largest-army'
|
||||
/>
|
||||
}
|
||||
<Placard className="BuildCard"
|
||||
{...{buildActive, setBuildActive}}
|
||||
disabled={!turn || !turn.roll}
|
||||
type={color}/>
|
||||
</div>;
|
||||
}
|
||||
|
||||
export { Hand };
|
Loading…
x
Reference in New Issue
Block a user