Improve planex group search performance

This commit is contained in:
Arnaud Vergnet 2021-05-11 16:43:43 +02:00
parent ed4bb216a0
commit e08fdc7c37
2 changed files with 32 additions and 50 deletions

View file

@ -20,7 +20,6 @@
import * as React from 'react'; import * as React from 'react';
import { List, withTheme } from 'react-native-paper'; import { List, withTheme } from 'react-native-paper';
import { FlatList, StyleSheet, View } from 'react-native'; import { FlatList, StyleSheet, View } from 'react-native';
import { stringMatchQuery } from '../../../utils/Search';
import GroupListItem from './GroupListItem'; import GroupListItem from './GroupListItem';
import AnimatedAccordion from '../../Animations/AnimatedAccordion'; import AnimatedAccordion from '../../Animations/AnimatedAccordion';
import type { import type {
@ -40,6 +39,9 @@ type PropsType = {
const LIST_ITEM_HEIGHT = 64; const LIST_ITEM_HEIGHT = 64;
const REPLACE_REGEX = /_/g; const REPLACE_REGEX = /_/g;
// The minimum number of characters to type before expanding the accordion
// This prevents expanding too many items at once
const MIN_SEARCH_SIZE_EXPAND = 2;
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -76,18 +78,6 @@ class GroupListAccordion extends React.Component<PropsType> {
); );
}; };
getData(): Array<PlanexGroupType> {
const { props } = this;
const originalData = props.item.content;
const displayData: Array<PlanexGroupType> = [];
originalData.forEach((data: PlanexGroupType) => {
if (stringMatchQuery(data.name, props.currentSearchString)) {
displayData.push(data);
}
});
return displayData;
}
itemLayout = ( itemLayout = (
_data: Array<PlanexGroupType> | null | undefined, _data: Array<PlanexGroupType> | null | undefined,
index: number index: number
@ -129,13 +119,13 @@ class GroupListAccordion extends React.Component<PropsType> {
} }
unmountWhenCollapsed={!isFavorite} // Only render list if expanded for increased performance unmountWhenCollapsed={!isFavorite} // Only render list if expanded for increased performance
opened={ opened={
props.currentSearchString.length > 0 || props.currentSearchString.length >= MIN_SEARCH_SIZE_EXPAND ||
(isFavorite && !isEmptyFavorite) (isFavorite && !isEmptyFavorite)
} }
enabled={!isEmptyFavorite} enabled={!isEmptyFavorite}
> >
<FlatList <FlatList
data={this.getData()} data={props.item.content}
extraData={props.currentSearchString + props.favorites.length} extraData={props.currentSearchString + props.favorites.length}
renderItem={this.getRenderItem} renderItem={this.getRenderItem}
keyExtractor={this.keyExtractor} keyExtractor={this.keyExtractor}

View file

@ -93,12 +93,7 @@ function GroupSelectionScreen() {
* @param item The article to render * @param item The article to render
* @return {*} * @return {*}
*/ */
const getRenderItem = ({ item }: { item: PlanexGroupCategoryType }) => { const getRenderItem = ({ item }: { item: PlanexGroupCategoryType }) => (
if (
shouldDisplayAccordion(item) ||
(item.id === 0 && item.content.length === 0)
) {
return (
<GroupListAccordion <GroupListAccordion
item={item} item={item}
favorites={[...favoriteGroups]} favorites={[...favoriteGroups]}
@ -107,9 +102,6 @@ function GroupSelectionScreen() {
currentSearchString={currentSearchString} currentSearchString={currentSearchString}
/> />
); );
}
return null;
};
/** /**
* Creates the dataset to be used in the FlatList * Creates the dataset to be used in the FlatList
@ -184,23 +176,6 @@ function GroupSelectionScreen() {
} }
}; };
/**
* Checks whether to display the given group category, depending on user search query
*
* @param item The group category
* @returns {boolean}
*/
const shouldDisplayAccordion = (item: PlanexGroupCategoryType): boolean => {
let shouldDisplay = false;
for (let i = 0; i < item.content.length; i += 1) {
if (stringMatchQuery(item.content[i].name, currentSearchString)) {
shouldDisplay = true;
break;
}
}
return shouldDisplay;
};
/** /**
* Generates the dataset to be used in the FlatList. * Generates the dataset to be used in the FlatList.
* This improves formatting of group names, sorts alphabetically the categories, and adds favorites at the top. * This improves formatting of group names, sorts alphabetically the categories, and adds favorites at the top.
@ -212,13 +187,30 @@ function GroupSelectionScreen() {
fetchedData: PlanexGroupsType | undefined fetchedData: PlanexGroupsType | undefined
): Array<PlanexGroupCategoryType> => { ): Array<PlanexGroupCategoryType> => {
const data: Array<PlanexGroupCategoryType> = []; const data: Array<PlanexGroupCategoryType> = [];
if (fetchedData) { if (fetchedData) {
// Convert the object into an array
Object.values(fetchedData).forEach( Object.values(fetchedData).forEach(
(category: PlanexGroupCategoryType) => { (category: PlanexGroupCategoryType) => {
data.push(category); const content: Array<PlanexGroupType> = [];
// Filter groups matching the search query
category.content.forEach((g: PlanexGroupType) => {
if (stringMatchQuery(g.name, currentSearchString)) {
content.push(g);
}
});
// Only add categories with groups matching the query
if (content.length > 0) {
data.push({
id: category.id,
name: category.name,
content: content,
});
}
} }
); );
data.sort(sortName); data.sort(sortName);
// Add the favorites at the top
data.unshift({ data.unshift({
name: i18n.t('screens.planex.favorites.title'), name: i18n.t('screens.planex.favorites.title'),
id: 0, id: 0,