add back shouldComponentUpdates =\

This commit is contained in:
Mashy 2019-11-26 13:27:50 +10:00
parent 8312b44b2b
commit 5153ed07b0
6 changed files with 430 additions and 399 deletions

View File

@ -1,44 +1,58 @@
const preact = require('preact'); const preact = require('preact');
const { connect } = require('preact-redux');
function Combiner(args) { const addState = connect(({ vboxCombiner }) => ({ vboxCombiner }));
const {
vbox,
vboxCombiner,
vboxSelected,
vboxBuySelected,
sendVboxCombine,
} = args;
const { stashSelect, storeSelect } = vboxSelected; class Combiner extends preact.Component {
shouldComponentUpdate(newProps) {
if (vboxCombiner) { if (newProps.vbox !== this.props.vbox) return true;
const combinerComboText = vboxCombiner.replace('Plus', '+'); if (newProps.vboxSelected !== this.props.vboxSelected) return true;
let bits = 0; if (newProps.vboxBuySelected !== this.props.vboxBuySelected) return true;
storeSelect.forEach(item => bits += item[0] + 1); if (newProps.sendVboxCombine !== this.props.sendVboxCombine) return true;
return ( if (newProps.vboxCombiner !== this.props.vboxCombiner) return true;
<button return false;
class='combiner vbox-btn'
disabled={bits > vbox.bits}
onClick={e => e.stopPropagation()}
onMouseDown={sendVboxCombine}>
{bits ? `Buy ${combinerComboText} ${bits}b` : `Combine ${combinerComboText}`}
</button>
);
} }
if (stashSelect.length === 0 && storeSelect.length === 1) { render(args) {
const item = storeSelect[0]; const {
return ( vbox,
<button vboxSelected,
class='combiner vbox-btn' vboxBuySelected,
onClick={e => e.stopPropagation()} sendVboxCombine,
onMouseDown={vboxBuySelected}> vboxCombiner,
{`Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`} } = args;
</button>
);
}
return false; const { stashSelect, storeSelect } = vboxSelected;
if (vboxCombiner) {
const combinerComboText = vboxCombiner.replace('Plus', '+');
let bits = 0;
storeSelect.forEach(item => bits += item[0] + 1);
return (
<button
class='combiner vbox-btn'
disabled={bits > vbox.bits}
onClick={e => e.stopPropagation()}
onMouseDown={sendVboxCombine}>
{bits ? `Buy ${combinerComboText} ${bits}b` : `Combine ${combinerComboText}`}
</button>
);
}
if (stashSelect.length === 0 && storeSelect.length === 1) {
const item = storeSelect[0];
return (
<button
class='combiner vbox-btn'
onClick={e => e.stopPropagation()}
onMouseDown={vboxBuySelected}>
{`Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`}
</button>
);
}
return false;
}
} }
module.exports = Combiner; module.exports = addState(Combiner);

View File

