better wip hey

This commit is contained in:
ntr 2019-06-03 23:24:48 +10:00
parent faff221ca6
commit 7e8e320c7d
24 changed files with 645 additions and 422 deletions

View File

@ -35,6 +35,7 @@
*CLIENT*
reconnect based on time delta
menu footer
fix refresh button
*SERVER*

View File

@ -61,6 +61,7 @@ module.exports = {
"react/jsx-uses-vars": 1,
"react/prefer-stateless-function": 1,
"react/prop-types": 0,
"react/no-unknown-property": 0,
// airbnb copypasta
// enforces getter/setter pairs in objects

View File

@ -79,8 +79,13 @@
stroke-width: 2px;
stroke: whitesmoke;
/* some stupid bug in chrome makes it fill the entire screen */
}
/* some stupid bug in chrome makes it fill the entire screen */
@media screen and (-webkit-min-device-pixel-ratio:0) {
#targeting {
max-height: 10em;
}
}
.resolving #targeting {

View File

@ -418,4 +418,4 @@ button.equipping {
}
/* Mobile Nav*/
.instance .nav-btn { display: none; }
.instance-nav { display: none; }

View File

@ -2,12 +2,10 @@
.instance {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content, min-content, min-content, 1fr;
grid-template-rows: min-content, 1fr;
grid-template-areas:
"top"
"controls"
"vbox"
"constructs"
"constructs";
}
.instance .nav-btn { display: initial; }
@ -131,4 +129,20 @@
.instance-construct:last-child {
border-left: 1px solid #222;
}
.instance-nav {
display: flex;
grid-area: nav;
margin-right: 0;
border-top: 2px solid #444;
}
.instance-nav button {
font-size: 150%;
border-right: 2px solid #444;
}
.instance-nav button:last-child {
border: none;
}
}

View File

