From c3747e4e5e595a129576e413916afe4f5cc9eaa0 Mon Sep 17 00:00:00 2001 From: Felix Linker Date: Sun, 3 Jan 2021 10:17:10 +0100 Subject: [PATCH] Add toggle for properties in overview --- src/app/components/HardpointSlotSection.jsx | 4 +- src/app/components/InternalSlotSection.jsx | 4 +- src/app/components/Modification.jsx | 18 +++- src/app/components/ModificationsMenu.jsx | 7 +- src/app/components/Slot.jsx | 28 ++++-- src/app/components/SlotSection.jsx | 2 + src/app/components/StandardSlotSection.jsx | 4 +- src/app/components/UtilitySlotSection.jsx | 4 +- src/app/pages/OutfittingPage.jsx | 95 ++++++++++++++++++++- 9 files changed, 145 insertions(+), 21 deletions(-) diff --git a/src/app/components/HardpointSlotSection.jsx b/src/app/components/HardpointSlotSection.jsx index f4fe5749..676840af 100644 --- a/src/app/components/HardpointSlotSection.jsx +++ b/src/app/components/HardpointSlotSection.jsx @@ -51,7 +51,7 @@ export default class HardpointSlotSection extends SlotSection { * @return {Array} Array of Slots */ _getSlots() { - let { ship, currentMenu } = this.props; + let { ship, currentMenu, propsToShow, onPropToggle } = this.props; let { originSlot, targetSlot } = this.state; let slots = []; @@ -66,6 +66,8 @@ export default class HardpointSlotSection extends SlotSection { dropClass={this._dropClass(h, originSlot, targetSlot)} m={h} enabled={h.enabled ? true : false} + propsToShow={propsToShow} + onPropToggle={onPropToggle} />); } diff --git a/src/app/components/InternalSlotSection.jsx b/src/app/components/InternalSlotSection.jsx index 313e34fa..89bdc6cc 100644 --- a/src/app/components/InternalSlotSection.jsx +++ b/src/app/components/InternalSlotSection.jsx @@ -179,7 +179,7 @@ export default class InternalSlotSection extends SlotSection { */ _getSlots() { let slots = []; - let { currentMenu, ship } = this.props; + let { currentMenu, ship, propsToShow, onPropToggle } = this.props; let { originSlot, targetSlot } = this.state; for (const m of ship.getInternals(undefined, true)) { @@ -191,6 +191,8 @@ export default class InternalSlotSection extends SlotSection { dragOver={this._dragOverSlot.bind(this, m)} drop={this._drop} dropClass={this._dropClass(m, originSlot, targetSlot)} + propsToShow={propsToShow} + onPropToggle={onPropToggle} />); } diff --git a/src/app/components/Modification.jsx b/src/app/components/Modification.jsx index 17938d0f..6ca58a82 100644 --- a/src/app/components/Modification.jsx +++ b/src/app/components/Modification.jsx @@ -14,6 +14,8 @@ export default class Modification extends TranslatedComponent { m: PropTypes.instanceOf(Module).isRequired, property: PropTypes.string.isRequired, onSet: PropTypes.func.isRequired, + showProp: PropTypes.object.isRequired, + onPropToggle: PropTypes.func.isRequired, }; /** @@ -22,9 +24,9 @@ export default class Modification extends TranslatedComponent { */ constructor(props) { super(props); - const { m, property } = props; + const { m, property, showProp } = props; const { beneficial, unit, value } = m.getFormatted(property, true); - this.state = { beneficial, unit, value }; + this.state = { beneficial, unit, value, showProp }; } /** @@ -41,6 +43,14 @@ export default class Modification extends TranslatedComponent { } } + _toggleProperty() { + const { onPropToggle, property } = this.props; + const showProp = !this.state.showProp; + // TODO: defer until menu closed + onPropToggle(property, showProp); + this.setState({ showProp }); + } + /** * Render the modification * @return {React.Component} modification @@ -48,7 +58,7 @@ export default class Modification extends TranslatedComponent { render() { const { formats } = this.context.language; const { highlight, m, property } = this.props; - const { beneficial, unit, value, inputValue } = this.state; + const { beneficial, unit, value, inputValue, showProp } = this.state; // Some features only apply to specific modules; these features will be // undefined on items that do not belong to the same class. Filter these @@ -61,7 +71,7 @@ export default class Modification extends TranslatedComponent { - {}}/> + this._toggleProperty()}/> diff --git a/src/app/components/ModificationsMenu.jsx b/src/app/components/ModificationsMenu.jsx index 31ea22d0..3dc24dcd 100644 --- a/src/app/components/ModificationsMenu.jsx +++ b/src/app/components/ModificationsMenu.jsx @@ -19,6 +19,8 @@ export default class ModificationsMenu extends TranslatedComponent { static propTypes = { className: PropTypes.string, m: PropTypes.object.isRequired, + propsToShow: PropTypes.object.isRequired, + onPropToggle: PropTypes.func.isRequired, }; /** @@ -143,7 +145,7 @@ export default class ModificationsMenu extends TranslatedComponent { * Create a modification component */ _mkModification(property, highlight) { - const { m } = this.props; + const { m, propsToShow, onPropToggle } = this.props; let onSet = m.set.bind(m); // Show resistance instead of effectiveness @@ -156,7 +158,8 @@ export default class ModificationsMenu extends TranslatedComponent { } return ; + onSet={onSet} highlight={highlight} showProp={propsToShow[property]} + onPropToggle={onPropToggle} />; } /** diff --git a/src/app/components/Slot.jsx b/src/app/components/Slot.jsx index 5ce16050..f366866a 100644 --- a/src/app/components/Slot.jsx +++ b/src/app/components/Slot.jsx @@ -11,6 +11,7 @@ import { blueprintTooltip } from '../utils/BlueprintFunctions'; import { Module } from 'ed-forge'; import { REG_MILITARY_SLOT, REG_HARDPOINT_SLOT } from 'ed-forge/lib/data/slots'; import autoBind from 'auto-bind'; +import { toPairs } from 'lodash'; const HARDPOINT_SLOT_LABELS = { 1: 'S', @@ -31,6 +32,8 @@ export default class Slot extends TranslatedComponent { drag: PropTypes.func, drop: PropTypes.func, dropClass: PropTypes.string, + propsToShow: PropTypes.object.isRequired, + onPropToggle: PropTypes.func.isRequired, }; /** @@ -69,7 +72,7 @@ export default class Slot extends TranslatedComponent { * @return {React.Component} Slot contents */ _getSlotDetails() { - const { m } = this.props; + const { m, propsToShow } = this.props; let { termtip, tooltip, language } = this.context; const { translate, units, formats } = language; @@ -80,7 +83,7 @@ export default class Slot extends TranslatedComponent { )} ; } else { - let classRating = String(m.getClass()) + m.getRating(); + let classRating = m.getClassRating(); let { drag, drop } = this.props; // Modifications tooltip shows blueprint and grade, if available @@ -102,10 +105,9 @@ export default class Slot extends TranslatedComponent { // } let mass = m.get('mass') || m.get('cargo') || m.get('fuel') || 0; - const disabled = !m.isEnabled(); return (
+ {toPairs(propsToShow).sort().map(([prop, show]) => { + const { unit, value } = m.getFormatted(prop, true); + if (!show || isNaN(value)) { + return null; + } else { + return (
+ {translate(prop)}: {formats.round(value)}{unit} +
); + } + })} {(m.getApplicableBlueprints() || []).length > 0 ? (
); } diff --git a/src/app/components/SlotSection.jsx b/src/app/components/SlotSection.jsx index 2f15d8c7..1d4a3f3b 100644 --- a/src/app/components/SlotSection.jsx +++ b/src/app/components/SlotSection.jsx @@ -17,6 +17,8 @@ export default class SlotSection extends TranslatedComponent { ship: PropTypes.instanceOf(Ship), code: PropTypes.string.isRequired, togglePwr: PropTypes.func, + propsToShow: PropTypes.object.isRequired, + onPropToggle: PropTypes.func.isRequired, }; /** diff --git a/src/app/components/StandardSlotSection.jsx b/src/app/components/StandardSlotSection.jsx index 1c09aec6..a90c1b1b 100644 --- a/src/app/components/StandardSlotSection.jsx +++ b/src/app/components/StandardSlotSection.jsx @@ -90,9 +90,9 @@ export default class StandardSlotSection extends SlotSection { * @return {React.Component} Slot component */ _mkSlot(m, warning) { - const { currentMenu } = this.props; + const { currentMenu, propsToShow, onPropToggle } = this.props; return ; } diff --git a/src/app/components/UtilitySlotSection.jsx b/src/app/components/UtilitySlotSection.jsx index 1cb01ed2..bfb7e6c7 100644 --- a/src/app/components/UtilitySlotSection.jsx +++ b/src/app/components/UtilitySlotSection.jsx @@ -52,7 +52,7 @@ export default class UtilitySlotSection extends SlotSection { */ _getSlots() { let slots = []; - let { ship, currentMenu } = this.props; + let { ship, currentMenu, propsToShow, onPropToggle } = this.props; let { originSlot, targetSlot } = this.state; for (let h of ship.getUtilities(undefined, true)) { @@ -67,6 +67,8 @@ export default class UtilitySlotSection extends SlotSection { dropClass={this._dropClass(h, originSlot, targetSlot)} m={h} enabled={h.enabled ? true : false} + propsToShow={propsToShow} + onPropToggle={onPropToggle} />); } diff --git a/src/app/pages/OutfittingPage.jsx b/src/app/pages/OutfittingPage.jsx index a28b5c01..165a4899 100644 --- a/src/app/pages/OutfittingPage.jsx +++ b/src/app/pages/OutfittingPage.jsx @@ -40,6 +40,75 @@ import ModalPermalink from '../components/ModalPermalink'; import ModalShoppingList from '../components/ModalShoppingList'; import ModalOrbis from '../components/ModalOrbis'; import autoBind from 'auto-bind'; +import { assign } from 'lodash'; + +const SHOW_BY_DEFAULT = { + 'cabincapacity': true, + 'causticresistance': true, + 'explosiveresistance': true, + 'kineticresistance': true, + 'thermicresistance': true, + 'heatefficiency': true, + 'powercapacity': true, + 'integrity': true, + 'engineminimalmass': true, + 'engineoptimalmass': true, + 'enginemaximalmass': true, + 'engineoptperformance': true, + 'fsdoptimalmass': true, + 'maxfuel': true, + 'dronelifetime': true, + 'weaponscapacity': true, + 'weaponsrecharge': true, + 'systemscapacity': true, + 'systemsrecharge': true, + 'enginescapacity': true, + 'enginesrecharge': true, + 'range': true, + 'shieldgenmaximalmass': true, + 'shieldgenminimalmass': true, + 'shieldgenoptimalmass': true, + 'brokenregenrate': true, + 'regenrate': true, + 'shieldgenstrength': true, + 'ammomaximum': true, + 'afmrepaircapacity': true, + 'fsdinterdictorfacinglimit': true, + 'fuelscooprate': true, + 'bays': true, + 'rebuildsperbay': true, + 'maximumrange': true, + 'maxactivedrones': true, + 'refinerybins': true, + 'shieldbankduration': true, + 'shieldbankspinup': true, + 'shieldbankreinforcement': true, + 'defencemodifierhealthaddition': true, + 'protection': true, + 'dronehackingtime': true, + 'defencemodifiershieldaddition': true, + 'jumpboost': true, + 'damagepersecond': true, + 'damage': true, + 'energypersecond': true, + 'heatpersecond': true, + 'sustaineddamagepersecond': true, + 'damageperenergy': true, + 'rateoffire': true, + 'maximumrange': true, + 'damagefalloffrange': true, + 'armourpenetration': true, + 'sustainedenergypersecond': true, + 'sustainedheatpersecond': true, + 'ammoclipsize': true, + 'ammomaximum': true, + 'reloadtime': true, + 'shotspeed': true, + 'defencemodifiershieldmultiplier': true, + 'scannerrange': true, + 'scannertimetoscan': true, + 'maxangle': true, +}; /** * The Outfitting Page @@ -81,6 +150,7 @@ export default class OutfittingPage extends Page { ship, code: ship.compress(), savedCode, + propsToShow: assign({}, SHOW_BY_DEFAULT), }; } @@ -186,6 +256,19 @@ export default class OutfittingPage extends Page { ); } + _propToShowToggled(propertyName, newStatus) { + const { propsToShow } = this.state; + if (newStatus === propsToShow[propertyName]) { + return; + } + if (newStatus) { + propsToShow[propertyName] = true; + } else { + delete propsToShow[propertyName]; + } + this.setState({ propsToShow: assign({}, propsToShow) }); + } + /** * Save the current build */ @@ -632,10 +715,14 @@ export default class OutfittingPage extends Page { {/* Main tables */} - - - - + + + + {/* Control of ship and opponent */} {/*