mnml/client/src/components/game.ctrl.jsx
2019-09-06 12:13:54 +10:00

138 lines
3.4 KiB
JavaScript

const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('../actions');
// dunno if this is a good idea
// bashing together instance and game to save having two panels
const addState = connect(
function receiveState(state) {
const {
ws,
game,
account,
animating,
} = state;
function sendReady() {
document.activeElement.blur();
return ws.sendGameReady(game.id);
}
function getInstanceState() {
return ws.sendInstanceState(game.instance);
}
return {
game,
sendReady,
account,
getInstanceState,
animating,
};
},
function receiveDispatch(dispatch) {
function quit() {
dispatch(actions.setNav('transition'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
return { quit };
}
);
function scoreboard(game, player, isOpponent) {
const text = game.phase === 'Finished'
? player.wins > game.rounds / 2 && 'Winner'
: '';
const classes =`scoreboard ${player.ready ? 'ready' : ''}`;
const body = isOpponent
? (
<tbody>
<tr><td>{player.name}</td></tr>
<tr><td>{player.wins} / {player.losses}</td></tr>
<tr><td>{player.ready ? 'ready' : ''}</td></tr>
</tbody>
) : (
<tbody>
<tr><td>{player.ready ? 'ready' : ''}</td></tr>
<tr><td>{player.wins} / {player.losses}</td></tr>
<tr><td>{player.name}</td></tr>
</tbody>
);
return (
<table class={classes}>
{body}
</table>
);
}
function Controls(args) {
const {
account,
game,
animating,
sendReady,
quit,
getInstanceState,
} = args;
if (!game) return false;
const opponent = game.players.find(t => t.id !== account.id);
const player = game.players.find(t => t.id === account.id);
function quitClick() {
getInstanceState();
quit();
}
const zero = Date.parse(game.phase_start);
const now = Date.now();
const end = Date.parse(game.phase_end);
const timerPct = game.phase_end
? ((now - zero) / (end - zero) * 100)
: 100;
const displayColour = !game.phase_end
? '#222'
: player.ready
? 'forestgreen'
: timerPct > 80
? 'red'
: 'whitesmoke';
const timerStyles = {
height: `${timerPct > 100 ? 100 : timerPct}%`,
background: displayColour,
};
const timer = (
<div class="timer-container">
<div class="timer" style={timerStyles} >&nbsp;</div>
</div>
);
const readyBtn = <button disabled={animating} class="ready" onClick={() => sendReady()}>Ready</button>;
const quitBtn = <button disabled={animating} onClick={quitClick}>Back</button>;
return (
<aside class="controls">
{timer}
<div class="controls">
{scoreboard(game, opponent, true)}
{game.phase === 'Finish' ? quitBtn : readyBtn}
{scoreboard(game, player)}
</div>
</aside>
);
}
module.exports = addState(Controls);