From ba893495e16ee33f104ddb873267fa418aafac3d Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Sat, 4 Apr 2020 20:17:55 +0200 Subject: [PATCH] Improved proximo search and display performance --- components/Lists/ProximoListItem.js | 40 ++++++++ screens/Proximo/ProximoListScreen.js | 131 +++++++++------------------ 2 files changed, 83 insertions(+), 88 deletions(-) create mode 100644 components/Lists/ProximoListItem.js diff --git a/components/Lists/ProximoListItem.js b/components/Lists/ProximoListItem.js new file mode 100644 index 0000000..52a6986 --- /dev/null +++ b/components/Lists/ProximoListItem.js @@ -0,0 +1,40 @@ +// @flow + +import * as React from 'react'; +import {Avatar, List, Text, withTheme} from 'react-native-paper'; +import i18n from "i18n-js"; + +type Props = { + onPress: Function, + color: string, + item: Object, +} + +class ProximoListItem extends React.PureComponent { + + colors: Object; + + constructor(props) { + super(props); + this.colors = props.theme.colors; + } + + render() { + return ( + } + right={() => + + {this.props.item.price}€ + } + /> + ); + } +} + +export default withTheme(ProximoListItem); diff --git a/screens/Proximo/ProximoListScreen.js b/screens/Proximo/ProximoListScreen.js index 17cfbea..e076270 100644 --- a/screens/Proximo/ProximoListScreen.js +++ b/screens/Proximo/ProximoListScreen.js @@ -1,11 +1,12 @@ // @flow import * as React from 'react'; -import {Image, Platform, ScrollView, View} from "react-native"; +import {FlatList, Image, Platform, ScrollView, View} from "react-native"; import i18n from "i18n-js"; import CustomModal from "../../components/Custom/CustomModal"; -import {Avatar, IconButton, List, RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper"; -import PureFlatList from "../../components/Lists/PureFlatList"; +import {IconButton, RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper"; +import {stringMatchQuery} from "../../utils/Search"; +import ProximoListItem from "../../components/Lists/ProximoListItem"; function sortPrice(a, b) { return a.price - b.price; @@ -39,7 +40,7 @@ type Props = { type State = { currentSortMode: number, modalCurrentDisplayItem: React.Node, - currentlyDisplayedData: Array, + currentSearchString: string, }; /** @@ -48,30 +49,21 @@ type State = { class ProximoListScreen extends React.Component { modalRef: Object; - originalData: Array; + listData: Array; shouldFocusSearchBar: boolean; - onSearchStringChange: Function; - onSortMenuPress: Function; - renderItem: Function; - onModalRef: Function; - colors: Object; constructor(props) { super(props); - this.originalData = this.props.route.params['data']['data']; + this.listData = this.props.route.params['data']['data']; this.shouldFocusSearchBar = this.props.route.params['shouldFocusSearchBar']; this.state = { - currentlyDisplayedData: this.originalData.sort(sortName), + currentSearchString: '', currentSortMode: 3, modalCurrentDisplayItem: null, }; - this.onSearchStringChange = this.onSearchStringChange.bind(this); - this.onSortMenuPress = this.onSortMenuPress.bind(this); - this.renderItem = this.renderItem.bind(this); - this.onModalRef = this.onModalRef.bind(this); this.colors = props.theme.colors; } @@ -80,11 +72,9 @@ class ProximoListScreen extends React.Component { * Creates the header content */ componentDidMount() { - const button = this.getSortMenuButton.bind(this); - const title = this.getSearchBar.bind(this); this.props.navigation.setOptions({ - headerRight: button, - headerTitle: title, + headerRight: this.getSortMenuButton, + headerTitle: this.getSearchBar, headerBackTitleVisible: false, headerTitleContainerStyle: Platform.OS === 'ios' ? {marginHorizontal: 0, width: '70%'} : @@ -97,21 +87,21 @@ class ProximoListScreen extends React.Component { * * @return {*} */ - getSearchBar() { + getSearchBar = () => { return ( ); - } + }; /** * Gets the sort menu header button * * @return {*} */ - getSortMenuButton() { + getSortMenuButton = () => { return ( { onPress={this.onSortMenuPress} /> ); - } + }; /** * Callback used when clicking on the sort menu button. * It will open the modal to show a sort selection */ - onSortMenuPress() { + onSortMenuPress = () => { this.setState({ modalCurrentDisplayItem: this.getModalSortMenu() }); if (this.modalRef) { this.modalRef.open(); } - } + }; /** * Sets the current sort mode. @@ -144,19 +134,18 @@ class ProximoListScreen extends React.Component { this.setState({ currentSortMode: mode, }); - let data = this.state.currentlyDisplayedData; switch (mode) { case 1: - data.sort(sortPrice); + this.listData.sort(sortPrice); break; case 2: - data.sort(sortPriceReverse); + this.listData.sort(sortPriceReverse); break; case 3: - data.sort(sortName); + this.listData.sort(sortName); break; case 4: - data.sort(sortNameReverse); + this.listData.sort(sortNameReverse); break; } if (this.modalRef && mode !== this.state.currentSortMode) { @@ -181,46 +170,14 @@ class ProximoListScreen extends React.Component { return color; } - /** - * Sanitizes the given string to improve search performance - * - * @param str The string to sanitize - * @return {string} The sanitized string - */ - sanitizeString(str: string): string { - return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); - } - - /** - * Returns only articles whose name contains the given string. - * Case and accents insensitive. - * - * @param str The string used to filter article names - * @returns {[]} - */ - filterData(str: string) { - let filteredData = []; - const testStr = this.sanitizeString(str); - const articles = this.originalData; - for (const article of articles) { - const name = this.sanitizeString(article.name); - if (name.includes(testStr)) { - filteredData.push(article) - } - } - return filteredData; - } - /** * Callback used when the search changes * * @param str The new search string */ - onSearchStringChange(str: string) { - this.setState({ - currentlyDisplayedData: this.filterData(str) - }) - } + onSearchStringChange = (str: string) => { + this.setState({currentSearchString: str}) + }; /** * Gets the modal content depending on the given article @@ -333,23 +290,20 @@ class ProximoListScreen extends React.Component { * @param item The article to render * @return {*} */ - renderItem({item}: Object) { - const onPress = this.onListItemPress.bind(this, item); - return ( - } - right={() => - - {item.price}€ - } - /> - ); - } + renderItem = ({item}: Object) => { + if (stringMatchQuery(item.name, this.state.currentSearchString)) { + const onPress = this.onListItemPress.bind(this, item); + const color = this.getStockColor(parseInt(item.quantity)); + return ( + + ); + } else + return null; + }; /** * Extracts a key for the given article @@ -366,9 +320,9 @@ class ProximoListScreen extends React.Component { * * @param ref */ - onModalRef(ref: Object) { + onModalRef = (ref: Object) => { this.modalRef = ref; - } + }; render() { return ( @@ -378,11 +332,12 @@ class ProximoListScreen extends React.Component { {this.state.modalCurrentDisplayItem} - );