summaryrefslogtreecommitdiff
path: root/frontend/src/components/game
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/game')
-rw-r--r--frontend/src/components/game/GameScene.css13
-rw-r--r--frontend/src/components/game/GameScene.jsx38
-rw-r--r--frontend/src/components/game/Hand.css26
-rw-r--r--frontend/src/components/game/Hand.jsx34
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>;
+}
bgstack15