From c48887a0d80581bc399fab9591d37b0868281f36 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Sat, 4 Apr 2020 11:55:51 +0200 Subject: [PATCH] Improved search performance --- components/Lists/ClubListItem.js | 6 +++-- navigation/DrawerNavigator.js | 2 -- screens/Amicale/ClubDisplayScreen.js | 19 +++++++++----- screens/Amicale/ClubListScreen.js | 38 ++++++++-------------------- utils/Search.js | 24 ++++++++++++++++++ 5 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 utils/Search.js diff --git a/components/Lists/ClubListItem.js b/components/Lists/ClubListItem.js index dfa05bb..de4c3bf 100644 --- a/components/Lists/ClubListItem.js +++ b/components/Lists/ClubListItem.js @@ -25,8 +25,10 @@ class ClubListItem extends React.PureComponent { getCategoriesRender(categories: Array) { let final = []; for (let i = 0; i < categories.length; i++) { - if (categories[i] !== null) - final.push(this.props.chipRender(this.props.categoryTranslator(categories[i]))); + if (categories[i] !== null){ + const category = this.props.categoryTranslator(categories[i]); + final.push(this.props.chipRender(category, this.props.item.id + ':' + category.id)); + } } return {final}; } diff --git a/navigation/DrawerNavigator.js b/navigation/DrawerNavigator.js index b5796c0..a3c8147 100644 --- a/navigation/DrawerNavigator.js +++ b/navigation/DrawerNavigator.js @@ -262,10 +262,8 @@ function ClubStackComponent() { name="ClubDisplayScreen" component={ClubDisplayScreen} options={({navigation}) => { - const openDrawer = getDrawerButton.bind(this, navigation); return { title: "", - headerLeft: openDrawer, ...TransitionPresets.ModalSlideFromBottomIOS, }; }} diff --git a/screens/Amicale/ClubDisplayScreen.js b/screens/Amicale/ClubDisplayScreen.js index 8da0375..460e6d7 100644 --- a/screens/Amicale/ClubDisplayScreen.js +++ b/screens/Amicale/ClubDisplayScreen.js @@ -52,19 +52,26 @@ class ClubDisplayScreen extends React.Component { return ""; } - getCategoriesRender(categories: Array) { + getCategoriesRender(categories: Array) { let final = []; for (let i = 0; i < categories.length; i++) { - if (categories[i] !== null) - final.push({this.getCategoryName(categories[i])}); + if (categories[i] !== null) { + final.push( + + {this.getCategoryName(categories[i])} + + ); + } } return {final}; } - getResponsiblesRender(resp: Array) { + getManagersRender(resp: Array) { let final = []; for (let i = 0; i < resp.length; i++) { - final.push({resp[i]}) + final.push({resp[i]}) } const hasManagers = resp.length > 0; return ( @@ -120,7 +127,7 @@ class ClubDisplayScreen extends React.Component { onLinkPress={openWebLink}/> : } - {this.getResponsiblesRender(this.displayData.responsibles)} + {this.getManagersRender(this.displayData.responsibles)} ); } diff --git a/screens/Amicale/ClubListScreen.js b/screens/Amicale/ClubListScreen.js index fef4a97..39097f1 100644 --- a/screens/Amicale/ClubListScreen.js +++ b/screens/Amicale/ClubListScreen.js @@ -6,6 +6,7 @@ import {Chip, Searchbar, withTheme} from 'react-native-paper'; import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen"; import i18n from "i18n-js"; import ClubListItem from "../../components/Lists/ClubListItem"; +import {isItemInCategoryFilter, stringMatchQuery} from "../../utils/Search"; type Props = { navigation: Object, @@ -27,7 +28,6 @@ class ClubListScreen extends React.Component { colors: Object; getRenderItem: Function; - originalData: Array; categories: Array; constructor(props) { @@ -69,26 +69,17 @@ class ClubListScreen extends React.Component { * @param str The new search string */ onSearchStringChange = (str: string) => { - this.updateFilteredData(this.sanitizeString(str), null); + this.updateFilteredData(str, null); }; - /** - * 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, ""); - } - keyExtractor = (item: Object) => { - return item.name + item.logo; + return item.id.toString(); }; getScreen = (data: Object) => { this.categories = data.categories; return ( + //$FlowFixMe { if (index === -1) newCategoriesState.push(categoryId); else - newCategoriesState.splice(index); + newCategoriesState.splice(index,1); } if (filterStr !== null || categoryId !== null) this.setState({ @@ -121,21 +112,14 @@ class ClubListScreen extends React.Component { }) } - isItemInCategoryFilter(categories: Array) { - for (const category of categories) { - if (this.state.currentlySelectedCategories.indexOf(category) !== -1) - return true; - } - return false; - } - - getChipRender = (category: Object) => { + getChipRender = (category: Object, key: string) => { const onPress = this.onChipSelect.bind(this, category.id); return {category.name} ; @@ -144,7 +128,7 @@ class ClubListScreen extends React.Component { getListHeader() { let final = []; for (let i = 0; i < this.categories.length; i++) { - final.push(this.getChipRender(this.categories[i])); + final.push(this.getChipRender(this.categories[i], this.categories[i].id)); } return { shouldRenderItem(item) { let shouldRender = this.state.currentlySelectedCategories.length === 0 - || this.isItemInCategoryFilter(item.category); + || isItemInCategoryFilter(this.state.currentlySelectedCategories, item.category); if (shouldRender) - shouldRender = this.sanitizeString(item.name).includes(this.state.currentSearchString); + shouldRender = stringMatchQuery(item.name, this.state.currentSearchString); return shouldRender; } diff --git a/utils/Search.js b/utils/Search.js new file mode 100644 index 0000000..625c75c --- /dev/null +++ b/utils/Search.js @@ -0,0 +1,24 @@ + + + +/** + * Sanitizes the given string to improve search performance + * + * @param str The string to sanitize + * @return {string} The sanitized string + */ +export function sanitizeString(str: string): string { + return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""); +} + +export function stringMatchQuery(str: string, query: string) { + return sanitizeString(str).includes(sanitizeString(query)); +} + +export function isItemInCategoryFilter(filter: Array, categories: Array) { + for (const category of categories) { + if (filter.indexOf(category) !== -1) + return true; + } + return false; +}