@ -1,51 +1,67 @@
const preact = require('preact'); const preact = require('preact');
const { connect } = require('preact-redux');
const { convertItem } = require('../utils'); const { convertItem } = require('../utils');
function Combos(props) { const addState = connect(
const { ({ info, instance, itemInfo, tutorial, vboxInfo }) => ({
info, info, instance, itemInfo, tutorial, vboxInfo,
instance, }));
itemInfo,
tutorial,
vboxInfo,
} = props;
if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; class Combos extends preact.Component {
shouldComponentUpdate(newProps) {
if (newProps.info !== this.props.info) return true;
if (newProps.instance !== this.props.instance) return true;
if (newProps.itemInfo !== this.props.itemInfo) return true;
if (newProps.tutorial !== this.props.tutorial) return true;
if (newProps.vboxInfo !== this.props.vboxInfo) return true;
return false;
}
const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info)); render(props) {
if (vboxCombos.length > 6 || vboxCombos.length === 0) return <div class="combos"></div>; const {
info,
instance,
itemInfo,
tutorial,
vboxInfo,
} = props;
if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false;
const comboTable = vboxCombos.map((c, i) => { const vboxCombos = itemInfo.combos.filter(c => c.components.includes(vboxInfo || info));
const mouseOver = e => { if (vboxCombos.length > 6 || vboxCombos.length === 0) return <div class="combos"></div>;
e.stopPropagation();
// this.setState({ comboItem: c.item }); const comboTable = vboxCombos.map((c, i) => {
// set comboInfo state here const mouseOver = e => {
}; e.stopPropagation();
const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci))) // this.setState({ comboItem: c.item });
? [<div key="0">{convertItem(c.components[0])}&nbsp;{convertItem(c.components[1])}</div>, // set comboInfo state here
<div key="1">{convertItem(c.components[2])}</div>] };
: c.components.map((u, j) => <div key={j} >{convertItem(u)}</div>); const componentTable = (c.components.some(ci => ['Red', 'Blue', 'Green'].includes(ci)))
return ( ? [<div key="0">{convertItem(c.components[0])}&nbsp;{convertItem(c.components[1])}</div>,
<div key={i} onMouseOver={mouseOver} class="table-button"> <div key="1">{convertItem(c.components[2])}</div>]
<div class="item"> : c.components.map((u, j) => <div key={j} >{convertItem(u)}</div>);
{convertItem(c.item)} return (
<div key={i} onMouseOver={mouseOver} class="table-button">
<div class="item">
{convertItem(c.item)}
</div>
{componentTable}
</div>
);
});
return (
<div class="combos">
<div class="combo-header">
<h2>COMBOS</h2>
Combine colours and items.
</div>
<div class="combo-list" onClick={e => e.stopPropagation()}>
{comboTable}
</div> </div>
{componentTable}
</div> </div>
); );
}); }
return (
<div class="combos">
<div class="combo-header">
<h2>COMBOS</h2>
Combine colours and items.
</div>
<div class="combo-list" onClick={e => e.stopPropagation()}>
{comboTable}
</div>
</div>
);
} }
module.exports = Combos; module.exports = addState(Combos);

View File

