diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx
index f4aafd3e..5d34368b 100644
--- a/client/src/components/info.component.jsx
+++ b/client/src/components/info.component.jsx
@@ -2,14 +2,13 @@ const preact = require('preact');
const range = require('lodash/range');
const reactStringReplace = require('react-string-replace');
-const { Component } = require('preact');
const { INFO } = require('./../constants');
const { convertItem, removeTier } = require('../utils');
const { tutorialStage } = require('../tutorial.utils');
const shapes = require('./shapes');
-class InfoComponent extends Component {
+class InfoComponent extends preact.Component {
shouldComponentUpdate(newProps) {
if (newProps.tutorial !== this.props.tutorial) return true;
if (newProps.tutorial) return false; // We don't care about info during tutorial
diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx
index 5d3ec130..fb246a57 100644
--- a/client/src/components/instance.constructs.jsx
+++ b/client/src/components/instance.constructs.jsx
@@ -18,7 +18,6 @@ const addState = connect(
account,
itemInfo,
itemEquip,
- activeConstruct,
navInstance,
tutorial,
} = state;
@@ -39,7 +38,6 @@ const addState = connect(
itemInfo,
itemEquip,
navInstance,
- activeConstruct,
sendUnequip,
tutorial,
};
@@ -77,19 +75,21 @@ const addState = connect(
function Construct(props) {
const {
+ // Changing state variables
+ construct,
iter,
itemEquip,
- construct,
+ itemInfo,
+ mobileVisible,
player,
+ tutorial,
+ // Function Calls
sendVboxApply,
+ sendUnequip,
setActiveConstruct,
setItemUnequip,
setItemEquip,
- itemInfo,
setInfo,
- sendUnequip,
- mobileVisible,
- tutorial,
} = props;
const { vbox } = player;
@@ -242,61 +242,73 @@ function Construct(props) {
);
}
-function InstanceConstructs(props) {
- const {
- activeConstruct,
- itemEquip,
- player,
- instance,
- // clearInfo,
- setInfo,
- setActiveConstruct,
+class InstanceConstructs extends preact.Component {
+ shouldComponentUpdate(newProps) {
+ if (newProps.itemEquip !== this.props.itemEquip) return true;
+ if (newProps.instance.phase !== this.props.instance.phase) return true;
+ if (newProps.tutorial !== this.props.tutorial) return true;
+ if (newProps.navInstance !== this.props.navInstance) return true;
+ // JSON or Array objects
+ if (JSON.stringify(newProps.player) !== JSON.stringify(this.props.player)) return true;
+ return false;
+ }
- sendVboxApply,
- itemInfo,
- setVboxHighlight,
- setItemUnequip,
- setItemEquip,
- sendUnequip,
- navInstance,
- tutorial,
- } = props;
-
- if (!player) return false;
- if (instance.phase === 'Lobby') return false;
-
- const constructs = range(0, 3).map(i => {
- if (tutorial && tutorial < 6) {
- if (tutorial <= 2 || (tutorial > 2 && i > 0)) {
- const mobileVisible = navInstance === i + 1;
- const classes = `instance-construct ${mobileVisible ? 'visible' : ''}`;
- return (
);
- }
- }
- return Construct({
- iter: i,
- construct: player.constructs[i],
- activeConstruct,
+ render(props) {
+ const {
+ // Changing state variables
itemEquip,
- setItemUnequip,
- setItemEquip,
+ instance, // we only change phase
+ navInstance,
player,
- sendVboxApply,
+ tutorial,
+ // Static data
+ itemInfo,
+ // Function calls
setInfo,
setActiveConstruct,
- itemInfo,
+ sendVboxApply,
setVboxHighlight,
+ setItemUnequip,
+ setItemEquip,
sendUnequip,
- tutorial,
- mobileVisible: navInstance === i + 1,
- });
- });
+ } = props;
+ console.log('grep constructs');
- return (
- setActiveConstruct(null)}>
- {constructs}
-
- );
+ if (!player) return false;
+ if (instance.phase === 'Lobby') return false;
+
+ const constructs = range(0, 3).map(i => {
+ if (tutorial && tutorial < 6) {
+ if (tutorial <= 2 || (tutorial > 2 && i > 0)) {
+ const mobileVisible = navInstance === i + 1;
+ const classes = `instance-construct ${mobileVisible ? 'visible' : ''}`;
+ return ();
+ }
+ }
+ return Construct({
+ iter: i,
+ construct: player.constructs[i],
+ itemEquip,
+ setItemUnequip,
+ setItemEquip,
+ player,
+ sendVboxApply,
+ setInfo,
+ setActiveConstruct,
+ itemInfo,
+ setVboxHighlight,
+ sendUnequip,
+ tutorial,
+ mobileVisible: navInstance === i + 1,
+ });
+ });
+
+ return (
+ setActiveConstruct(null)}>
+ {constructs}
+
+ );
+ }
}
module.exports = addState(InstanceConstructs);
diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx
index ca0f3ad4..f13f3c8f 100644
--- a/client/src/components/vbox.component.jsx
+++ b/client/src/components/vbox.component.jsx
@@ -1,8 +1,9 @@
const preact = require('preact');
+const { connect } = require('preact-redux');
const range = require('lodash/range');
const countBy = require('lodash/countBy');
const without = require('lodash/without');
-const { connect } = require('preact-redux');
+
const { removeTier } = require('../utils');
const shapes = require('./shapes');
const actions = require('../actions');
@@ -95,333 +96,350 @@ const addState = connect(
);
-function Vbox(args) {
- const {
- combiner,
- navInstance,
- itemInfo,
- player,
- reclaiming,
- sendVboxAccept,
- sendVboxCombine,
- sendVboxDiscard,
- sendVboxReclaim,
-
- setCombiner,
- setInfo,
-
- vboxSelected,
- setVboxSelected,
-
- setItemEquip,
- tutorial,
- itemUnequip,
- sendItemUnequip,
-
- setReclaiming,
- info,
- } = args;
-
- if (!player) return false;
- const { vbox } = player;
- const vboxSelecting = vboxSelected.length;
-
- function combinerChange(newCombiner) {
- setCombiner(newCombiner);
-
- if (newCombiner.length === 1) {
- setItemEquip(newCombiner[0]);
- } else {
- setItemEquip(null);
- }
-
- return true;
+class Vbox extends preact.Component {
+ shouldComponentUpdate(newProps) {
+ // Single variable props
+ if (newProps.combiner !== this.props.combiner) return true;
+ if (newProps.itemUnequip !== this.props.itemUnequip) return true;
+ if (newProps.reclaiming !== this.props.reclaiming) return true;
+ if (newProps.navInstance !== this.props.navInstance) return true;
+ if (newProps.tutorial !== this.props.tutorial) return true;
+ // Don't bother if info changes during tutorial
+ if (!newProps.tutorial && newProps.info !== this.props.info) return true;
+ // JSON or Array objects
+ if (JSON.stringify(newProps.vboxSelected) !== JSON.stringify(this.props.vboxSelected)) return true;
+ if (JSON.stringify(newProps.player) !== JSON.stringify(this.props.player)) return true;
+ return false;
}
- //
- // VBOX
- //
- function vboxHover(e, v) {
- if (v) {
- if (info !== v) setInfo(v);
- e.stopPropagation();
- }
- return true;
- }
+ render(args) {
+ const {
+ // Changing state variables
+ combiner,
+ itemUnequip,
+ player,
+ reclaiming,
+ tutorial,
+ navInstance,
+ info,
+ vboxSelected,
- function clearVboxSelected() {
- setVboxSelected([]);
- }
+ // Static
+ itemInfo,
+ // Function Calls
+ sendItemUnequip,
+ sendVboxAccept,
+ sendVboxCombine,
+ sendVboxDiscard,
+ sendVboxReclaim,
+ setVboxSelected,
+ setItemEquip,
+ setInfo,
+ setCombiner,
+ setReclaiming,
+ } = args;
- function vboxBuySelected() {
- if (!vboxSelecting) return false;
- document.activeElement.blur();
- clearVboxSelected();
- sendVboxAccept(vboxSelected[0], vboxSelected[1]);
- return true;
- }
+ if (!player) return false;
+ const { vbox } = player;
+ const vboxSelecting = vboxSelected.length;
- function availableBtn(v, group, index) {
- if (!v) return ;
- const selected = vboxSelected[0] === group && vboxSelected[1] === index;
+ function combinerChange(newCombiner) {
+ setCombiner(newCombiner);
- // state not yet set in double click handler
- function onDblClick(e) {
- clearVboxSelected();
- sendVboxAccept(group, index);
- e.stopPropagation();
- }
-
- function onClick(e) {
- e.stopPropagation();
- setItemEquip(null);
- setCombiner([]);
-
- if (selected) return clearVboxSelected();
- return setVboxSelected([group, index]);
- }
-
- const combinerItems = combiner.map(j => vbox.bound[j]);
- const combinerCount = countBy(combinerItems, co => co);
-
- const comboHighlight = combinerItems.length > 0 && itemInfo.combos.some(combo => {
- if (combo.components.includes(v)) {
- return combinerItems.every(c => {
- if (!combo.components.includes(c)) return false;
- const comboCount = countBy(combo.components, co => co);
- if (combinerCount[c] > comboCount[c]) return false;
- if (c === v && combinerCount[c] + 1 > comboCount[c]) return false;
- return true;
- });
- } return false;
- }) ? 'combo-border' : '';
-
- const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`;
-
- if (shapes[v]) {
- return (
-
- );
- }
-
- return (
-
- );
- }
-
-
- function vboxElement() {
- return (
- setReclaiming(false)}
- onClick={e => e.stopPropagation()}
- onMouseOver={e => hoverInfo(e, 'vbox')}>
-
-
e.target.scrollIntoView(true)}>VBOX
-
hoverInfo(e, 'bits')} >{vbox.bits}b
-
-
- {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))}
-
-
- {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))}
- {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))}
-
-
-
- );
- }
-
- //
- // INVENTORY
- //
- function reclaimClick(e) {
- e.stopPropagation();
- return setReclaiming(!reclaiming);
- }
-
- const inventoryClass = `vbox-section ${reclaiming ? 'reclaiming' : ''}`;
-
- function inventoryBtn(v, i) {
- const inventoryHighlight = vboxSelecting || itemUnequip.length;
-
- if (!v && v !== 0) {
- return ;
- }
-
- const combinerItems = combiner.map(j => vbox.bound[j]);
- const combinerCount = countBy(combinerItems, co => co);
-
- const comboHighlight = combinerItems.length > 0 && itemInfo.combos.some(combo => {
- if (combo.components.includes(v)) {
- return combinerItems.every(c => {
- if (!combo.components.includes(c)) return false;
- const comboCount = countBy(combo.components, co => co);
- if (combinerCount[c] > comboCount[c]) return false;
- if (c === v && combinerCount[c] + 1 > comboCount[c]) return false;
- return true;
- });
- } return false;
- }) ? 'combo-border' : '';
-
- function onClick(e) {
- if (vboxSelecting) clearVboxSelected();
- if (reclaiming) return sendVboxReclaim(i);
-
- // 4 things selected
- if (combiner.length > 2) return combinerChange([i]);
-
- // removing
- const combinerIndex = combiner.indexOf(i);
- if (combinerIndex > -1) {
- return combinerChange(without(combiner, i));
+ if (newCombiner.length === 1) {
+ setItemEquip(newCombiner[0]);
+ } else {
+ setItemEquip(null);
}
- combiner.push(i);
-
- if (!comboHighlight) {
- return combinerChange([i]);
- }
-
- return combinerChange(combiner);
- }
-
- const highlighted = combiner.indexOf(i) > -1;
- const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : '';
- const classes = `${highlighted ? 'highlight' : border} ${comboHighlight}`;
- if (shapes[v]) {
- return (
-
- );
- }
-
- return (
-
- );
- }
-
- function combinerBtn() {
- let text = '';
- let comboItem = '';
- if (combiner.length < 3) {
- for (let i = 0; i < 3; i++) {
- if (combiner.length > i) {
- text += '■ ';
- } else {
- text += '▫ ';
- }
- }
- } else {
- // Since theres 3 items in combiner and you can't have invalid combos we can preview it
- const combinerItems = combiner.map(j => vbox.bound[j]);
- const combinerCount = countBy(combinerItems, co => co);
- const comboItemObj = itemInfo.combos.find(combo => combinerItems.every(c => {
- if (!combo.components.includes(c)) return false;
- const comboCount = countBy(combo.components, co => co);
- if (combinerCount[c] > comboCount[c]) return false;
- return true;
- }));
- comboItem = comboItemObj ? comboItemObj.item : 'refine';
- comboItem = comboItem.replace('Plus', '+');
- text = `Combine - ${comboItem}`;
- }
-
- return (
-
- );
- }
-
- function inventoryElement() {
- function inventoryClick(e) {
- e.stopPropagation();
- setReclaiming(false);
- if (vboxSelecting) return vboxBuySelected();
- if (itemUnequip.length) return sendItemUnequip(itemUnequip);
return true;
}
- return (
- e.stopPropagation()}
- style={vboxSelecting || (itemUnequip.length) ? { cursor: 'pointer' } : null}
- onMouseOver={e => hoverInfo(e, 'inventory')}>
-
-
e.target.scrollIntoView(true)}>INVENTORY
+ //
+ // VBOX
+ //
+ function vboxHover(e, v) {
+ if (v) {
+ if (info !== v) setInfo(v);
+ e.stopPropagation();
+ }
+ return true;
+ }
+
+ function clearVboxSelected() {
+ setVboxSelected([]);
+ }
+
+ function vboxBuySelected() {
+ if (!vboxSelecting) return false;
+ document.activeElement.blur();
+ clearVboxSelected();
+ sendVboxAccept(vboxSelected[0], vboxSelected[1]);
+ return true;
+ }
+
+ function availableBtn(v, group, index) {
+ if (!v) return
;
+ const selected = vboxSelected[0] === group && vboxSelected[1] === index;
+
+ // state not yet set in double click handler
+ function onDblClick(e) {
+ clearVboxSelected();
+ sendVboxAccept(group, index);
+ e.stopPropagation();
+ }
+
+ function onClick(e) {
+ e.stopPropagation();
+ setItemEquip(null);
+ setCombiner([]);
+
+ if (selected) return clearVboxSelected();
+ return setVboxSelected([group, index]);
+ }
+
+ const combinerItems = combiner.map(j => vbox.bound[j]);
+ const combinerCount = countBy(combinerItems, co => co);
+
+ const comboHighlight = combinerItems.length > 0 && itemInfo.combos.some(combo => {
+ if (combo.components.includes(v)) {
+ return combinerItems.every(c => {
+ if (!combo.components.includes(c)) return false;
+ const comboCount = countBy(combo.components, co => co);
+ if (combinerCount[c] > comboCount[c]) return false;
+ if (c === v && combinerCount[c] + 1 > comboCount[c]) return false;
+ return true;
+ });
+ } return false;
+ }) ? 'combo-border' : '';
+
+ const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`;
+
+ if (shapes[v]) {
+ return (
+ );
+ }
+
+ return (
+
+ );
+ }
+
+
+ function vboxElement() {
+ return (
+
setReclaiming(false)}
+ onClick={e => e.stopPropagation()}
+ onMouseOver={e => hoverInfo(e, 'vbox')}>
+
+
e.target.scrollIntoView(true)}>VBOX
+
hoverInfo(e, 'bits')} >{vbox.bits}b
+
+
+ {range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))}
+
+
+ {range(0, 3).map(i => availableBtn(vbox.free[1][i], 1, i))}
+ {range(0, 3).map(i => availableBtn(vbox.free[2][i], 2, i))}
+
+
-
- {range(0, 9).map(i => inventoryBtn(vbox.bound[i], i))}
+ );
+ }
+
+ //
+ // INVENTORY
+ //
+ function reclaimClick(e) {
+ e.stopPropagation();
+ return setReclaiming(!reclaiming);
+ }
+
+ const inventoryClass = `vbox-section ${reclaiming ? 'reclaiming' : ''}`;
+
+ function inventoryBtn(v, i) {
+ const inventoryHighlight = vboxSelecting || itemUnequip.length;
+
+ if (!v && v !== 0) {
+ return
;
+ }
+
+ const combinerItems = combiner.map(j => vbox.bound[j]);
+ const combinerCount = countBy(combinerItems, co => co);
+
+ const comboHighlight = combinerItems.length > 0 && itemInfo.combos.some(combo => {
+ if (combo.components.includes(v)) {
+ return combinerItems.every(c => {
+ if (!combo.components.includes(c)) return false;
+ const comboCount = countBy(combo.components, co => co);
+ if (combinerCount[c] > comboCount[c]) return false;
+ if (c === v && combinerCount[c] + 1 > comboCount[c]) return false;
+ return true;
+ });
+ } return false;
+ }) ? 'combo-border' : '';
+
+ function onClick(e) {
+ if (vboxSelecting) clearVboxSelected();
+ if (reclaiming) return sendVboxReclaim(i);
+
+ // 4 things selected
+ if (combiner.length > 2) return combinerChange([i]);
+
+ // removing
+ const combinerIndex = combiner.indexOf(i);
+ if (combinerIndex > -1) {
+ return combinerChange(without(combiner, i));
+ }
+
+ combiner.push(i);
+
+ if (!comboHighlight) {
+ return combinerChange([i]);
+ }
+
+ return combinerChange(combiner);
+ }
+
+ const highlighted = combiner.indexOf(i) > -1;
+ const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : '';
+ const classes = `${highlighted ? 'highlight' : border} ${comboHighlight}`;
+ if (shapes[v]) {
+ return (
+
+ );
+ }
+
+ return (
+
+ );
+ }
+
+ function combinerBtn() {
+ let text = '';
+ let comboItem = '';
+ if (combiner.length < 3) {
+ for (let i = 0; i < 3; i++) {
+ if (combiner.length > i) {
+ text += '■ ';
+ } else {
+ text += '▫ ';
+ }
+ }
+ } else {
+ // Since theres 3 items in combiner and you can't have invalid combos we can preview it
+ const combinerItems = combiner.map(j => vbox.bound[j]);
+ const combinerCount = countBy(combinerItems, co => co);
+ const comboItemObj = itemInfo.combos.find(combo => combinerItems.every(c => {
+ if (!combo.components.includes(c)) return false;
+ const comboCount = countBy(combo.components, co => co);
+ if (combinerCount[c] > comboCount[c]) return false;
+ return true;
+ }));
+ comboItem = comboItemObj ? comboItemObj.item : 'refine';
+ comboItem = comboItem.replace('Plus', '+');
+ text = `Combine - ${comboItem}`;
+ }
+
+ return (
+
+ );
+ }
+
+ function inventoryElement() {
+ function inventoryClick(e) {
+ e.stopPropagation();
+ setReclaiming(false);
+ if (vboxSelecting) return vboxBuySelected();
+ if (itemUnequip.length) return sendItemUnequip(itemUnequip);
+ return true;
+ }
+
+ return (
+
e.stopPropagation()}
+ style={vboxSelecting || (itemUnequip.length) ? { cursor: 'pointer' } : null}
+ onMouseOver={e => hoverInfo(e, 'inventory')}>
+
+
e.target.scrollIntoView(true)}>INVENTORY
+
+
+
+ {range(0, 9).map(i => inventoryBtn(vbox.bound[i], i))}
+
+ {combinerBtn()}
- {combinerBtn()}
+ );
+ }
+
+ //
+ // EVERYTHING
+ //
+ function hoverInfo(e, newInfo) {
+ e.stopPropagation();
+ if (info === newInfo) return true;
+ return setInfo(newInfo);
+ }
+
+ const classes = `vbox ${navInstance === 0 ? 'visible' : ''}`;
+ return (
+
+ {vboxElement()}
+
⮞
+ {inventoryElement()}
);
}
-
- //
- // EVERYTHING
- //
- function hoverInfo(e, newInfo) {
- e.stopPropagation();
- if (info === newInfo) return true;
- return setInfo(newInfo);
- }
-
- const classes = `vbox ${navInstance === 0 ? 'visible' : ''}`;
- return (
-
- {vboxElement()}
-
⮞
- {inventoryElement()}
-
- );
}
module.exports = addState(Vbox);