From c534f973a10905795d7f0aa4a0608ead349d6ba2 Mon Sep 17 00:00:00 2001 From: Mashy Date: Sun, 27 Oct 2019 22:59:59 +1000 Subject: [PATCH] add shouldComponentUpdate to vbox components --- client/src/components/info.component.jsx | 3 +- client/src/components/instance.constructs.jsx | 120 ++-- client/src/components/vbox.component.jsx | 636 +++++++++--------- 3 files changed, 394 insertions(+), 365 deletions(-) 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);