@ -4,8 +4,8 @@ const { connect } = require('preact-redux');
const actions = require('../actions'); const actions = require('../actions');
const InfoContainer = require('./vbox.info'); const InfoContainer = require('./vbox.info');
const { StashHdr, StashElement } = require('./vbox.stash'); const StashElement = require('./vbox.stash');
const { StoreHdr, StoreElement } = require('./vbox.store'); const StoreElement = require('./vbox.store');
const Combiner = require('./vbox.combiner'); const Combiner = require('./vbox.combiner');
const Combos = require('./vbox.combos'); const Combos = require('./vbox.combos');
@ -96,13 +96,11 @@ const addState = connect(
class Vbox extends preact.Component { class Vbox extends preact.Component {
shouldComponentUpdate(newProps) { shouldComponentUpdate(newProps) {
// Single variable props
if (newProps.itemUnequip !== this.props.itemUnequip) return true; if (newProps.itemUnequip !== this.props.itemUnequip) return true;
if (newProps.instance !== this.props.instance) return true;
if (newProps.player !== this.props.player) return true;
if (newProps.tutorial !== this.props.tutorial) return true; if (newProps.tutorial !== this.props.tutorial) return true;
if (newProps.vboxSelected !== this.props.vboxSelected) return true; if (newProps.vboxSelected !== this.props.vboxSelected) return true;
if (newProps.vboxHighlight !== this.props.vboxHighlight) return true;
if (newProps.player !== this.props.player) return true;
if (newProps.instance !== this.props.instance) return true;
return false; return false;
} }
@ -110,13 +108,9 @@ class Vbox extends preact.Component {
const { const {
// Changing state variables // Changing state variables
itemUnequip, itemUnequip,
info,
instance, instance,
player, player,
tutorial, tutorial,
vboxCombiner,
vboxHighlight,
vboxInfo,
vboxSelected, vboxSelected,
// Static // Static
itemInfo, itemInfo,
@ -148,72 +142,94 @@ class Vbox extends preact.Component {
return true; return true;
} }
function storeHdr() {
return (
<div class="store-hdr">
<h2
onTouchStart={e => e.target.scrollIntoView(true)}
onMouseOver={e => vboxHover(e, 'store')}> STORE
</h2>
<h1 class={`bits ${vbox.bits < 3 ? 'red' : false}`} onMouseOver={e => vboxHover(e, 'bits')}>
{vbox.bits}b
</h1>
<button
class='vbox-btn'
onMouseOver={e => vboxHover(e, 'refill')}
disabled={vbox.bits < 2
|| (tutorial && tutorial < 7
&& instance.time_control === 'Practice' && instance.rounds.length === 1)
}
onClick={e => e.stopPropagation()}
onMouseDown={() => sendVboxDiscard()}>
refill <br />
2b
</button>
</div>
);
}
function stashHdr() {
const refund = storeSelect.length === 0 && stashSelect.length === 1
? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost
: 0;
const tutorialDisabled = tutorial && tutorial < 8
&& instance.time_control === 'Practice' && instance.rounds.length === 1;
const refundBtn = (
<button
disabled={tutorialDisabled || !refund}
class='vbox-btn'
onClick={e => e.stopPropagation()}
onMouseDown={e => {
e.stopPropagation();
sendVboxReclaim(vboxSelected.stashSelect[0]);
}}>
refund <br />
{refund}b
</button>
);
return (
<div class='stash-hdr'>
<h2 onTouchStart={e => e.target.scrollIntoView(true)}
onMouseOver={e => vboxHover(e, 'stash')}> STASH
</h2>
{refundBtn}
</div>
);
}
// EVERYTHING // EVERYTHING
return ( return (
<div class='vbox'> <div class='vbox'>
<StoreHdr {storeHdr()}
instance={instance} {stashHdr()}
tutorial={tutorial}
sendVboxDiscard={sendVboxDiscard}
vbox={vbox}
vboxHover={vboxHover}
/>
<StoreElement <StoreElement
clearVboxSelected = {clearVboxSelected} clearVboxSelected={clearVboxSelected}
setInfo = {setInfo} setVboxSelected={setVboxSelected}
setVboxSelected = {setVboxSelected}
stashSelect = {stashSelect}
storeSelect = {storeSelect}
vbox = {vbox}
vboxHighlight = {vboxHighlight}
vboxHover = {vboxHover}
/>
<StashHdr
instance={instance}
itemInfo={itemInfo}
sendVboxReclaim={sendVboxReclaim}
tutorial={tutorial}
vbox={vbox} vbox={vbox}
vboxHover={vboxHover}
vboxSelected={vboxSelected} vboxSelected={vboxSelected}
vboxHover = {vboxHover}
/> />
<StashElement <StashElement
itemUnequip = {itemUnequip} sendItemUnequip={sendItemUnequip}
stashSelect = {stashSelect} setInfo={setInfo}
storeSelect = {storeSelect} setVboxSelected={setVboxSelected}
sendItemUnequip = {sendItemUnequip} vbox={vbox}
setInfo = {setInfo} vboxBuySelected={vboxBuySelected}
setVboxSelected = {setVboxSelected} vboxHover={vboxHover}
vbox = {vbox}
vboxBuySelected = {vboxBuySelected}
vboxHighlight = {vboxHighlight}
vboxHover = {vboxHover}
/> />
<div class='info-combiner'> <div class='info-combiner'>
<InfoContainer <InfoContainer
clearTutorial={clearTutorial} clearTutorial={clearTutorial}
info={info}
instance={instance}
itemInfo={itemInfo}
player={player}
tutorial={tutorial}
vboxInfo={vboxInfo}
/> />
<Combiner <Combiner
vbox={vbox} vbox={vbox}
vboxCombiner={vboxCombiner}
vboxSelected={vboxSelected} vboxSelected={vboxSelected}
vboxBuySelected={vboxBuySelected} vboxBuySelected={vboxBuySelected}
sendVboxCombine={sendVboxCombine} sendVboxCombine={sendVboxCombine}
/> />
</div> </div>
<Combos <Combos />
info={info}
instance={instance}
itemInfo={itemInfo}
tutorial={tutorial}
vboxInfo={vboxInfo}
/>
</div> </div>
); );
} }

View File

@ -1,55 +1,74 @@
const preact = require('preact'); const preact = require('preact');
const { connect } = require('preact-redux');
const { tutorialStage } = require('../tutorial.utils'); const { tutorialStage } = require('../tutorial.utils');
const { genItemInfo } = require('./vbox.utils'); const { genItemInfo } = require('./vbox.utils');
function Info(props) { const addState = connect(
const { ({ info, player, tutorial, vboxInfo, itemInfo, instance }) => ({
// Variables that will change info, player, tutorial, vboxInfo, itemInfo, instance,
info, }));
player,
tutorial,
vboxInfo,
// Static
clearTutorial,
itemInfo,
instance,
} = props;
if (tutorial) {
const tutorialStageInfo = tutorialStage(tutorial, clearTutorial, instance); class Info extends preact.Component {
if (tutorialStageInfo) return tutorialStageInfo; shouldComponentUpdate(newProps) {
if (newProps.clearTutorial !== this.props.clearTutorial) return true;
if (newProps.info !== this.props.info) return true;
if (newProps.player !== this.props.player) return true;
if (newProps.tutorial !== this.props.tutorial) return true;
if (newProps.vboxInfo !== this.props.vboxInfo) return true;
if (newProps.itemInfo !== this.props.itemInfo) return true;
if (newProps.instance !== this.props.instance) return true;
return false;
} }
// Prioritise the vbox info render(props) {
if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info); const {
clearTutorial,
info,
player,
tutorial,
vboxInfo,
itemInfo,
instance,
} = props;
// check normal info state if (tutorial) {
if (!info) return false; const tutorialStageInfo = tutorialStage(tutorial, clearTutorial, instance);
if (info.includes('constructName')) { if (tutorialStageInfo) return tutorialStageInfo;
return ( }
<div class='info info-item'>
<h2> {info.replace('constructName ', '')} </h2> // Prioritise the vbox info
<p> This is the name of your construct. <br /> if (vboxInfo) return genItemInfo(vboxInfo, itemInfo, player, info);
Names are randomly generated and are purely cosmetic. <br />
You can change change your construct name in the <b>RESHAPE</b> tab outside of games. // check normal info state
</p> if (!info) return false;
</div> if (info.includes('constructName')) {
); return (
<div class='info info-item'>
<h2> {info.replace('constructName ', '')} </h2>
<p> This is the name of your construct. <br />
Names are randomly generated and are purely cosmetic. <br />
You can change change your construct name in the <b>RESHAPE</b> tab outside of games.
</p>
</div>
);
}
if (info.includes('constructAvatar')) {
return (
<div class='info info-item'>
<h2> {info.replace('constructAvatar ', '')} </h2>
<p> This is your construct avatar. <br />
Avatars are randomly generated and are purely cosmetic. <br />
You can change your construct avatar in the <b>RESHAPE</b> tab outside of games.
</p>
</div>
);
}
return genItemInfo(info, itemInfo, player, info);
} }
if (info.includes('constructAvatar')) {
return (
<div class='info info-item'>
<h2> {info.replace('constructAvatar ', '')} </h2>
<p> This is your construct avatar. <br />
Avatars are randomly generated and are purely cosmetic. <br />
You can change your construct avatar in the <b>RESHAPE</b> tab outside of games.
</p>
</div>
);
}
return genItemInfo(info, itemInfo, player, info);
} }
module.exports = Info; module.exports = addState(Info);

