euchre-live

Euchre web-app for the socially distant family
git clone git://git.alexkarle.com/euchre-live.git
Log | Files | Refs | README | LICENSE

commit dbbf06b5ac760198d83de2cebcb3980bcdb80a74 (patch)
parent cf5347786d32a33e04bc968bfc81f73d05fa1c99
Author: Chris Karle <chriskarle@hotmail.com>
Date:   Sat, 18 Apr 2020 17:54:51 -0400

CardTable, MainHand, HiddenHand

Added new HiddenHand widget that displays a collection of
card backs, add these to other players.

Format of main player sections with info, hands.

Display trump_nominee and position it in front of dealer.

Fixed click bug on MainHand final cards.

Apologies to the reader if my commit messages are far more
dry and uninteresting than my teammate's :-)

Diffstat:
Massets/app.js | 2+-
Massets/app.scss | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Massets/components/CardTable.js | 100++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Aassets/components/HiddenHand.js | 34++++++++++++++++++++++++++++++++++
Massets/components/MainHand.js | 2+-
5 files changed, 199 insertions(+), 32 deletions(-)

diff --git a/assets/app.js b/assets/app.js @@ -63,7 +63,7 @@ class App extends React.Component { fc3.send(JSON.stringify({ action:'join_game', player_name: 'Dana', game_id: initialTable })); fc1.send(JSON.stringify({ action:'take_seat', seat: 0 })); fc2.send(JSON.stringify({ action:'take_seat', seat: 1 })); - fc3.send(JSON.stringify({ action:'take_seat', seat: 3 })); + fc3.send(JSON.stringify({ action:'take_seat', seat: 2 })); } render () { diff --git a/assets/app.scss b/assets/app.scss @@ -57,12 +57,60 @@ } } .player__name { + font-size: 1.6rem; + font-weight: bold; +} +.play__hinfo { + font-size: 1.3rem; + min-height: 20px; +} +.play__tinfo { font-size: 1.3rem; + min-height: 20px; +} +.partner__stack{ + display: flex; + flex-direction: column; + align-items: center; +} +.partner__info { + display: flex; + justify-content: space-evenly; +} +.my__stack { + float: right; + font-size: 1.5rem; +} +.mh__card { + width: 100px; +} +.mh__card__row { + display: flex; +} +.hid__card { + width: 30px; +} +.hid__card__row { + display: flex; +} +.vert__stack { + display: flex; + flex-direction: column; + .hid__card__div { + height: 32px; + } + .hid__card__row { + flex-direction: column; + } + .hid__card { + transform: rotate(90deg); + } } .tm__left { // background-color: rgb(217, 249, 255); - .player__name { + .vert__stack { float: right; + align-items: flex-end; } } .tt__center { @@ -70,11 +118,40 @@ text-align: center; } -.mh__card { - width: 100px; +// .tm__right { +// background-color: rgb(217, 249, 255); +// } +// .tb__center { +// background-color: rgb(217, 249, 255); +// } + +.trump__card { + width: 80px; } -.mh__card__row { +.trump__outer { + height: 100%; + width: 100%; +} +.trump__holder { + height: 100%; display: flex; + align-items: center; +} +.trump__holder.me { + flex-direction: column; + justify-content: flex-end; +} +.trump__holder.partner { + flex-direction: column; + justify-content: flex-start; +} +.trump__holder.left { + flex-direction: row; + justify-content: flex-start; +} +.trump__holder.right { + flex-direction: row; + justify-content: flex-end; } .table__header { @@ -91,14 +168,6 @@ } - -// .tm__right { -// background-color: rgb(217, 249, 255); -// } -// .tb__center { -// background-color: rgb(217, 249, 255); -// } - // .tb__left { // background-color: slategray; // } diff --git a/assets/components/CardTable.js b/assets/components/CardTable.js @@ -5,6 +5,9 @@ import {Button, Grid, Row, Column} from 'carbon-components-react'; import {Logout32} from '@carbon/icons-react'; import SeatPicker from './SeatPicker'; import MainHand from './MainHand'; +import HiddenHand from './HiddenHand'; + +const trumpPlacement = ['me', 'left', 'partner', 'right']; export default class CardTable extends React.Component { @@ -13,11 +16,15 @@ export default class CardTable extends React.Component { this.state = { playerNames: [], mySeat: -1, + myCards: [], + myHandInfo: 'mhi', + myTurnInfo: 'mti', phase: 'lobby', - left: { name: '', seat: -1 }, - partner: { name: '', seat: -1 }, - right: { name: '', seat: -1 }, - myCards: [] + left: { name: '', seat: -1, handInfo: '', turnInfo: ' ' }, + partner: { name: '', seat: -1, handInfo: '', turnInfo: ' ' }, + right: { name: '', seat: -1, handInfo: '', turnInfo: '' }, + trumpPlace: '', + trumpNom: '' }; }; @@ -61,7 +68,7 @@ export default class CardTable extends React.Component { processVote = (msg) => { if (this.state.phase == 'lobby') { - this.gameStartSetup(); + this.gameStartSetup(msg); } this.setState({ phase: 'vote', @@ -69,24 +76,42 @@ export default class CardTable extends React.Component { }); }; - gameStartSetup = () => { + gameStartSetup = (msg) => { const { playerNames, mySeat } = this.state; + let handInfo = [' ', ' ', ' ', ' ']; + let turnInfo = [' ', ' ', ' ', ' ']; + handInfo[msg.game.dealer] = 'Dealer'; + turnInfo[msg.game.turn] = 'trump?'; const leftSeat = (mySeat + 1) % 4; const partnerSeat = (mySeat + 2) % 4; const rightSeat = (mySeat + 3) % 4; + let tpIndex = msg.game.dealer - mySeat; + tpIndex = (tpIndex < 0) ? tpIndex + 4 : tpIndex; + const trumpPlace = trumpPlacement[tpIndex]; + console.log('trumpPlace:', trumpPlace); this.setState ({ left : { name: playerNames[leftSeat], - seat: leftSeat + seat: leftSeat, + handInfo: handInfo[leftSeat], + turnInfo: turnInfo[leftSeat] }, partner : { name: playerNames[partnerSeat], - seat: partnerSeat + seat: partnerSeat, + handInfo: handInfo[partnerSeat], + turnInfo: turnInfo[partnerSeat] }, right : { name: playerNames[rightSeat], - seat: rightSeat - } + seat: rightSeat, + handInfo: handInfo[rightSeat], + turnInfo: turnInfo[rightSeat] + }, + myHandInfo : handInfo[mySeat], + myTurnInfo : turnInfo[mySeat], + trumpPlace : trumpPlace, + trumpNom: msg.game.trump_nominee }); }; @@ -107,7 +132,7 @@ export default class CardTable extends React.Component { sendStart = (startDealer) => { this.props.client.send(JSON.stringify({ - action: 'start_game' + action: 'start_game', start_seat: startDealer })) console.log('start game, dealer = ', startDealer); }; @@ -117,11 +142,14 @@ export default class CardTable extends React.Component { } render () { - const { playerNames, mySeat, phase, left, partner, right, myCards } = this.state; + const { playerNames, mySeat, phase, left, partner, right, myCards, + myHandInfo, myTurnInfo, trumpPlace, trumpNom } = this.state; const {name, tableName} = this.props; const showSeatPicker = phase == 'lobby'; const showTrump = phase == 'vote'; const welcomeMsg = 'Welcome to the ' + tableName + ' table, ' + name + '!'; + const tcp = "trump__holder " + trumpPlace; + const trumpImage = 'cards/' + trumpNom + '.svg'; return ( <div id="table"> <Grid> @@ -145,14 +173,30 @@ export default class CardTable extends React.Component { <Column className="tt__left" sm={1}> </Column> <Column className="tt__center" sm={2}> - <div className="player__name">{partner.name}</div> + {!showSeatPicker && ( + <div className="partner__stack"> + <div className="player__name">{partner.name}</div> + <div className="partner__info"> + <div className="play__hinfo">{partner.handInfo}</div> + <div className="play__tinfo">{partner.turnInfo}</div> + </div> + <HiddenHand + numCards={5} /> + </div>)} </Column> <Column className="tt__right" sm={1}> </Column> </Row> <Row className="table__mid"> <Column className="tm__left" sm={1}> - <div className="player__name">{left.name}</div> + {!showSeatPicker && ( + <div className="vert__stack"> + <div className="player__name">{left.name}</div> + <div className="play__hinfo">{left.handInfo}</div> + <div className="play__tinfo">{left.turnInfo}</div> + <HiddenHand + numCards={5} /> + </div>)} </Column> <Column className="tm__center" sm={2}> {showSeatPicker && ( @@ -163,15 +207,35 @@ export default class CardTable extends React.Component { mySeat={mySeat} handleStart={this.sendStart} />)} + { showTrump && ( + <div className="trump__outer"> + <div className={tcp}> + <img className="trump__card" src={trumpImage} /> + </div> + </div> + )} </Column> <Column className="tm__right" sm={1}> - <div className="player__name">{right.name}</div> + {!showSeatPicker && ( + <div className="vert__stack"> + <div className="player__name">{right.name}</div> + <div className="play__hinfo">{right.handInfo}</div> + <div className="play__tinfo">{right.turnInfo}</div> + <HiddenHand + numCards={5} /> + </div>)} </Column> </Row> <Row className="table__bot"> <Column className="tb__left" sm={1}> + {!showSeatPicker && ( + <div className="my__stack"> + <div className="my__hinfo">You: {myHandInfo}</div> + <div className="my__tinfo">{myTurnInfo}</div> + </div> + )} </Column> - <Column className="tb__center" sm={2}> + <Column className="tb__center" sm={3}> {!showSeatPicker && ( <MainHand cards={myCards} @@ -179,8 +243,8 @@ export default class CardTable extends React.Component { /> )} </Column> - <Column className="tb__right" sm={1}> - </Column> + {/* <Column className="tb__right" sm={1}> + </Column> */} </Row> </Grid> diff --git a/assets/components/HiddenHand.js b/assets/components/HiddenHand.js @@ -0,0 +1,33 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +class HiddenHand extends React.Component { + + cardBacks = (num) => { + let cbacks = []; + for (let i = 0; i < num; i++){ + cbacks.push( + <div + key={i} + className="hid__card__div"> + <img className="hid__card" src="cards/1B.svg" /> + </div> + ); + } + return cbacks; + } + + render () { + const { numCards } = this.props; + const cardBacks = this.cardBacks(numCards); + return ( + <div className="hid__card__row"> + {cardBacks} + </div> + ); + }; +} +HiddenHand.propTypes = { + numCards: PropTypes.number +} +export default HiddenHand; +\ No newline at end of file diff --git a/assets/components/MainHand.js b/assets/components/MainHand.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {Button, Link} from 'carbon-components-react'; +import { Link } from 'carbon-components-react'; class MainHand extends React.Component {