Browse Source

Improved search performance

Arnaud Vergnet 1 year ago
parent
commit
c48887a0d8

+ 4
- 2
components/Lists/ClubListItem.js View File

@@ -25,8 +25,10 @@ class ClubListItem extends React.PureComponent<Props> {
25 25
     getCategoriesRender(categories: Array<number | null>) {
26 26
         let final = [];
27 27
         for (let i = 0; i < categories.length; i++) {
28
-            if (categories[i] !== null)
29
-                final.push(this.props.chipRender(this.props.categoryTranslator(categories[i])));
28
+            if (categories[i] !== null){
29
+                const category = this.props.categoryTranslator(categories[i]);
30
+                final.push(this.props.chipRender(category, this.props.item.id + ':' + category.id));
31
+            }
30 32
         }
31 33
         return <View style={{flexDirection: 'row'}}>{final}</View>;
32 34
     }

+ 0
- 2
navigation/DrawerNavigator.js View File

@@ -262,10 +262,8 @@ function ClubStackComponent() {
262 262
                 name="ClubDisplayScreen"
263 263
                 component={ClubDisplayScreen}
264 264
                 options={({navigation}) => {
265
-                    const openDrawer = getDrawerButton.bind(this, navigation);
266 265
                     return {
267 266
                         title: "",
268
-                        headerLeft: openDrawer,
269 267
                         ...TransitionPresets.ModalSlideFromBottomIOS,
270 268
                     };
271 269
                 }}

+ 13
- 6
screens/Amicale/ClubDisplayScreen.js View File

@@ -52,19 +52,26 @@ class ClubDisplayScreen extends React.Component<Props, State> {
52 52
         return "";
53 53
     }
54 54
 
55
-    getCategoriesRender(categories: Array<number|null>) {
55
+    getCategoriesRender(categories: Array<number | null>) {
56 56
         let final = [];
57 57
         for (let i = 0; i < categories.length; i++) {
58
-            if (categories[i] !== null)
59
-                final.push(<Chip style={{marginRight: 5}}>{this.getCategoryName(categories[i])}</Chip>);
58
+            if (categories[i] !== null) {
59
+                final.push(
60
+                    <Chip
61
+                        style={{marginRight: 5}}
62
+                        key={i.toString()}>
63
+                        {this.getCategoryName(categories[i])}
64
+                    </Chip>
65
+                );
66
+            }
60 67
         }
61 68
         return <View style={{flexDirection: 'row', marginTop: 5}}>{final}</View>;
62 69
     }
63 70
 
64
-    getResponsiblesRender(resp: Array<string>) {
71
+    getManagersRender(resp: Array<string>) {
65 72
         let final = [];
66 73
         for (let i = 0; i < resp.length; i++) {
67
-            final.push(<Paragraph>{resp[i]}</Paragraph>)
74
+            final.push(<Paragraph key={i.toString()}>{resp[i]}</Paragraph>)
68 75
         }
69 76
         const hasManagers = resp.length > 0;
70 77
         return (
@@ -120,7 +127,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
120 127
                               onLinkPress={openWebLink}/>
121 128
                     </Card.Content>
122 129
                     : <View/>}
123
-                {this.getResponsiblesRender(this.displayData.responsibles)}
130
+                {this.getManagersRender(this.displayData.responsibles)}
124 131
             </ScrollView>
125 132
         );
126 133
     }

+ 11
- 27
screens/Amicale/ClubListScreen.js View File

@@ -6,6 +6,7 @@ import {Chip, Searchbar, withTheme} from 'react-native-paper';
6 6
 import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
7 7
 import i18n from "i18n-js";
8 8
 import ClubListItem from "../../components/Lists/ClubListItem";
9
+import {isItemInCategoryFilter, stringMatchQuery} from "../../utils/Search";
9 10
 
10 11
 type Props = {
11 12
     navigation: Object,
@@ -27,7 +28,6 @@ class ClubListScreen extends React.Component<Props, State> {
27 28
     colors: Object;
28 29
 
29 30
     getRenderItem: Function;
30
-    originalData: Array<Object>;
31 31
     categories: Array<Object>;
32 32
 
33 33
     constructor(props) {
@@ -69,26 +69,17 @@ class ClubListScreen extends React.Component<Props, State> {
69 69
      * @param str The new search string
70 70
      */
71 71
     onSearchStringChange = (str: string) => {
72
-        this.updateFilteredData(this.sanitizeString(str), null);
72
+        this.updateFilteredData(str, null);
73 73
     };
74 74
 
75
-    /**
76
-     * Sanitizes the given string to improve search performance
77
-     *
78
-     * @param str The string to sanitize
79
-     * @return {string} The sanitized string
80
-     */
81
-    sanitizeString(str: string): string {
82
-        return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
83
-    }
84
-
85 75
     keyExtractor = (item: Object) => {
86
-        return item.name + item.logo;
76
+        return item.id.toString();
87 77
     };
88 78
 
89 79
     getScreen = (data: Object) => {
90 80
         this.categories = data.categories;
91 81
         return (
82
+            //$FlowFixMe
92 83
             <FlatList
93 84
                 data={data.clubs}
94 85
                 keyExtractor={this.keyExtractor}
@@ -112,7 +103,7 @@ class ClubListScreen extends React.Component<Props, State> {
112 103
             if (index === -1)
113 104
                 newCategoriesState.push(categoryId);
114 105
             else
115
-                newCategoriesState.splice(index);
106
+                newCategoriesState.splice(index,1);
116 107
         }
117 108
         if (filterStr !== null || categoryId !== null)
118 109
             this.setState({
@@ -121,21 +112,14 @@ class ClubListScreen extends React.Component<Props, State> {
121 112
             })
122 113
     }
123 114
 
124
-    isItemInCategoryFilter(categories: Array<string>) {
125
-        for (const category of categories) {
126
-            if (this.state.currentlySelectedCategories.indexOf(category) !== -1)
127
-                return true;
128
-        }
129
-        return false;
130
-    }
131
-
132
-    getChipRender = (category: Object) => {
115
+    getChipRender = (category: Object, key: string) => {
133 116
         const onPress = this.onChipSelect.bind(this, category.id);
134 117
         return <Chip
135
-            selected={this.isItemInCategoryFilter([category.id])}
118
+            selected={isItemInCategoryFilter(this.state.currentlySelectedCategories, [category.id])}
136 119
             mode={'outlined'}
137 120
             onPress={onPress}
138 121
             style={{marginRight: 5, marginBottom: 5}}
122
+            key={key}
139 123
         >
140 124
             {category.name}
141 125
         </Chip>;
@@ -144,7 +128,7 @@ class ClubListScreen extends React.Component<Props, State> {
144 128
     getListHeader() {
145 129
         let final = [];
146 130
         for (let i = 0; i < this.categories.length; i++) {
147
-            final.push(this.getChipRender(this.categories[i]));
131
+            final.push(this.getChipRender(this.categories[i], this.categories[i].id));
148 132
         }
149 133
         return <View style={{
150 134
             justifyContent: 'space-around',
@@ -163,9 +147,9 @@ class ClubListScreen extends React.Component<Props, State> {
163 147
 
164 148
     shouldRenderItem(item) {
165 149
         let shouldRender = this.state.currentlySelectedCategories.length === 0
166
-            || this.isItemInCategoryFilter(item.category);
150
+            || isItemInCategoryFilter(this.state.currentlySelectedCategories, item.category);
167 151
         if (shouldRender)
168
-            shouldRender = this.sanitizeString(item.name).includes(this.state.currentSearchString);
152
+            shouldRender = stringMatchQuery(item.name, this.state.currentSearchString);
169 153
         return shouldRender;
170 154
     }
171 155
 

+ 24
- 0
utils/Search.js View File

@@ -0,0 +1,24 @@
1
+
2
+
3
+
4
+/**
5
+ * Sanitizes the given string to improve search performance
6
+ *
7
+ * @param str The string to sanitize
8
+ * @return {string} The sanitized string
9
+ */
10
+export function sanitizeString(str: string): string {
11
+    return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
12
+}
13
+
14
+export function stringMatchQuery(str: string, query: string) {
15
+    return sanitizeString(str).includes(sanitizeString(query));
16
+}
17
+
18
+export function isItemInCategoryFilter(filter: Array<string>, categories: Array<string>) {
19
+    for (const category of categories) {
20
+        if (filter.indexOf(category) !== -1)
21
+            return true;
22
+    }
23
+    return false;
24
+}

Loading…
Cancel
Save