View File

@ -1,4 +1,6 @@
const preact = require('preact'); const preact = require('preact');
const { connect } = require('preact-redux');
const range = require('lodash/range'); const range = require('lodash/range');
const without = require('lodash/without'); const without = require('lodash/without');
@ -6,143 +8,124 @@ const shapes = require('./shapes');
const buttons = require('./buttons'); const buttons = require('./buttons');
const { removeTier } = require('../utils'); const { removeTier } = require('../utils');
function stashHdr(props) { const addState = connect(
const { ({ itemUnequip, vboxHighlight, vboxSelected }) => ({ itemUnequip, vboxHighlight, vboxSelected }));
instance,
itemInfo,
sendVboxReclaim,
tutorial,
vbox,
vboxHover,
vboxSelected,
} = props;
const { storeSelect, stashSelect } = vboxSelected;
const refund = storeSelect.length === 0 && stashSelect.length === 1
? itemInfo.items.find(i => i.item === vbox.bound[stashSelect[0]]).cost
: 0;
const tutorialDisabled = tutorial && tutorial < 8
&& instance.time_control === 'Practice' && instance.rounds.length === 1;
const refundBtn = (
<button
disabled={tutorialDisabled || !refund}
class='vbox-btn'
onClick={e => e.stopPropagation()}
onMouseDown={e => {
e.stopPropagation();
sendVboxReclaim(vboxSelected.stashSelect[0]);
}}>
refund <br />
{refund}b
</button>
);
return ( class stashElement extends preact.Component {
<div class='stash-hdr'> shouldComponentUpdate(newProps) {
<h2 onTouchStart={e => e.target.scrollIntoView(true)} if (newProps.sendItemUnequip !== this.props.sendItemUnequip) return true;
onMouseOver={e => vboxHover(e, 'stash')}> STASH if (newProps.setInfo !== this.props.setInfo) return true;
</h2> if (newProps.setVboxSelected !== this.props.setVboxSelected) return true;
{refundBtn} if (newProps.vbox !== this.props.vbox) return true;
</div> if (newProps.vboxBuySelected !== this.props.vboxBuySelected) return true;
); if (newProps.vboxHover !== this.props.vboxHover) return true;
}
function stashElement(props) { if (newProps.itemUnequip !== this.props.itemUnequip) return true;
const { if (newProps.vboxHighlight !== this.props.vboxHighlight) return true;
itemUnequip, if (newProps.vboxSelected !== this.props.vboxSelected) return true;
sendItemUnequip, return false;
setInfo,
setVboxSelected,
stashSelect,
storeSelect,
vbox,
vboxBuySelected,
vboxHighlight,
vboxHover,
} = props;
const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0;
function stashClick(e) {
e.stopPropagation();
if (itemUnequip.length) return sendItemUnequip(itemUnequip);
if (vboxSelecting) return vboxBuySelected();
return true;
} }
function stashBtn(v, i) { render(props) {
const stashHighlight = vboxSelecting || itemUnequip.length; const {
sendItemUnequip,
setInfo,
setVboxSelected,
vbox,
vboxBuySelected,
vboxHover,
if (!v && v !== 0) { itemUnequip,
const emptyInvClick = () => { vboxHighlight,
if (vboxSelecting) return vboxBuySelected(); vboxSelected,
return false; } = props;
};
return <button
key={i}
onClick={emptyInvClick}
disabled={!stashHighlight}
class={stashHighlight ? 'receiving' : 'empty'} >&nbsp;</button>;
}
const notValidCombo = vboxHighlight && !vboxHighlight.includes(v); const { storeSelect, stashSelect } = vboxSelected;
function onClick(type, e) { const vboxSelecting = storeSelect.length === 1 && stashSelect.length === 0;
function stashClick(e) {
e.stopPropagation(); e.stopPropagation();
const combinerContainsIndex = stashSelect.indexOf(i) > -1; if (itemUnequip.length) return sendItemUnequip(itemUnequip);
// removing if (vboxSelecting) return vboxBuySelected();
if (combinerContainsIndex) { return true;
if (type === 'click') {
return setVboxSelected({ storeSelect, stashSelect: without(stashSelect, i) });
}
return true;
}
if (notValidCombo) {
setInfo(vbox.bound[i]);
return setVboxSelected({ storeSelect: [], stashSelect: [i] });
}
return setVboxSelected({ storeSelect, stashSelect: [...stashSelect, i] });
} }
const highlighted = stashSelect.indexOf(i) > -1; function stashBtn(v, i) {
const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : ''; const stashHighlight = vboxSelecting || itemUnequip.length;
const classes = highlighted
? 'highlight'
: `${border} ${notValidCombo ? 'fade' : ''}`;
const invObject = shapes[v] ? shapes[v]() : v; if (!v && v !== 0) {
const emptyInvClick = () => {
if (vboxSelecting) return vboxBuySelected();
return false;
};
return <button
key={i}
onClick={emptyInvClick}
disabled={!stashHighlight}
class={stashHighlight ? 'receiving' : 'empty'} >&nbsp;</button>;
}
const notValidCombo = vboxHighlight && !vboxHighlight.includes(v);
function onClick(type, e) {
e.stopPropagation();
const combinerContainsIndex = stashSelect.indexOf(i) > -1;
// removing
if (combinerContainsIndex) {
if (type === 'click') {
return setVboxSelected({ storeSelect, stashSelect: without(stashSelect, i) });
}
return true;
}
if (notValidCombo) {
setInfo(vbox.bound[i]);
return setVboxSelected({ storeSelect: [], stashSelect: [i] });
}
return setVboxSelected({ storeSelect, stashSelect: [...stashSelect, i] });
}
const highlighted = stashSelect.indexOf(i) > -1;
const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : '';
const classes = highlighted
? 'highlight'
: `${border} ${notValidCombo ? 'fade' : ''}`;
const invObject = shapes[v] ? shapes[v]() : v;
return (
<label
key={i}
draggable='true'
onDragStart={ev => {
onClick('drag', ev);
ev.dataTransfer.setData('text', '');
}}>
<button
class={classes}
onMouseOver={e => vboxHover(e, v)}
onClick={e => e.stopPropagation()}
onMouseDown={e => onClick('click', e)}>
{invObject}
</button>
</label>
);
}
return ( return (
<label <div
key={i} class='stash'
draggable='true' onMouseDown={stashClick}
onDragStart={ev => { onClick={e => e.stopPropagation()}
onClick('drag', ev); onDragOver={ev => ev.preventDefault()}
ev.dataTransfer.setData('text', ''); onDrop={stashClick}
}}> >
<button {range(0, 6).map(i => stashBtn(vbox.bound[i], i))}
class={classes} </div>
onMouseOver={e => vboxHover(e, v)}
onClick={e => e.stopPropagation()}
onMouseDown={e => onClick('click', e)}>
{invObject}
</button>
</label>
); );
} }
return (
<div
class='stash'
onMouseDown={stashClick}
onClick={e => e.stopPropagation()}
onDragOver={ev => ev.preventDefault()}
onDrop={stashClick}
>
{range(0, 6).map(i => stashBtn(vbox.bound[i], i))}
</div>
);
} }
module.exports = { stashHdr, stashElement }; module.exports = addState(stashElement);

