From 2d74cbc0cc43e50f74a618f5b6ceb526fdd2e99b Mon Sep 17 00:00:00 2001 From: Thibault LAURIANO Date: Fri, 25 Jun 2021 19:51:32 +0200 Subject: [PATCH 1/6] Fix Desktop - CMD + K is slow and laggy #3601 --- src/components/OptionsSelector.js | 35 +++++--- src/pages/SearchPage.js | 143 ++++++++++++++++-------------- 2 files changed, 96 insertions(+), 82 deletions(-) mode change 100755 => 100644 src/components/OptionsSelector.js mode change 100755 => 100644 src/pages/SearchPage.js diff --git a/src/components/OptionsSelector.js b/src/components/OptionsSelector.js old mode 100755 new mode 100644 index d03519c43de1..3f96c8d651d7 --- a/src/components/OptionsSelector.js +++ b/src/components/OptionsSelector.js @@ -12,6 +12,8 @@ import withLocalize, {withLocalizePropTypes} from './withLocalize'; const propTypes = { /** Callback to fire when a row is tapped */ onSelectRow: PropTypes.func, + filterAdapter: PropTypes.func, + getCustomHeaderMessage: PropTypes.func, /** Sections for the section list */ sections: PropTypes.arrayOf(PropTypes.shape({ @@ -28,21 +30,12 @@ const propTypes = { shouldShow: PropTypes.bool, })).isRequired, - /** Value in the search input field */ - value: PropTypes.string.isRequired, - - /** Callback fired when text changes */ - onChangeText: PropTypes.func.isRequired, - /** Optional placeholder text for the selector */ placeholderText: PropTypes.string, /** Options that have already been selected */ selectedOptions: PropTypes.arrayOf(optionPropTypes), - /** Optional header message */ - headerMessage: PropTypes.string, - /** Whether we can select multiple options */ canSelectMultipleOptions: PropTypes.bool, @@ -69,9 +62,10 @@ const propTypes = { const defaultProps = { onSelectRow: () => {}, + filterAdapter: () => {}, + getCustomHeaderMessage: () => {}, placeholderText: '', selectedOptions: [], - headerMessage: '', canSelectMultipleOptions: false, hideSectionHeaders: false, disableArrowKeysActions: false, @@ -86,8 +80,10 @@ class OptionsSelector extends Component { super(props); this.handleKeyPress = this.handleKeyPress.bind(this); + this.onChangeText = this.onChangeText.bind(this); this.selectRow = this.selectRow.bind(this); this.viewableItems = []; + this.searchValue = ''; this.state = { focusedIndex: 0, @@ -98,6 +94,17 @@ class OptionsSelector extends Component { this.textInput.focus(); } + /** + * Updates sections filtered by searchValue + * + * @param {String} searchValue + */ + onChangeText(searchValue) { + const sections = this.props.filterAdapter(searchValue); + this.searchValue = searchValue; + this.setState({sections}); + } + /** * Scrolls to the focused index within the SectionList * @@ -188,6 +195,7 @@ class OptionsSelector extends Component { } render() { + const headerMessage = this.props.getCustomHeaderMessage(this.searchValue); return ( @@ -195,9 +203,8 @@ class OptionsSelector extends Component { styleFocusIn={[styles.textInputReversedFocus]} ref={el => this.textInput = el} style={[styles.textInput]} - value={this.props.value} - onChangeText={this.props.onChangeText} onKeyPress={this.handleKeyPress} + onChangeText={this.onChangeText} placeholder={this.props.placeholderText || this.props.translate('optionsSelector.nameEmailOrPhoneNumber')} placeholderTextColor={themeColors.placeholderText} @@ -207,12 +214,12 @@ class OptionsSelector extends Component { ref={el => this.list = el} optionHoveredStyle={styles.hoveredComponentBG} onSelectRow={this.selectRow} - sections={this.props.sections} + sections={this.state.sections || this.props.sections} focusedIndex={this.state.focusedIndex} selectedOptions={this.props.selectedOptions} canSelectMultipleOptions={this.props.canSelectMultipleOptions} hideSectionHeaders={this.props.hideSectionHeaders} - headerMessage={this.props.headerMessage} + headerMessage={headerMessage} disableFocusOptions={this.props.disableArrowKeysActions} hideAdditionalOptionStates={this.props.hideAdditionalOptionStates} forceTextUnreadStyle={this.props.forceTextUnreadStyle} diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js old mode 100755 new mode 100644 index 564e0181679c..e59da513993b --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -1,6 +1,5 @@ -import _ from 'underscore'; import React, {Component} from 'react'; -import {View} from 'react-native'; +import {View, Text} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import OptionsSelector from '../components/OptionsSelector'; @@ -14,8 +13,6 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../components/wit import {fetchOrCreateChatReport} from '../libs/actions/Report'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; import ScreenWrapper from '../components/ScreenWrapper'; -import Timing from '../libs/actions/Timing'; -import CONST from '../CONST'; import FullScreenLoadingIndicator from '../components/FullscreenLoadingIndicator'; import withLocalize, {withLocalizePropTypes} from '../components/withLocalize'; import compose from '../libs/compose'; @@ -62,11 +59,10 @@ class SearchPage extends Component { constructor(props) { super(props); - Timing.start(CONST.TIMING.SEARCH_RENDER); - this.selectReport = this.selectReport.bind(this); - this.onChangeText = this.onChangeText.bind(this); - this.debouncedUpdateOptions = _.debounce(this.updateOptions.bind(this), 300); + this.filterAdapter = this.filterAdapter.bind(this); + this.getCustomHeaderMessage = this.getCustomHeaderMessage.bind(this); + this.lazyLoad = this.lazyLoad.bind(this); const { recentReports, @@ -79,20 +75,25 @@ class SearchPage extends Component { props.betas, ); - this.state = { - searchValue: '', - recentReports, - personalDetails, - userToInvite, - }; + this.recentReports = recentReports; + this.personalDetails = personalDetails; + this.userToInvite = userToInvite; } componentDidMount() { - Timing.end(CONST.TIMING.SEARCH_RENDER); } - onChangeText(searchValue = '') { - this.setState({searchValue}, this.debouncedUpdateOptions); + /** + * Returns header message given searchValue + * @param {String} searchValue + * @returns {String} header messae + */ + getCustomHeaderMessage(searchValue = '') { + return getHeaderMessage( + (this.recentReports.length + this.personalDetails.length) !== 0, + Boolean(this.userToInvite), + searchValue, + ); } /** @@ -101,17 +102,37 @@ class SearchPage extends Component { * @returns {Array} */ getSections() { + return this.filterAdapter(''); + } + + + /** + * Returns the sections needed for the OptionsSelector + * @param {String} searchValue + * @returns {Array} + */ + filterAdapter(searchValue) { + const { + recentReports, + personalDetails, + userToInvite, + } = getSearchOptions( + this.props.reports, + this.props.personalDetails, + searchValue, + this.props.betas, + ); const sections = [{ title: this.props.translate('common.recents'), - data: this.state.recentReports.concat(this.state.personalDetails), + data: recentReports.concat(personalDetails), shouldShow: true, indexOffset: 0, }]; - if (this.state.userToInvite) { + if (userToInvite) { sections.push(({ undefined, - data: [this.state.userToInvite], + data: [userToInvite], shouldShow: true, indexOffset: 0, })); @@ -120,22 +141,10 @@ class SearchPage extends Component { return sections; } - updateOptions() { - const { - recentReports, - personalDetails, - userToInvite, - } = getSearchOptions( - this.props.reports, - this.props.personalDetails, - this.state.searchValue, - this.props.betas, - ); - this.setState({ - userToInvite, - recentReports, - personalDetails, - }); + lazyLoad() { + // eslint-disable-next-line no-console + console.log('lazyLoad', this.state.readyToLoad); + this.setState({readyToLoad: true}); } /** @@ -149,11 +158,7 @@ class SearchPage extends Component { } if (option.reportID) { - this.setState({ - searchValue: '', - }, () => { - Navigation.navigate(ROUTES.getReportRoute(option.reportID)); - }); + Navigation.navigate(ROUTES.getReportRoute(option.reportID)); } else { fetchOrCreateChatReport([ this.props.session.email, @@ -164,36 +169,38 @@ class SearchPage extends Component { render() { const sections = this.getSections(); - const headerMessage = getHeaderMessage( - (this.state.recentReports.length + this.state.personalDetails.length) !== 0, - Boolean(this.state.userToInvite), - this.state.searchValue, - ); return ( {({didScreenTransitionEnd}) => ( - <> - Navigation.dismissModal(true)} - /> - - - {didScreenTransitionEnd && ( - - )} - - - + !didScreenTransitionEnd + ? ( + + ... + + ) + : ( + <> + Navigation.dismissModal(true)} + /> + + + {didScreenTransitionEnd && ( + + )} + + + + ) )} ); From bdc8dadee9f9907d448a5255b199b6dee5824092 Mon Sep 17 00:00:00 2001 From: Thibault LAURIANO Date: Mon, 28 Jun 2021 19:24:07 +0200 Subject: [PATCH 2/6] Remove unnecessary text on SearchPage --- src/components/Looxor | 3 +++ src/pages/SearchPage.js | 8 ++------ 2 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 src/components/Looxor diff --git a/src/components/Looxor b/src/components/Looxor new file mode 100644 index 000000000000..3b54a01ea0b4 --- /dev/null +++ b/src/components/Looxor @@ -0,0 +1,3 @@ +Looxor +MyNameIsJin08011952l. +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 \ No newline at end of file diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index e59da513993b..bdc1502cf3ce 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {View, Text} from 'react-native'; +import {View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import OptionsSelector from '../components/OptionsSelector'; @@ -173,11 +173,7 @@ class SearchPage extends Component { {({didScreenTransitionEnd}) => ( !didScreenTransitionEnd - ? ( - - ... - - ) + ? null : ( <> Date: Mon, 28 Jun 2021 19:38:51 +0200 Subject: [PATCH 3/6] Remove unnecessary log --- src/pages/SearchPage.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index bdc1502cf3ce..872b890cdaa8 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -142,8 +142,6 @@ class SearchPage extends Component { } lazyLoad() { - // eslint-disable-next-line no-console - console.log('lazyLoad', this.state.readyToLoad); this.setState({readyToLoad: true}); } From 141592ab59114eace970f2086d22894a7c985b0d Mon Sep 17 00:00:00 2001 From: Thibault LAURIANO Date: Mon, 28 Jun 2021 20:42:11 +0200 Subject: [PATCH 4/6] Add Timing, Update sections, Add commments --- src/components/OptionsSelector.js | 8 +++++--- src/pages/SearchPage.js | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/OptionsSelector.js b/src/components/OptionsSelector.js index 3f96c8d651d7..1795c73f35c3 100644 --- a/src/components/OptionsSelector.js +++ b/src/components/OptionsSelector.js @@ -12,7 +12,9 @@ import withLocalize, {withLocalizePropTypes} from './withLocalize'; const propTypes = { /** Callback to fire when a row is tapped */ onSelectRow: PropTypes.func, + /** Function to get a filtered result as list */ filterAdapter: PropTypes.func, + /** FUnction to get header message from parent component */ getCustomHeaderMessage: PropTypes.func, /** Sections for the section list */ @@ -87,6 +89,7 @@ class OptionsSelector extends Component { this.state = { focusedIndex: 0, + sections: props.sections, }; } @@ -195,7 +198,6 @@ class OptionsSelector extends Component { } render() { - const headerMessage = this.props.getCustomHeaderMessage(this.searchValue); return ( @@ -214,12 +216,12 @@ class OptionsSelector extends Component { ref={el => this.list = el} optionHoveredStyle={styles.hoveredComponentBG} onSelectRow={this.selectRow} - sections={this.state.sections || this.props.sections} + sections={this.state.sections} focusedIndex={this.state.focusedIndex} selectedOptions={this.props.selectedOptions} canSelectMultipleOptions={this.props.canSelectMultipleOptions} hideSectionHeaders={this.props.hideSectionHeaders} - headerMessage={headerMessage} + headerMessage={this.props.getCustomHeaderMessage(this.searchValue)} disableFocusOptions={this.props.disableArrowKeysActions} hideAdditionalOptionStates={this.props.hideAdditionalOptionStates} forceTextUnreadStyle={this.props.forceTextUnreadStyle} diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index 872b890cdaa8..0c9044d96292 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -13,6 +13,8 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../components/wit import {fetchOrCreateChatReport} from '../libs/actions/Report'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; import ScreenWrapper from '../components/ScreenWrapper'; +import Timing from '../libs/actions/Timing'; +import CONST from '../CONST'; import FullScreenLoadingIndicator from '../components/FullscreenLoadingIndicator'; import withLocalize, {withLocalizePropTypes} from '../components/withLocalize'; import compose from '../libs/compose'; @@ -59,6 +61,8 @@ class SearchPage extends Component { constructor(props) { super(props); + Timing.start(CONST.TIMING.SEARCH_RENDER); + this.selectReport = this.selectReport.bind(this); this.filterAdapter = this.filterAdapter.bind(this); this.getCustomHeaderMessage = this.getCustomHeaderMessage.bind(this); From 2a18f5c04277ebb186c007c8a2ec13c224b609d0 Mon Sep 17 00:00:00 2001 From: Thibault LAURIANO Date: Mon, 28 Jun 2021 21:23:00 +0200 Subject: [PATCH 5/6] Remove unnecessary variable, add lines before comments --- src/components/OptionsSelector.js | 2 ++ src/pages/SearchPage.js | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/OptionsSelector.js b/src/components/OptionsSelector.js index 1795c73f35c3..2fe712597218 100644 --- a/src/components/OptionsSelector.js +++ b/src/components/OptionsSelector.js @@ -12,8 +12,10 @@ import withLocalize, {withLocalizePropTypes} from './withLocalize'; const propTypes = { /** Callback to fire when a row is tapped */ onSelectRow: PropTypes.func, + /** Function to get a filtered result as list */ filterAdapter: PropTypes.func, + /** FUnction to get header message from parent component */ getCustomHeaderMessage: PropTypes.func, diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index 0c9044d96292..ff97d5b6288b 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -66,7 +66,6 @@ class SearchPage extends Component { this.selectReport = this.selectReport.bind(this); this.filterAdapter = this.filterAdapter.bind(this); this.getCustomHeaderMessage = this.getCustomHeaderMessage.bind(this); - this.lazyLoad = this.lazyLoad.bind(this); const { recentReports, @@ -145,10 +144,6 @@ class SearchPage extends Component { return sections; } - lazyLoad() { - this.setState({readyToLoad: true}); - } - /** * Reset the search value and redirect to the selected report * From 4fe5bbf006639b168dccd943487bac37997b1060 Mon Sep 17 00:00:00 2001 From: Thibault LAURIANO Date: Tue, 29 Jun 2021 10:14:58 +0200 Subject: [PATCH 6/6] Rename filterAdapter, Add Timing.end, Add props.recentReports, Correct tyop --- src/components/Looxor | 3 -- src/components/OptionsSelector.js | 8 +-- src/pages/SearchPage.js | 84 ++++++++++++++----------------- 3 files changed, 43 insertions(+), 52 deletions(-) delete mode 100644 src/components/Looxor diff --git a/src/components/Looxor b/src/components/Looxor deleted file mode 100644 index 3b54a01ea0b4..000000000000 --- a/src/components/Looxor +++ /dev/null @@ -1,3 +0,0 @@ -Looxor -MyNameIsJin08011952l. -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 \ No newline at end of file diff --git a/src/components/OptionsSelector.js b/src/components/OptionsSelector.js index 2fe712597218..651992c16032 100644 --- a/src/components/OptionsSelector.js +++ b/src/components/OptionsSelector.js @@ -14,9 +14,9 @@ const propTypes = { onSelectRow: PropTypes.func, /** Function to get a filtered result as list */ - filterAdapter: PropTypes.func, + searchSections: PropTypes.func, - /** FUnction to get header message from parent component */ + /** Function to get header message from parent component */ getCustomHeaderMessage: PropTypes.func, /** Sections for the section list */ @@ -66,7 +66,7 @@ const propTypes = { const defaultProps = { onSelectRow: () => {}, - filterAdapter: () => {}, + searchSections: () => {}, getCustomHeaderMessage: () => {}, placeholderText: '', selectedOptions: [], @@ -105,7 +105,7 @@ class OptionsSelector extends Component { * @param {String} searchValue */ onChangeText(searchValue) { - const sections = this.props.filterAdapter(searchValue); + const sections = this.props.searchSections(searchValue); this.searchValue = searchValue; this.setState({sections}); } diff --git a/src/pages/SearchPage.js b/src/pages/SearchPage.js index ff97d5b6288b..6b224722de81 100644 --- a/src/pages/SearchPage.js +++ b/src/pages/SearchPage.js @@ -64,26 +64,12 @@ class SearchPage extends Component { Timing.start(CONST.TIMING.SEARCH_RENDER); this.selectReport = this.selectReport.bind(this); - this.filterAdapter = this.filterAdapter.bind(this); + this.searchSections = this.searchSections.bind(this); this.getCustomHeaderMessage = this.getCustomHeaderMessage.bind(this); - - const { - recentReports, - personalDetails, - userToInvite, - } = getSearchOptions( - props.reports, - props.personalDetails, - '', - props.betas, - ); - - this.recentReports = recentReports; - this.personalDetails = personalDetails; - this.userToInvite = userToInvite; } componentDidMount() { + Timing.end(CONST.TIMING.SEARCH_RENDER); } /** @@ -92,9 +78,19 @@ class SearchPage extends Component { * @returns {String} header messae */ getCustomHeaderMessage(searchValue = '') { + const { + recentReports, + personalDetails, + userToInvite, + } = getSearchOptions( + this.props.reports, + this.props.personalDetails, + '', + this.props.betas, + ); return getHeaderMessage( - (this.recentReports.length + this.personalDetails.length) !== 0, - Boolean(this.userToInvite), + (recentReports.length + personalDetails.length) !== 0, + Boolean(userToInvite), searchValue, ); } @@ -105,16 +101,16 @@ class SearchPage extends Component { * @returns {Array} */ getSections() { - return this.filterAdapter(''); + // getSections is same to searchSections given empty searchValue + return this.searchSections(); } - /** * Returns the sections needed for the OptionsSelector * @param {String} searchValue * @returns {Array} */ - filterAdapter(searchValue) { + searchSections(searchValue = '') { const { recentReports, personalDetails, @@ -169,31 +165,29 @@ class SearchPage extends Component { return ( {({didScreenTransitionEnd}) => ( - !didScreenTransitionEnd - ? null - : ( - <> - Navigation.dismissModal(true)} + didScreenTransitionEnd && ( + <> + Navigation.dismissModal(true)} + /> + + + {didScreenTransitionEnd && ( + - - - {didScreenTransitionEnd && ( - - )} - - - - ) + )} + + + + ) )} );