diff options
Diffstat (limited to 'frontend/src/components/game')
-rw-r--r-- | frontend/src/components/game/GameScene.css | 13 | ||||
-rw-r--r-- | frontend/src/components/game/GameScene.jsx | 38 | ||||
-rw-r--r-- | frontend/src/components/game/Hand.css | 26 | ||||
-rw-r--r-- | frontend/src/components/game/Hand.jsx | 34 |
4 files changed, 98 insertions, 13 deletions
diff --git a/frontend/src/components/game/GameScene.css b/frontend/src/components/game/GameScene.css new file mode 100644 index 00000000..525e68fa --- /dev/null +++ b/frontend/src/components/game/GameScene.css @@ -0,0 +1,13 @@ +.gameSceneRoot { + background: url('background-papyrus.jpg') center no-repeat; + background-size: cover; +} + +.fullscreen { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + overflow: auto; +} diff --git a/frontend/src/components/game/GameScene.jsx b/frontend/src/components/game/GameScene.jsx index fb5763db..cf3c91f8 100644 --- a/frontend/src/components/game/GameScene.jsx +++ b/frontend/src/components/game/GameScene.jsx @@ -2,7 +2,7 @@ import { Button, Classes, Intent } from '@blueprintjs/core'; import { List } from 'immutable'; import React, { Component } from 'react'; import { connect } from 'react-redux'; -import type { ApiPlayerTurnInfo } from '../../api/model'; +import type { ApiHandCard, ApiPlayerTurnInfo } from '../../api/model'; import { Game } from '../../models/games'; import { Player } from '../../models/players'; import { actions } from '../../redux/actions/game'; @@ -10,7 +10,9 @@ import { getCurrentTurnInfo } from '../../redux/currentGame'; import { getCurrentGame } from '../../redux/games'; import { getCurrentPlayer, getPlayers } from '../../redux/players'; -import { PlayerList } from '../lobby/PlayerList'; +import { Hand } from './Hand'; + +import './GameScene.css' type GameSceneProps = { game: Game, @@ -20,21 +22,31 @@ type GameSceneProps = { sayReady: () => void } -class GameScenePresenter extends Component<GameSceneProps> { - getTitle() { - if (this.props.game) { - return this.props.game.name + ' — Game'; - } else { - return 'What are you doing here? You haven\'t joined a game yet!'; - } +type GameSceneState = { + selectedCard: ApiHandCard | void +} + +class GameScenePresenter extends Component<GameSceneProps, GameSceneState> { + + state = { + selectedCard: null + }; + + selectCard(c: ApiHandCard) { + this.setState({selectedCard: c}) } render() { return ( - <div> - <h2>{this.getTitle()}</h2> - <PlayerList players={this.props.players} currentPlayer={this.props.currentPlayer} owner={this.props.game.owner}/> - <Button text="READY" className={Classes.LARGE} intent={Intent.PRIMARY} icon='play' onClick={this.props.sayReady} /> + <div className='gameSceneRoot fullscreen'> + <h2>Now playing!</h2> + <p>{this.props.turnInfo ? this.props.turnInfo.message : 'Click "ready" when you are'}</p> + + {this.props.turnInfo && <Hand cards={this.props.turnInfo.hand} + selectedCard={this.state.selectedCard} + onClick={(c) => this.selectCard(c)}/>} + + {!this.props.turnInfo && <Button text="READY" className={Classes.LARGE} intent={Intent.PRIMARY} icon='play' onClick={this.props.sayReady} />} <h3>Turn Info</h3> <div> diff --git a/frontend/src/components/game/Hand.css b/frontend/src/components/game/Hand.css new file mode 100644 index 00000000..de7b556d --- /dev/null +++ b/frontend/src/components/game/Hand.css @@ -0,0 +1,26 @@ +.hand { + display: flex; +} + +.hand-card { + margin: 0.2rem; +} + +.hand-card-unplayable { + opacity: 0.7; +} + +.hand-card-img-selected { + border: 2px solid #0054ff; +} + +.hand-card-img { + border-radius: 0.5rem; + box-shadow: 0 0 10px black; + width: 11rem; +} + +.hand-card-img:hover { + box-shadow: 0 10px 40px black; + width: 14rem; +} diff --git a/frontend/src/components/game/Hand.jsx b/frontend/src/components/game/Hand.jsx new file mode 100644 index 00000000..7dea23de --- /dev/null +++ b/frontend/src/components/game/Hand.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import type { ApiHandCard } from '../../api/model'; +import './Hand.css' + +type HandCardProps = { + card: ApiHandCard, + isSelected: boolean, + onClick: () => void +} + +const HandCard = ({card, isSelected, onClick}: HandCardProps) => { + let playableClass = card.playability.playable ? '' : 'hand-card-unplayable'; + let selectedClass = isSelected ? 'hand-card-img-selected' : ''; + return <div className={`hand-card ${playableClass}`} + onClick={() => card.playability.playable && onClick()} + aria-disabled={!card.playability.playable}> + <img src={`/images/cards/${card.image}`} + title={card.name} + alt={'Card ' + card.name} + className={`hand-card-img ${selectedClass}`}/> + </div> +}; + +type HandProps = { + cards: ApiHandCard[], + selectedCard: ApiHandCard, + onClick: (card: ApiHandCard) => void +} + +export const Hand = ({cards, selectedCard, onClick}: HandProps) => { + return <div className='hand'>{cards.map((c, i) => <HandCard key={i} card={c} + isSelected={selectedCard === c} + onClick={() => onClick(c)}/>)}</div>; +} |