167 lines
4.1 KiB
JavaScript
167 lines
4.1 KiB
JavaScript
const preact = require('preact');
|
|
const { connect } = require('preact-redux');
|
|
|
|
const Vbox = require('./vbox.component');
|
|
const InfoContainer = require('./info.container');
|
|
const InstanceConstructsContainer = require('./instance.constructs');
|
|
const EquipmentContainer = require('./instance.equip');
|
|
|
|
const actions = require('../actions');
|
|
|
|
const addState = connect(
|
|
function receiveState(state) {
|
|
const { ws, instance, player, account, nav } = state;
|
|
|
|
function sendInstanceReady() {
|
|
return ws.sendInstanceReady(instance.id);
|
|
}
|
|
|
|
return { player, instance, sendInstanceReady, nav };
|
|
},
|
|
|
|
function receiveDispatch(dispatch) {
|
|
function setInfo(c) {
|
|
return dispatch(actions.setInfo(c));
|
|
}
|
|
|
|
function setNav(v) {
|
|
return dispatch(actions.setNav(v));
|
|
}
|
|
|
|
return {
|
|
setInfo,
|
|
setNav,
|
|
};
|
|
}
|
|
);
|
|
|
|
function Instance(args) {
|
|
const {
|
|
instance,
|
|
player,
|
|
sendInstanceReady,
|
|
setInfo,
|
|
|
|
nav,
|
|
setNav,
|
|
} = args;
|
|
|
|
if (!instance) return false;
|
|
|
|
function hoverInfo(e, info) {
|
|
e.stopPropagation();
|
|
return setInfo(info);
|
|
}
|
|
|
|
const rdyClasses = `instance-btn instance-ui-btn ${player.ready ? 'ready' : ''}`;
|
|
const readyInfo = instance.phase === 'Lobby'
|
|
? 'lobbyReady'
|
|
: 'ready';
|
|
const readyBtn = (
|
|
<button
|
|
className={rdyClasses}
|
|
onMouseOver={e => hoverInfo(e, readyInfo)}
|
|
onClick={() => sendInstanceReady()}>
|
|
Ready
|
|
</button>
|
|
);
|
|
|
|
function navClick() {
|
|
if (nav === 'vbox') return setNav('constructs');
|
|
return setNav('vbox');
|
|
}
|
|
|
|
const navBtn = (
|
|
<button
|
|
className="nav-btn"
|
|
onClick={navClick}>
|
|
{nav === 'vbox' ? 'Constructs' : 'Vbox'}
|
|
</button>
|
|
);
|
|
|
|
|
|
const actionBtn = player
|
|
? readyBtn
|
|
: null;
|
|
|
|
// TIMER
|
|
const zero = Date.parse(instance.phase_start);
|
|
const now = Date.now();
|
|
const end = Date.parse(instance.phase_end);
|
|
const timerPct = ((now - zero) / (end - zero) * 100);
|
|
const timerStyles = {
|
|
width: `${timerPct < 100 ? timerPct : 0}%`,
|
|
background: player.ready ? 'forestgreen' : 'whitesmoke',
|
|
};
|
|
|
|
function playerRound(id) {
|
|
if (!instance.rounds.length) return null;
|
|
return instance.rounds[instance.rounds.length - 1].find(r => r.player_ids.includes(id));
|
|
}
|
|
|
|
function playerText(p) {
|
|
const round = playerRound(p.id);
|
|
if (!round) {
|
|
return p.ready
|
|
? 'ready'
|
|
: '';
|
|
}
|
|
|
|
if (round.finished) return 'finished';
|
|
if (round.game_id) return 'in game';
|
|
|
|
return p.ready
|
|
? 'ready'
|
|
: '';
|
|
}
|
|
|
|
function ScoreBoard() {
|
|
if (instance.phase !== 'Lobby') return null;
|
|
|
|
const players = instance.players.map((p, i) => {
|
|
const pText = playerText(p);
|
|
return (
|
|
<tr key={i}
|
|
className={p.ready ? 'ready' : ''}>
|
|
<td>{p.name}</td>
|
|
<td>{p.score.wins} / {p.score.losses}</td>
|
|
<td>{pText}</td>
|
|
</tr>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<table className="scoreboard" >
|
|
<tbody>
|
|
{players}
|
|
</tbody>
|
|
</table>
|
|
);
|
|
}
|
|
|
|
const timer = (
|
|
<div className="timer-container">
|
|
<div className="timer" style={timerStyles} > </div>
|
|
</div>
|
|
);
|
|
|
|
const instanceClasses = `instance ${nav === 'constructs' ? 'constructs-visible' : ''}`;
|
|
|
|
return (
|
|
<main className={instanceClasses} onMouseOver={() => setInfo(null)} >
|
|
<div className="top">
|
|
{actionBtn}
|
|
{timer}
|
|
{navBtn}
|
|
</div>
|
|
<ScoreBoard />
|
|
<Vbox />
|
|
<InfoContainer />
|
|
<EquipmentContainer />
|
|
<InstanceConstructsContainer />
|
|
</main>
|
|
);
|
|
}
|
|
|
|
module.exports = addState(Instance);
|