Browse Source

Use flatlist empty list render to display errors and loading

Arnaud Vergnet 1 year ago
parent
commit
784872ed96

+ 0
- 1
components/Custom/NetworkErrorComponent.js View File

@@ -7,7 +7,6 @@ import {MaterialCommunityIcons} from "@expo/vector-icons";
7 7
 import i18n from 'i18n-js';
8 8
 
9 9
 type Props = {
10
-    navigation: Object,
11 10
     message: string,
12 11
     icon: string,
13 12
     onRefresh: Function,

+ 0
- 54
components/Lists/EmptyWebSectionListItem.js View File

@@ -1,54 +0,0 @@
1
-import * as React from 'react';
2
-import {ActivityIndicator, Subheading, withTheme} from 'react-native-paper';
3
-import {StyleSheet, View} from "react-native";
4
-import {MaterialCommunityIcons} from "@expo/vector-icons";
5
-
6
-/**
7
- * Component used to display a message when a list is empty
8
- *
9
- * @param props Props to pass to the component
10
- * @return {*}
11
- */
12
-function EmptyWebSectionListItem(props: { text: string, icon: string, refreshing: boolean, theme: {} }) {
13
-    const {colors} = props.theme;
14
-    return (
15
-        <View>
16
-            <View style={styles.iconContainer}>
17
-                {props.refreshing ?
18
-                    <ActivityIndicator
19
-                        animating={true}
20
-                        size={'large'}
21
-                        color={colors.primary}/>
22
-                    :
23
-                    <MaterialCommunityIcons
24
-                        name={props.icon}
25
-                        size={100}
26
-                        color={colors.textDisabled}/>}
27
-            </View>
28
-
29
-            <Subheading style={{
30
-                ...styles.subheading,
31
-                color: colors.textDisabled
32
-            }}>
33
-                {props.text}
34
-            </Subheading>
35
-        </View>
36
-    );
37
-}
38
-
39
-const styles = StyleSheet.create({
40
-    iconContainer: {
41
-        justifyContent: 'center',
42
-        alignItems: 'center',
43
-        width: '100%',
44
-        height: 100,
45
-        marginBottom: 20
46
-    },
47
-    subheading: {
48
-        textAlign: 'center',
49
-        marginRight: 20,
50
-        marginLeft: 20,
51
-    }
52
-});
53
-
54
-export default withTheme(EmptyWebSectionListItem);

+ 19
- 67
components/Lists/WebSectionList.js View File

@@ -5,7 +5,8 @@ import {readData} from "../../utils/WebData";
5 5
 import i18n from "i18n-js";
6 6
 import {Snackbar} from 'react-native-paper';
7 7
 import {RefreshControl, SectionList, View} from "react-native";
8
-import EmptyWebSectionListItem from "./EmptyWebSectionListItem";
8
+import NetworkErrorComponent from "../Custom/NetworkErrorComponent";
9
+import BasicLoadingScreen from "../Custom/BasicLoadingScreen";
9 10
 
10 11
 type Props = {
11 12
     navigation: Object,
@@ -22,7 +23,7 @@ type Props = {
22 23
 type State = {
23 24
     refreshing: boolean,
24 25
     firstLoading: boolean,
25
-    fetchedData: Object,
26
+    fetchedData: ?Object,
26 27
     snackbarVisible: boolean
27 28
 };
28 29
 
@@ -48,14 +49,13 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
48 49
     state = {
49 50
         refreshing: false,
50 51
         firstLoading: true,
51
-        fetchedData: {},
52
+        fetchedData: undefined,
52 53
         snackbarVisible: false
53 54
     };
54 55
 
55 56
     onRefresh: Function;
56 57
     onFetchSuccess: Function;
57 58
     onFetchError: Function;
58
-    getEmptyRenderItem: Function;
59 59
     getEmptySectionHeader: Function;
60 60
     showSnackBar: Function;
61 61
     hideSnackBar: Function;
@@ -66,7 +66,6 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
66 66
         this.onRefresh = this.onRefresh.bind(this);
67 67
         this.onFetchSuccess = this.onFetchSuccess.bind(this);
68 68
         this.onFetchError = this.onFetchError.bind(this);
69
-        this.getEmptyRenderItem = this.getEmptyRenderItem.bind(this);
70 69
         this.getEmptySectionHeader = this.getEmptySectionHeader.bind(this);
71 70
         this.showSnackBar = this.showSnackBar.bind(this);
72 71
         this.hideSnackBar = this.hideSnackBar.bind(this);
@@ -123,7 +122,7 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
123 122
      */
124 123
     onFetchError() {
125 124
         this.setState({
126
-            fetchedData: {},
125
+            fetchedData: undefined,
127 126
             refreshing: false,
128 127
             firstLoading: false
129 128
         });
@@ -158,57 +157,6 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
158 157
     }
159 158
 
160 159
     /**
161
-     * Gets an empty render item
162
-     *
163
-     * @param item The data to display
164
-     * @return {*}
165
-     */
166
-    getEmptyRenderItem({item}: Object) {
167
-        return (
168
-            <EmptyWebSectionListItem
169
-                text={item.text}
170
-                icon={item.icon}
171
-                refreshing={this.state.refreshing}
172
-            />
173
-        );
174
-    }
175
-
176
-    /**
177
-     * Creates an empty dataset
178
-     *
179
-     * @return {*}
180
-     */
181
-    createEmptyDataset() {
182
-        return [
183
-            {
184
-                title: '',
185
-                data: [
186
-                    {
187
-                        text: this.state.refreshing ?
188
-                            i18n.t('general.loading') :
189
-                            i18n.t('general.networkError'),
190
-                        isSpinner: this.state.refreshing,
191
-                        icon: this.state.refreshing ?
192
-                            'refresh' :
193
-                            'access-point-network-off'
194
-                    }
195
-                ],
196
-                keyExtractor: this.datasetKeyExtractor,
197
-            }
198
-        ];
199
-    }
200
-
201
-    /**
202
-     * Extracts a key from the given item
203
-     *
204
-     * @param item The item to extract the key from
205
-     * @return {string} The extracted key
206
-     */
207
-    datasetKeyExtractor(item: Object): string {
208
-        return item.text
209
-    }
210
-
211
-    /**
212 160
      * Shows the error popup
213 161
      */
214 162
     showSnackBar() {
@@ -223,11 +171,10 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
223 171
     }
224 172
 
225 173
     render() {
226
-        let dataset = this.props.createDataset(this.state.fetchedData);
227
-        const isEmpty = dataset[0].data.length === 0;
228
-        const shouldRenderHeader = !isEmpty && (this.props.renderSectionHeader !== null);
229
-        if (isEmpty)
230
-            dataset = this.createEmptyDataset();
174
+        let dataset = [];
175
+        if (this.state.fetchedData !== undefined)
176
+            dataset = this.props.createDataset(this.state.fetchedData);
177
+        const shouldRenderHeader = this.props.renderSectionHeader !== null;
231 178
         return (
232 179
             <View>
233 180
                 <Snackbar
@@ -241,6 +188,7 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
241 188
                 >
242 189
                     {i18n.t("homeScreen.listUpdateFail")}
243 190
                 </Snackbar>
191
+                {/*$FlowFixMe*/}
244 192
                 <SectionList
245 193
                     sections={dataset}
246 194
                     refreshControl={
@@ -252,12 +200,16 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
252 200
                     //$FlowFixMe
253 201
                     renderSectionHeader={shouldRenderHeader ? this.props.renderSectionHeader : this.getEmptySectionHeader}
254 202
                     //$FlowFixMe
255
-                    renderItem={isEmpty ? this.getEmptyRenderItem : this.props.renderItem}
256
-                    style={{minHeight: 300, width: '100%'}}
203
+                    renderItem={this.props.renderItem}
257 204
                     stickySectionHeadersEnabled={this.props.stickyHeader}
258
-                    contentContainerStyle={
259
-                        isEmpty ?
260
-                            {flexGrow: 1, justifyContent: 'center', alignItems: 'center'} : {}
205
+                    contentContainerStyle={{minHeight: '100%'}}
206
+                    style={{minHeight: '100%'}}
207
+                    ListEmptyComponent={this.state.refreshing
208
+                        ? <BasicLoadingScreen/>
209
+                        : <NetworkErrorComponent
210
+                            message={i18n.t('general.networkError')}
211
+                            icon={"access-point-network-off"}
212
+                            onRefresh={this.onRefresh}/>
261 213
                     }
262 214
                 />
263 215
             </View>

Loading…
Cancel
Save