View File

@ -1,112 +1,95 @@
const preact = require('preact'); const preact = require('preact');
const { connect } = require('preact-redux');
const range = require('lodash/range'); const range = require('lodash/range');
const shapes = require('./shapes'); const shapes = require('./shapes');
function storeHdr(props) { const addState = connect(({ vboxHighlight }) => ({ vboxHighlight }));
const {
instance,
tutorial,
sendVboxDiscard,
vbox,
vboxHover,
} = props;
return ( class storeElement extends preact.Component {
<div class="store-hdr"> shouldComponentUpdate(newProps) {
<h2 if (newProps.clearVboxSelected !== this.props.clearVboxSelected) return true;
onTouchStart={e => e.target.scrollIntoView(true)} if (newProps.setVboxSelected !== this.props.setVboxSelected) return true;
onMouseOver={e => vboxHover(e, 'store')}> STORE if (newProps.vbox !== this.props.vbox) return true;
</h2> if (newProps.vboxHighlight !== this.props.vboxHighlight) return true;
<h1 class={`bits ${vbox.bits < 3 ? 'red' : false}`} onMouseOver={e => vboxHover(e, 'bits')}> if (newProps.vboxHover !== this.props.vboxHover) return true;
{vbox.bits}b if (newProps.vboxSelected !== this.props.vboxSelected) return true;
</h1> return false;
<button
class='vbox-btn'
onMouseOver={e => vboxHover(e, 'refill')}
disabled={vbox.bits < 2
|| (tutorial && tutorial < 7
&& instance.time_control === 'Practice' && instance.rounds.length === 1)
}
onClick={e => e.stopPropagation()}
onMouseDown={() => sendVboxDiscard()}>
refill <br />
2b
</button>
</div>
);
}
function storeElement(props) {
const {
clearVboxSelected,
setVboxSelected,
storeSelect,
stashSelect,
vbox,
vboxHighlight,
vboxHover,
} = props;
function availableBtn(v, group, index) {
if (!v) return <button disabled class='empty' key={(group * 10) + index} >&nbsp;</button>;
const selected = storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index);
const notValidCombo = vboxHighlight && !vboxHighlight.includes(v);
function onClick(e) {
e.stopPropagation();
if (storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index)) {
return setVboxSelected(
{ storeSelect: storeSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect }
);
}
if (!storeSelect.length && !stashSelect.length) {
return setVboxSelected({ storeSelect: [[group, index]], stashSelect });
}
if (notValidCombo) {
return setVboxSelected({ storeSelect: [[group, index]], stashSelect: [] });
}
return setVboxSelected({ storeSelect: [...storeSelect, [group, index]], stashSelect });
}
const classes = selected
? `${v.toLowerCase()} highlight`
: `${v.toLowerCase()} ${notValidCombo ? 'fade' : ''}`;
const vboxObject = shapes[v] ? shapes[v]() : v;
const disabled = vbox.bits <= group;
return (
<label
key={group * 10 + index}
onDragEnd={clearVboxSelected}>
<button
class={classes}
disabled={disabled}
onMouseOver={e => vboxHover(e, v)}
onMouseDown={onClick}
onClick={e => e.stopPropagation()}
> {vboxObject}
</button>
</label>
);
} }
return ( render(props) {
<div class='store' const {
onClick={e => e.stopPropagation()}> // passed
<div class="vbox-colours"> clearVboxSelected,
{range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} setVboxSelected,
vbox,
vboxHover,
vboxSelected,
// state
vboxHighlight,
} = props;
const { storeSelect, stashSelect } = vboxSelected;
function availableBtn(v, group, index) {
if (!v) return <button disabled class='empty' key={(group * 10) + index} >&nbsp;</button>;
const selected = storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index);
const notValidCombo = vboxHighlight && !vboxHighlight.includes(v);
function onClick(e) {
e.stopPropagation();
if (storeSelect.length && storeSelect.some(vs => vs[0] === group && vs[1] === index)) {
return setVboxSelected(
{ storeSelect: storeSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect }
);
}
if (!storeSelect.length && !stashSelect.length) {
return setVboxSelected({ storeSelect: [[group, index]], stashSelect });
}
if (notValidCombo) {
return setVboxSelected({ storeSelect: [[group, index]], stashSelect: [] });
}
return setVboxSelected({ storeSelect: [...storeSelect, [group, index]], stashSelect });
}
const classes = selected
? `${v.toLowerCase()} highlight`
: `${v.toLowerCase()} ${notValidCombo ? 'fade' : ''}`;
const vboxObject = shapes[v] ? shapes[v]() : v;
const disabled = vbox.bits <= group;
return (
<label
key={group * 10 + index}
onDragEnd={clearVboxSelected}>
<button
class={classes}
disabled={disabled}
onMouseOver={e => vboxHover(e, v)}
onMouseDown={onClick}
onClick={e => e.stopPropagation()}
> {vboxObject}
</button>
</label>
);
}
return (
<div class='store'
onClick={e => e.stopPropagation()}>
<div class="vbox-colours">
{range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))}
</div>
<div class="vbox-items">
{range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))}
{range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))}
</div>
</div> </div>
<div class="vbox-items"> );
{range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))} }
{range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))}
</div>
</div>
);
} }
module.exports = { storeHdr, storeElement }; module.exports = addState(storeElement);