From dd7a133caaa45c2e39246aaa0c56428ffe32d5ae Mon Sep 17 00:00:00 2001 From: willyb321 Date: Sun, 11 Nov 2018 01:31:30 +1100 Subject: [PATCH] add search bar initial why am i awake its like 2am --- package.json | 1 + src/app/components/AvailableModulesMenu.jsx | 92 ++++++++++++++++----- src/less/select.less | 9 ++ 3 files changed, 81 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index b81809bb..28dbe455 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,7 @@ "react": "^15.5.4", "react-dom": "^15.5.4", "react-extras": "^0.7.1", + "react-fuzzy": "^0.5.2", "react-ga": "^2.5.3", "react-number-editor": "Athanasius/react-number-editor.git#miggy", "recharts": "^1.2.0", diff --git a/src/app/components/AvailableModulesMenu.jsx b/src/app/components/AvailableModulesMenu.jsx index cddafb14..abc7b4c7 100644 --- a/src/app/components/AvailableModulesMenu.jsx +++ b/src/app/components/AvailableModulesMenu.jsx @@ -5,6 +5,7 @@ import TranslatedComponent from './TranslatedComponent'; import { stopCtxPropagation } from '../utils/UtilityFunctions'; import cn from 'classnames'; import { MountFixed, MountGimballed, MountTurret } from './SvgIcons'; +import FuzzySearch from 'react-fuzzy'; const PRESS_THRESHOLD = 500; // mouse/touch down threshold @@ -39,7 +40,7 @@ const GRPCAT = { 'mc': 'projectiles', 'axmc': 'experimental', 'fc': 'projectiles', - 'rfl': 'experimental', + 'rfl': 'experimental', 'pa': 'projectiles', 'rg': 'projectiles', 'mr': 'ordnance', @@ -133,6 +134,7 @@ export default class AvailableModulesMenu extends TranslatedComponent { constructor(props, context) { super(props); this._hideDiff = this._hideDiff.bind(this); + this._showSearch = this._showSearch.bind(this); this.state = this._initState(props, context); this.slotItems = [];// Array to hold
  • refs. } @@ -159,7 +161,7 @@ export default class AvailableModulesMenu extends TranslatedComponent { onSelect(m); } ); - + let fuzzy = []; if (modules instanceof Array) { list = buildGroup(modules[0].grp, modules); } else { @@ -167,9 +169,11 @@ export default class AvailableModulesMenu extends TranslatedComponent { // At present time slots with grouped options (Hardpoints and Internal) can be empty if (m) { let emptyId = 'empty'; - if(this.firstSlotId == null) this.firstSlotId = emptyId; + if (this.firstSlotId == null) this.firstSlotId = emptyId; let keyDown = this._keyDown.bind(this, onSelect); - list.push(
    this.slotItems[emptyId] = slotItem} >{translate('empty')}
    ); + list.push(
    this.slotItems[emptyId] = slotItem}>{translate('empty')}
    ); } // Need to regroup the modules by our own categorisation @@ -197,7 +201,8 @@ export default class AvailableModulesMenu extends TranslatedComponent { if (categories.length === 1) { // Show category header instead of group header if (m && grp == m.grp) { - list.push(
    this.groupElem = elem} key={category} className={'select-category upp'}>{translate(category)}
    ); + list.push(
    this.groupElem = elem} key={category} + className={'select-category upp'}>{translate(category)}
    ); } else { list.push(
    {translate(category)}
    ); } @@ -208,19 +213,23 @@ export default class AvailableModulesMenu extends TranslatedComponent { categoryHeader = true; } if (m && grp == m.grp) { - list.push(
    this.groupElem = elem} key={grp} className={'select-group cap'}>{translate(grp)}
    ); + list.push(
    this.groupElem = elem} key={grp} + className={'select-group cap'}>{translate(grp)}
    ); } else { list.push(
    {translate(grp)}
    ); } } list.push(buildGroup(grp, modules[grp])); + for (const i of modules[grp]) { + fuzzy.push({ grp, m: i, name: `${i.class}${i.rating} ${translate(grp)} ${i.mount ? i.mount : ''}` }); + } } } } } } let trackingFocus = false; - return { list, currentGroup, trackingFocus }; + return { list, currentGroup, fuzzy, trackingFocus }; } /** @@ -242,9 +251,11 @@ export default class AvailableModulesMenu extends TranslatedComponent { const sortedModules = modules.sort(this._moduleOrder); - // Calculate the number of items per class. Used so we don't have long lists with only a few items in each row - const tmp = sortedModules.map((v, i) => v['class']).reduce((count, cls) => { count[cls] = ++count[cls] || 1; return count; }, {}); + const tmp = sortedModules.map((v, i) => v['class']).reduce((count, cls) => { + count[cls] = ++count[cls] || 1; + return count; + }, {}); const itemsPerClass = Math.max.apply(null, Object.keys(tmp).map(key => tmp[key])); let itemsOnThisRow = 0; @@ -297,22 +308,29 @@ export default class AvailableModulesMenu extends TranslatedComponent { }; } - switch(m.mount) { - case 'F': mount = ; break; - case 'G': mount = ; break; - case 'T': mount = ; break; + switch (m.mount) { + case 'F': + mount = ; + break; + case 'G': + mount = ; + break; + case 'T': + mount = ; + break; } if (m.name && m.name === prevName) { // elems.push(
    ); itemsOnThisRow = 0; } if (itemsOnThisRow == 6 || i > 0 && sortedModules.length > 3 && itemsPerClass > 2 && m.class != prevClass && (m.rating != prevRating || m.mount)) { - elems.push(
    ); + elems.push(
    ); itemsOnThisRow = 0; } let tbIdx = (classes.indexOf('disabled') < 0) ? 0 : undefined; elems.push( -
  • this.slotItems[m.id] = slotItem}> +
  • this.slotItems[m.id] = slotItem}> {mount} {(mount ? ' ' : '') + m.class + m.rating + (m.missile ? '/' + m.missile : '') + (m.name ? ' ' + translate(m.name) : '')}
  • @@ -340,6 +358,36 @@ export default class AvailableModulesMenu extends TranslatedComponent { } } + /** + * Generate tooltip content for the difference between the + * mounted module and the hovered modules + */ + _showSearch() { + return ( + this.props.onSelect.bind(null, e.m)()} + resultsTemplate={(props, state, styles, clickHandler) => { + return state.results.map((val, i) => { + return ( +
    clickHandler(i)} + > + {val.name} +
    + ); + }); + }} + /> + ); + } + /** * Mouse over diff handler * @param {Function} showDiff diff tooltip callback @@ -405,7 +453,7 @@ export default class AvailableModulesMenu extends TranslatedComponent { * @param {Function} select Select module callback * @param {SytheticEvent} event Event */ - _keyUp(select,event) { + _keyUp(select, event) { // nothing here yet } @@ -475,12 +523,13 @@ export default class AvailableModulesMenu extends TranslatedComponent { this.slotItems[this.firstSlotId].focus(); } } + /** * Handle focus if the component updates * */ componentWillUnmount() { - if(this.props.slotDiv) { + if (this.props.slotDiv) { this.props.slotDiv.focus(); } } @@ -501,11 +550,12 @@ export default class AvailableModulesMenu extends TranslatedComponent { render() { return (
    this.node = node} - className={cn('select', this.props.className)} - onScroll={this._hideDiff} - onClick={(e) => e.stopPropagation() } - onContextMenu={stopCtxPropagation} + className={cn('select', this.props.className)} + onScroll={this._hideDiff} + onClick={(e) => e.stopPropagation()} + onContextMenu={stopCtxPropagation} > + {this._showSearch()} {this.state.list}
    ); diff --git a/src/less/select.less b/src/less/select.less index 012baa18..f84f6acb 100755 --- a/src/less/select.less +++ b/src/less/select.less @@ -22,6 +22,15 @@ select { } } +.react-fuzzy-search > * { + padding: 0 !important; + color: @primary; + & > input { + border: 1px solid @primary !important; + color: @primary-bg; + } +} + .cmdr-select { border: 1px solid @primary; padding: 0.5em 0.5em;