@ -23,7 +23,7 @@ html, body, #mnml {
/*padding: 0 20%;*/
/* stops inspector going skitz*/
/*overflow: hidden;*/
overflow-x: hidden;
}
html {
@ -70,10 +70,11 @@ figure {
padding: 0 2em;
display: grid;
grid-template-columns: 1fr 8fr;
grid-template-rows: min-content 1fr;
grid-template-rows: min-content 1fr min-content;
grid-template-areas:
"hd hd"
"nav main";
"nav main"
"nav footer";
}
nav {
@ -145,6 +146,7 @@ button, input {
letter-spacing: 0.25em;
box-sizing: border-box;
font-size: 100%;
flex: 1;
/*the transitions */
transition-property: color;
@ -159,22 +161,6 @@ button:hover, button:focus {
border-color: whitesmoke;
}
button.right[disabled]:hover, button.left[disabled]:hover {
box-shadow: none;
}
button.top:hover, button.top:focus {
box-shadow: inset 0 0.25em 0 0 whitesmoke;
}
button.right:hover, button.right:focus {
box-shadow: inset -0.5em 0 0 0 whitesmoke;
}
button.left:hover, button.left:focus {
box-shadow: inset 0.5em 0 0 0 whitesmoke;
}
a {
color: whitesmoke;
font-size: 150%;
@ -313,18 +299,20 @@ header {
letter-spacing: 0.05em;
}
.header-username {
letter-spacing: 0.05em;
display: inline;
.header-status {
margin: 1em 0;
display: flex;
}
.header-status {
text-align: right;
.header-username {
letter-spacing: 0.05em;
flex: 1;
display: inline;
}
.header-status svg {
margin: 0.5em 0 0 1em;
height: 1.5em;
height: 1em;
background-color: black;
stroke: whitesmoke;
}
@ -359,29 +347,14 @@ header {
TEAM
*/
.menu-constructs {
.team {
display: flex;
display: grid;
grid-template-rows: min-content min-content;
grid-template-areas:
"top"
"team";
}
.constructs-list {
max-height: 100%;
margin-top: 0.5em;
grid-area: team;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 1fr;
grid-gap: 0.5em;
grid-gap: 1em;
grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
}
.menu-construct {
height: 100%;
box-sizing: border-box;
border: 1px solid black;
display: flex;
@ -544,10 +517,11 @@ main .top button {
max-height: 0.25em;
border: none;
margin: 1em 0;
margin: 1em 0 0 0;
}
.timer {
flex: 1 0 100%;
background: whitesmoke;
transition-property: all;
transition-duration: 0.5s;
@ -559,6 +533,33 @@ main .top button {
margin-bottom: 2em;
}
footer {
display: flex;
flex-flow: row wrap;
grid-area: footer;
margin: 0;
}
footer button {
margin: 0;
border: none;
background: #222;
}
footer button:disabled {
color: #444;
}
footer button:not(:last-child) {
background: #222;
border-right: 1px solid black;
}
footer button .ready {
background: forestgreen;
color: black;
}
@media (max-height: 900px), (max-width: 1500px) {
#mnml {
font-size: 75%;
@ -569,7 +570,6 @@ main .top button {
}
}
/* Mobile Nav*/
#nav-btn {
#nav-btn, #instance-nav {
display: none;
}

View File

@ -2,11 +2,11 @@
#mnml {
font-size: 8pt;
padding: 0;
grid-template-columns: min-content 1fr;
grid-template-rows: min-content 1fr;
grid-template-columns: 1fr;
grid-template-rows: 1fr min-content;
grid-template-areas:
"tnav hd "
"main main";
"main"
"footer";
}
#mnml button {
@ -21,9 +21,8 @@
display: none;
}
#nav-btn {
display: inline-block;
margin: 0 0.5em;
#nav-btn, #instance-nav {
display: unset;
}
#mnml.nav-visible nav {
@ -35,6 +34,10 @@
display: none;
}
header {
display: none;
}
main {
overflow-x: hidden;
}

View File

@ -0,0 +1,36 @@
// eslint-disable-next-line
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('./../actions');
const TeamFooter = require('./team.footer');
const ListFooter = require('./list.footer');
const InstanceFooter = require('./instance.footer');
const GameFooter = require('./game.footer');
const addState = connect(
({ nav, instance, game }) => {
return { nav, instance, game };
},
dispatch => ({
setShowNav: v => dispatch(actions.setShowNav(v)),
})
);
function renderHeader(args) {
const {
nav,
instance,
game,
} = args;
if (instance) return <InstanceFooter />;
if (game) return <GameFooter />;
if (nav === 'team') return <TeamFooter />;
if (nav === 'list') return <ListFooter />;
}
module.exports = addState(renderHeader);

View File

@ -1,122 +0,0 @@
const preact = require('preact');
const GameConstruct = require('./game.construct');
const Targeting = require('./targeting.arrows');
function GamePanel(props) {
const {
game,
account,
resolution,
setActiveSkill,
setActiveConstruct,
sendInstanceState,
sendGameReady,
skip,
quit,
} = props;
if (!game) return <div>...</div>;
function actionClick() {
if (game.phase === 'Finish') {
sendInstanceState(game.instance);
quit();
return true;
}
if (resolution) {
return skip();
}
return sendGameReady();
}
const otherTeams = game.players.filter(t => t.id !== account.id);
const playerTeam = game.players.find(t => t.id === account.id);
let actionText = 'Ready';
let actionStyles = 'instance-btn instance-ui-btn right';
if (game.phase === 'Finish') actionText = 'Done';
if (resolution) actionText = 'Skip';
if (actionText === 'Ready' && playerTeam.ready) actionStyles += ' ready';
const header = (
<div className="top">
<button
className={actionStyles}
onClick={() => actionClick()}>
{actionText}
</button>
</div>
);
function findConstruct(id) {
const team = game.players.find(t => t.constructs.find(c => c.id === id));
if (team) return team.constructs.find(c => c.id === id);
return null;
}
const zero = Date.parse(game.phase_start);
const now = Date.now();
const end = Date.parse(game.phase_end);
const timerPct = ((now - zero) / (end - zero) * 100);
const displayPct = resolution || game.phase === 'Finish'
? 0
: Math.min(timerPct, 100);
const displayColour = playerTeam.ready
? 'forestgreen'
: timerPct > 80
? 'red'
: 'whitesmoke';
const timerStyles = {
width: `${displayPct}%`,
background: displayColour,
};
const timer = (
<div className="timer-container">
<div className="timer" style={timerStyles} >&nbsp;</div>
</div>
);
function PlayerTeam(team) {
const constructs = team.constructs.map((c, i) =>
<GameConstruct key={c.id} i={i} construct={c} player={true} />);
return (
<div className="team player">
{constructs}
</div>
);
}
function OpponentTeam(team) {
const constructs = team.constructs.map((c, i) =>
<GameConstruct key={c.id} i={i} construct={c} player={false} />);
return (
<div className="team opponent">
{constructs}
</div>
);
}
const gameClasses = `game ${resolution ? 'resolving': ''}`;
function gameClick(e) {
e.stopPropagation();
setActiveConstruct(null);
}
return (
<main className={gameClasses} onClick={gameClick} >
{header}
{timer}
{otherTeams.map(OpponentTeam)}
<Targeting />
{PlayerTeam(playerTeam, setActiveSkill)}
</main>
);
}
module.exports = GamePanel;

View File

@ -1,81 +0,0 @@
const { connect } = require('preact-redux');
const actions = require('../actions');
const Game = require('./game.component');
const addState = connect(
function receiveState(state) {
const {
ws,
game,
account,
resolution,
showLog,
activeSkill,
activeConstruct,
} = state;
function selectSkillTarget(targetConstructId) {
if (activeSkill) {
return ws.sendGameSkill(game.id, activeSkill.constructId, targetConstructId, activeSkill.skill);
}
return false;
}
function sendGameReady() {
ws.sendGameReady(game.id);
}
function sendInstanceState(instanceId) {
if (!instanceId) return false;
return ws.sendInstanceState(instanceId);
}
// intercept self casting skills
if (activeSkill && activeSkill.skill.self_targeting) {
ws.sendGameSkill(game.id, activeSkill.constructId, null, activeSkill.skill.skill);
}
return {
game,
showLog,
account,
resolution,
activeSkill,
activeConstruct,
selectSkillTarget,
sendInstanceState,
sendGameReady,
};
},
function receiveDispatch(dispatch) {
function setActiveSkill(constructId, skill) {
dispatch(actions.setActiveSkill(constructId, skill));
// particlesJS(`particles-${constructId}`, config);
}
function setActiveConstruct(construct) {
dispatch(actions.setActiveConstruct(construct));
}
function quit() {
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
function toggleLog(v) {
dispatch(actions.setShowLog(v));
}
function skip() {
dispatch(actions.setSkip(true));
}
return { setActiveSkill, setActiveConstruct, quit, toggleLog, skip };
}
);
module.exports = addState(Game);

View File

@ -0,0 +1,136 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('../actions');
const addState = connect(
function receiveState(state) {
const {
ws,
game,
account,
resolution,
showNav,
} = state;
function sendGameReady() {
ws.sendGameReady(game.id);
}
function sendInstanceState(instanceId) {
if (!instanceId) return false;
return ws.sendInstanceState(instanceId);
}
return {
game,
account,
resolution,
sendInstanceState,
sendGameReady,
showNav,
};
},
function receiveDispatch(dispatch) {
function quit() {
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
function skip() {
dispatch(actions.setSkip(true));
}
function setShowNav(v) {
return dispatch(actions.setShowNav(v));
}
return { setShowNav, quit, skip };
}
);
function GameFooter(props) {
const {
game,
account,
resolution,
showNav,
quit,
skip,
setShowNav,
sendGameReady,
sendInstanceState,
} = props;
if (!game) {
return (
<footer id="footer">
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
</footer>
);
}
const playerTeam = game.players.find(t => t.id === account.id);
function actionClick() {
if (game.phase === 'Finish') {
sendInstanceState(game.instance);
quit();
return true;
}
if (resolution) {
return skip();
}
return sendGameReady();
}
let actionText = 'Ready';
if (game.phase === 'Finish') actionText = 'Done';
if (resolution) actionText = 'Skip';
const ready = (actionText === 'Ready' && playerTeam.ready)
? 'ready'
: '';
const zero = Date.parse(game.phase_start);
const now = Date.now();
const end = Date.parse(game.phase_end);
const timerPct = ((now - zero) / (end - zero) * 100);
const displayPct = resolution || game.phase === 'Finish'
? 0
: Math.min(timerPct, 100);
const displayColour = playerTeam.ready
? 'forestgreen'
: timerPct > 80
? 'red'
: 'whitesmoke';
const timerStyles = {
width: `${displayPct}%`,
background: displayColour,
};
const timer = (
<div className="timer-container">
<div className="timer" style={timerStyles} >&nbsp;</div>
</div>
);
return (
<footer>
{timer}
<button
className={ready}
onClick={() => actionClick()}>
{actionText}
</button>
</footer>
);
}
module.exports = addState(GameFooter);

View File

@ -0,0 +1,107 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('../actions');
const GameConstruct = require('./game.construct');
const Targeting = require('./targeting.arrows');
const addState = connect(
function receiveState(state) {
const {
ws,
game,
account,
resolution,
activeSkill,
activeConstruct,
} = state;
function selectSkillTarget(targetConstructId) {
if (activeSkill) {
return ws.sendGameSkill(game.id, activeSkill.constructId, targetConstructId, activeSkill.skill);
}
return false;
}
// intercept self casting skills
if (activeSkill && activeSkill.skill.self_targeting) {
ws.sendGameSkill(game.id, activeSkill.constructId, null, activeSkill.skill.skill);
}
return {
game,
account,
resolution,
activeSkill,
activeConstruct,
selectSkillTarget,
};
},
function receiveDispatch(dispatch) {
function setActiveSkill(constructId, skill) {
dispatch(actions.setActiveSkill(constructId, skill));
// particlesJS(`particles-${constructId}`, config);
}
function setActiveConstruct(construct) {
dispatch(actions.setActiveConstruct(construct));
}
return { setActiveSkill, setActiveConstruct };
}
);
function Game(props) {
const {
game,
account,
resolution,
setActiveSkill,
setActiveConstruct,
} = props;
if (!game) return <div>...</div>;
const otherTeams = game.players.filter(t => t.id !== account.id);
const playerTeam = game.players.find(t => t.id === account.id);
function PlayerTeam(team) {
const constructs = team.constructs.map((c, i) =>
<GameConstruct key={c.id} i={i} construct={c} player={true} />);
return (
<div className="team player">
{constructs}
</div>
);
}
function OpponentTeam(team) {
const constructs = team.constructs.map((c, i) =>
<GameConstruct key={c.id} i={i} construct={c} player={false} />);
return (
<div className="team opponent">
{constructs}
</div>
);
}
const gameClasses = `game ${resolution ? 'resolving': ''}`;
function gameClick(e) {
e.stopPropagation();
setActiveConstruct(null);
}
return (
<main className={gameClasses} onClick={gameClick} >
{otherTeams.map(OpponentTeam)}
<Targeting />
{PlayerTeam(playerTeam, setActiveSkill)}
</main>
);
}
module.exports = addState(Game);

View File

@ -1,15 +0,0 @@
const { connect } = require('preact-redux');
const Header = require('./header.component');
const actions = require('./../actions');
const addState = connect(
({ account, ping, showNav }) => {
return { account, ping, showNav };
},
dispatch => ({
setShowNav: v => dispatch(actions.setShowNav(v)),
})
);
module.exports = addState(Header);

View File

@ -1,7 +1,9 @@
// eslint-disable-next-line
const preact = require('preact');
const { connect } = require('preact-redux');
const { saw } = require('./shapes');
const actions = require('./../actions');
function pingColour(ping) {
if (ping < 100) return 'forestgreen';
@ -9,8 +11,14 @@ function pingColour(ping) {
return 'red';
}
const addState = connect(
({ account, ping, showNav }) => {
return { account, ping };
},
);
function renderHeader(args) {
const { account, ping, setShowNav, showNav } = args;
const { account, ping } = args;
const accountStatus = account
? (<div className="header-status">
@ -22,14 +30,11 @@ function renderHeader(args) {
return (
<header>
<h1 className="header-title">
<span id="nav-btn" onClick={() => setShowNav(!showNav)} ></span>
mnml.gg
</h1>
<h1 className="header-title">mnml.gg</h1>
{accountStatus}
</header>
);
}
module.exports = renderHeader;
module.exports = addState(renderHeader);

View File

@ -10,13 +10,8 @@ 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 };
const { ws, instance, nav } = state;
return { instance, nav };
},
function receiveDispatch(dispatch) {
@ -24,13 +19,8 @@ const addState = connect(
return dispatch(actions.setInfo(c));
}
function setNav(v) {
return dispatch(actions.setNav(v));
}
return {
setInfo,
setNav,
};
}
);
@ -38,62 +28,13 @@ const addState = connect(
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));
@ -139,21 +80,10 @@ function Instance(args) {
);
}
const timer = (
<div className="timer-container">
<div className="timer" style={timerStyles} >&nbsp;</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 />

View File

@ -0,0 +1,126 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('../actions');
const addState = connect(
function receiveState(state) {
const { ws, instance, player, nav, showNav } = state;
function sendInstanceReady() {
return ws.sendInstanceReady(instance.id);
}
return { player, instance, sendInstanceReady, nav, showNav };
},
function receiveDispatch(dispatch) {
function setShowNav(v) {
return dispatch(actions.setShowNav(v));
}
function setInfo(c) {
return dispatch(actions.setInfo(c));
}
function setNav(v) {
return dispatch(actions.setNav(v));
}
return {
setInfo,
setNav,
setShowNav,
};
}
);
function Instance(args) {
const {
instance,
player,
nav,
showNav,
setInfo,
setNav,
setShowNav,
sendInstanceReady,
} = args;
if (!instance || !player) {
return (
<footer id="footer">
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
</footer>
);
}
function hoverInfo(e, info) {
e.stopPropagation();
return setInfo(info);
}
const rdyClasses = `${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 = instance.phase === 'InProgress'
? (
<button
id="instance-nav"
onClick={navClick}>
{nav === 'vbox' ? 'Constructs' : 'Vbox'}
</button>
)
: null;
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 displayColour = player.ready
? 'forestgreen'
: timerPct > 80
? 'red'
: 'whitesmoke';
const timerStyles = {
width: `${timerPct}%`,
background: displayColour,
};
const timer = (
<div className="timer-container">
<div className="timer" style={timerStyles} >&nbsp;</div>
</div>
);
return (
<footer id="footer">
{timer}
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
{navBtn}
{readyBtn}
</footer>
);
}
module.exports = addState(Instance);

View File

@ -0,0 +1,47 @@
const { connect } = require('preact-redux');
const preact = require('preact');
const actions = require('./../actions');
const addState = connect(
function receiveState(state) {
const { showNav } = state;
return { showNav };
},
function receiveDispatch(dispatch) {
function navToTeam() {
return dispatch(actions.setNav('team'));
}
function setShowNav(v) {
return dispatch(actions.setShowNav(v));
}
return {
navToTeam,
setShowNav,
};
}
);
function ListFooter(args) {
const {
showNav,
navToTeam,
setShowNav,
} = args;
return (
<footer>
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
<button
className="instance-btn instance-ui-btn left"
onClick={() => navToTeam()}>
Change Constructs
</button>
</footer>
);
}
module.exports = addState(ListFooter);

View File

@ -37,15 +37,6 @@ const addState = connect(
instanceList,
};
},
function receiveDispatch(dispatch) {
function navToTeam() {
return dispatch(actions.setNav('team'));
}
return {
navToTeam,
};
}
);
function List(args) {
@ -57,7 +48,6 @@ function List(args) {
sendInstanceJoin,
sendInstanceList,
instanceList,
navToTeam,
} = args;
function listElements() {
@ -120,20 +110,8 @@ function List(args) {
</div>
);
const header = (
<div className="top">
<button
className="instance-btn instance-ui-btn left"
onClick={() => navToTeam()}>
Select Constructs
</button>
</div>
);
return (
<main className="menu-instances">
{header}
<div className="construct-list">
{constructPanels}
</div>

View File

@ -3,7 +3,7 @@ const preact = require('preact');
const { connect } = require('preact-redux');
const Login = require('./login');
const GameContainer = require('./game.container');
const Game = require('./game');
const Instance = require('./instance.component');
const Team = require('./team');
const List = require('./list');
@ -28,7 +28,7 @@ function Main(props) {
}
if (game) {
return <GameContainer />;
return <Game />;
}
if (instance) {

View File

@ -1,19 +1,20 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const Header = require('./header.container');
// const Header = require('./header');
const Main = require('./main');
const Nav = require('./nav');
const Footer = require('./footer');
const addState = connect(
state => ({ showNav: state.showNav })
);
const Mnml = ({ showNav, setShowNav }) =>
const Mnml = ({ showNav }) =>
<div id="mnml" className={showNav ? 'nav-visible' : ''}>
<Header />
<Nav />
<Main />
<Footer />
</div>;
module.exports = addState(Mnml);

View File

@ -3,9 +3,17 @@ const preact = require('preact');
const { Fragment } = require('preact');
const actions = require('../actions');
const { saw } = require('./shapes');
const testGame = process.env.NODE_ENV === 'development' && require('./../test.game');
const testInstance = process.env.NODE_ENV === 'development' && require('./../test.instance');
function pingColour(ping) {
if (ping < 100) return 'forestgreen';
if (ping < 200) return 'yellow';
return 'red';
}
const addState = connect(
function receiveState(state) {
const {
@ -13,7 +21,8 @@ const addState = connect(
account,
instances,
team,
// constructs,
ping,
game,
} = state;
@ -34,6 +43,7 @@ const addState = connect(
instances,
team,
game,
ping,
sendInstanceState,
sendAccountInstances,
sendInstanceList,
@ -79,14 +89,15 @@ const addState = connect(
function Nav(args) {
const {
account,
sendInstanceState,
sendAccountInstances,
sendInstanceList,
ping,
team,
instances,
game,
sendInstanceState,
sendAccountInstances,
sendInstanceList,
setTestGame,
setTestInstance,
setNav,
@ -122,8 +133,18 @@ function Nav(args) {
const canJoin = team.some(c => !c);
const accountStatus = account
? (<div className="header-status">
<h2 className="header-username">{account.name}</h2>
{saw(pingColour(ping))}
<div className="ping-text">{ping}ms</div>
</div>)
: false;
return (
<nav onClick={hideNav} >
<h1 className="header-title">mnml.gg</h1>
{accountStatus}
<button onClick={() => navTo('team')}>1. Select Team</button>
<button disabled={canJoin} onClick={() => navTo('list')}>2. Join</button>
<hr />

View File

@ -0,0 +1,56 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('./../actions');
const addState = connect(
function receiveState(state) {
const { team, showNav } = state;
return {
team,
showNav,
};
},
function receiveDispatch(dispatch) {
function navToList() {
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
return dispatch(actions.setNav('list'));
}
function setShowNav(v) {
return dispatch(actions.setShowNav(v));
}
return {
navToList,
setShowNav,
};
}
);
function TeamFooter(args) {
const {
showNav,
team,
navToList,
setShowNav,
} = args;
if (!team) return false;
return (
<footer>
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
<button
disabled={team.some(c => !c)}
className="instance-btn instance-ui-btn right"
onClick={() => navToList()}>
Join Instance
</button>
</footer>
);
}
module.exports = addState(TeamFooter);

View File

@ -12,14 +12,13 @@ const idSort = stringSort('id');
const addState = connect(
function receiveState(state) {
const { ws, constructs, team, account } = state;
const { ws, constructs, team } = state;
function sendConstructSpawn(name) {
return ws.sendConstructSpawn(name);
}
return {
account,
constructs,
team,
sendConstructSpawn,
@ -31,29 +30,19 @@ const addState = connect(
dispatch(actions.setTeam(constructIds));
}
function navToList() {
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
return dispatch(actions.setNav('list'));
}
return {
setTeam,
navToList,
};
}
);
function Team(args) {
const {
account,
constructs,
team,
setTeam,
sendConstructSpawn,
navToList,
} = args;
if (!constructs) return <div></div>;
@ -98,25 +87,10 @@ function Team(args) {
const spawnButtons = range(spawnButtonsNum)
.map(i => <SpawnButton key={constructs.length + i} spawn={name => sendConstructSpawn(name)} />);
const header = (
<div className="top">
<button
disabled={team.some(c => !c)}
className="instance-btn instance-ui-btn right"
onClick={() => navToList()}>
Join Instance
</button>
</div>
);
return (
<main className="menu-constructs">
{header}
<div className="constructs-list">
<main className="team">
{constructPanels}
{spawnButtons}
</div>
</main>
);
}

View File

@ -8,7 +8,7 @@ function errorToast(err) {
return toast.error({
title: 'BEEP BOOP',
message: err,
position: 'bottomCenter',
position: 'topRight',
});
}
@ -275,7 +275,7 @@ function createSocket(events) {
ws.addEventListener('open', () => {
toast.info({
message: 'connected',
position: 'bottomCenter',
position: 'topRight',
});
sendPing();
@ -303,7 +303,7 @@ function createSocket(events) {
console.error('WebSocket closed', event);
toast.warning({
message: 'disconnected',
position: 'bottomCenter',
position: 'topRight',
});
return setTimeout(connect, 5000);
});