forked from vergnet/application-amicale
Improve planex group search performance
This commit is contained in:
parent
ed4bb216a0
commit
e08fdc7c37
2 changed files with 32 additions and 50 deletions
|
@ -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}
|
||||||
|
|
|
@ -93,23 +93,15 @@ 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 (
|
<GroupListAccordion
|
||||||
shouldDisplayAccordion(item) ||
|
item={item}
|
||||||
(item.id === 0 && item.content.length === 0)
|
favorites={[...favoriteGroups]}
|
||||||
) {
|
onGroupPress={onListItemPress}
|
||||||
return (
|
onFavoritePress={onListFavoritePress}
|
||||||
<GroupListAccordion
|
currentSearchString={currentSearchString}
|
||||||
item={item}
|
/>
|
||||||
favorites={[...favoriteGroups]}
|
);
|
||||||
onGroupPress={onListItemPress}
|
|
||||||
onFavoritePress={onListFavoritePress}
|
|
||||||
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,
|
||||||
|
|
Loading…
Reference in a new issue