Browse Source

simplify web section list

Arnaud Vergnet 2 years ago
parent
commit
35a4b377f8

+ 2
- 2
src/components/Screens/ErrorView.tsx View File

@@ -26,8 +26,8 @@ import * as Animatable from 'react-native-animatable';
26 26
 import { REQUEST_CODES, REQUEST_STATUS } from '../../utils/Requests';
27 27
 
28 28
 type Props = {
29
-  status?: Exclude<REQUEST_STATUS, REQUEST_STATUS.SUCCESS>;
30
-  code?: Exclude<REQUEST_CODES, REQUEST_CODES.SUCCESS>;
29
+  status?: REQUEST_STATUS;
30
+  code?: REQUEST_CODES;
31 31
   icon?: string;
32 32
   message?: string;
33 33
   loading?: boolean;

+ 2
- 2
src/components/Screens/RequestScreen.tsx View File

@@ -4,7 +4,7 @@ import { useRequestLogic } from '../../utils/customHooks';
4 4
 import { useFocusEffect } from '@react-navigation/native';
5 5
 import BasicLoadingScreen from './BasicLoadingScreen';
6 6
 import i18n from 'i18n-js';
7
-import { REQUEST_STATUS } from '../../utils/Requests';
7
+import { REQUEST_CODES, REQUEST_STATUS } from '../../utils/Requests';
8 8
 
9 9
 export type RequestScreenProps<T> = {
10 10
   request: () => Promise<T>;
@@ -13,7 +13,7 @@ export type RequestScreenProps<T> = {
13 13
     loading: boolean,
14 14
     refreshData: (newRequest?: () => Promise<T>) => void,
15 15
     status: REQUEST_STATUS,
16
-    code: number | undefined
16
+    code?: REQUEST_CODES
17 17
   ) => React.ReactElement;
18 18
   cache?: T;
19 19
   onCacheUpdate?: (newCache: T) => void;

+ 42
- 81
src/components/Screens/WebSectionList.tsx View File

@@ -21,22 +21,19 @@ import React, { useState } from 'react';
21 21
 import i18n from 'i18n-js';
22 22
 import { Snackbar } from 'react-native-paper';
23 23
 import {
24
-  NativeScrollEvent,
25
-  NativeSyntheticEvent,
26 24
   RefreshControl,
27 25
   SectionListData,
28
-  SectionListRenderItemInfo,
26
+  SectionListProps,
29 27
   StyleSheet,
30 28
   View,
31 29
 } from 'react-native';
32
-import * as Animatable from 'react-native-animatable';
33 30
 import ErrorView from './ErrorView';
34
-import BasicLoadingScreen from './BasicLoadingScreen';
35 31
 import { TAB_BAR_HEIGHT } from '../Tabbar/CustomTabBar';
36
-import { ERROR_TYPE } from '../../utils/WebData';
37 32
 import CollapsibleSectionList from '../Collapsible/CollapsibleSectionList';
38 33
 import GENERAL_STYLES from '../../constants/Styles';
39
-import RequestScreen from './RequestScreen';
34
+import RequestScreen, { RequestScreenProps } from './RequestScreen';
35
+import { CollapsibleComponentPropsType } from '../Collapsible/CollapsibleComponent';
36
+import { REQUEST_CODES, REQUEST_STATUS } from '../../utils/Requests';
40 37
 
41 38
 export type SectionListDataType<ItemT> = Array<{
42 39
   title: string;
@@ -45,31 +42,36 @@ export type SectionListDataType<ItemT> = Array<{
45 42
   keyExtractor?: (data: ItemT) => string;
46 43
 }>;
47 44
 
48
-type Props<ItemT, RawData> = {
49
-  request: () => Promise<RawData>;
50
-  refreshOnFocus: boolean;
51
-  renderItem: (data: SectionListRenderItemInfo<ItemT>) => React.ReactNode;
52
-  createDataset: (
53
-    data: RawData | undefined,
54
-    isLoading: boolean
55
-  ) => SectionListDataType<ItemT>;
56
-
57
-  onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
58
-  showError?: boolean;
59
-  itemHeight?: number | null;
60
-  autoRefreshTime?: number;
61
-  updateData?: number | string;
62
-  renderListHeaderComponent?: (
63
-    data?: RawData
64
-  ) => React.ComponentType<any> | React.ReactElement | null;
65
-  renderSectionHeader?: (
66
-    data: { section: SectionListData<ItemT> },
67
-    isLoading: boolean
68
-  ) => React.ReactElement | null;
69
-  stickyHeader?: boolean;
70
-  cache?: RawData;
71
-  onCacheUpdate?: (newCache: RawData) => void;
72
-};
45
+type Props<ItemT, RawData> = Omit<
46
+  CollapsibleComponentPropsType,
47
+  'children' | 'paddedProps'
48
+> &
49
+  Omit<
50
+    RequestScreenProps<RawData>,
51
+    | 'render'
52
+    | 'showLoading'
53
+    | 'showError'
54
+    | 'refresh'
55
+    | 'onFinish'
56
+    | 'onMajorError'
57
+  > &
58
+  Omit<
59
+    SectionListProps<ItemT>,
60
+    'sections' | 'getItemLayout' | 'ListHeaderComponent' | 'ListEmptyComponent'
61
+  > & {
62
+    createDataset: (
63
+      data: RawData | undefined,
64
+      isLoading: boolean
65
+    ) => SectionListDataType<ItemT>;
66
+    renderListHeaderComponent?: (
67
+      data?: RawData
68
+    ) => React.ComponentType<any> | React.ReactElement | null;
69
+    renderSectionHeader?: (
70
+      data: { section: SectionListData<ItemT> },
71
+      isLoading: boolean
72
+    ) => React.ReactElement | null;
73
+    itemHeight?: number | null;
74
+  };
73 75
 
74 76
 const styles = StyleSheet.create({
75 77
   container: {
@@ -100,48 +102,12 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
100 102
     };
101 103
   };
102 104
 
103
-  const getRenderSectionHeader = (
104
-    data: { section: SectionListData<ItemT> },
105
-    loading: boolean
106
-  ) => {
107
-    const { renderSectionHeader } = props;
108
-    if (renderSectionHeader) {
109
-      return (
110
-        <Animatable.View
111
-          animation={'fadeInUp'}
112
-          duration={500}
113
-          useNativeDriver={true}
114
-        >
115
-          {renderSectionHeader(data, loading)}
116
-        </Animatable.View>
117
-      );
118
-    }
119
-    return null;
120
-  };
121
-
122
-  const getRenderItem = (data: SectionListRenderItemInfo<ItemT>) => {
123
-    const { renderItem } = props;
124
-    return (
125
-      <Animatable.View
126
-        animation={'fadeInUp'}
127
-        duration={500}
128
-        useNativeDriver={true}
129
-      >
130
-        {renderItem(data)}
131
-      </Animatable.View>
132
-    );
133
-  };
134
-
135
-  const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
136
-    if (props.onScroll) {
137
-      props.onScroll(event);
138
-    }
139
-  };
140
-
141 105
   const render = (
142 106
     data: RawData | undefined,
143 107
     loading: boolean,
144
-    refreshData: (newRequest?: () => Promise<RawData>) => void
108
+    refreshData: (newRequest?: () => Promise<RawData>) => void,
109
+    status: REQUEST_STATUS,
110
+    code?: REQUEST_CODES
145 111
   ) => {
146 112
     const { itemHeight } = props;
147 113
     const dataset = props.createDataset(data, loading);
@@ -150,8 +116,8 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
150 116
     }
151 117
     return (
152 118
       <CollapsibleSectionList
119
+        {...props}
153 120
         sections={dataset}
154
-        extraData={props.updateData}
155 121
         paddedProps={(paddingTop) => ({
156 122
           refreshControl: (
157 123
             <RefreshControl
@@ -161,9 +127,7 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
161 127
             />
162 128
           ),
163 129
         })}
164
-        renderSectionHeader={(info) => getRenderSectionHeader(info, loading)}
165
-        renderItem={getRenderItem}
166
-        stickySectionHeadersEnabled={props.stickyHeader}
130
+        renderItem={props.renderItem}
167 131
         style={styles.container}
168 132
         ListHeaderComponent={
169 133
           props.renderListHeaderComponent != null
@@ -171,11 +135,10 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
171 135
             : null
172 136
         }
173 137
         ListEmptyComponent={
174
-          loading ? (
175
-            <BasicLoadingScreen />
176
-          ) : (
138
+          loading ? undefined : (
177 139
             <ErrorView
178
-              status={ERROR_TYPE.CONNECTION_ERROR}
140
+              status={status}
141
+              code={code}
179 142
               button={{
180 143
                 icon: 'refresh',
181 144
                 text: i18n.t('general.retry'),
@@ -187,8 +150,6 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
187 150
         getItemLayout={
188 151
           itemHeight ? (d, i) => getItemLayout(itemHeight, d, i) : undefined
189 152
         }
190
-        onScroll={onScroll}
191
-        hasTab={true}
192 153
       />
193 154
     );
194 155
   };

+ 10
- 11
src/screens/Home/HomeScreen.tsx View File

@@ -26,7 +26,7 @@ import {
26 26
   StyleSheet,
27 27
 } from 'react-native';
28 28
 import i18n from 'i18n-js';
29
-import { ActivityIndicator, Headline, withTheme } from 'react-native-paper';
29
+import { Headline, withTheme } from 'react-native-paper';
30 30
 import { CommonActions } from '@react-navigation/native';
31 31
 import { StackNavigationProp } from '@react-navigation/stack';
32 32
 import * as Animatable from 'react-native-animatable';
@@ -315,11 +315,11 @@ class HomeScreen extends React.Component<PropsType, StateType> {
315 315
    */
316 316
   getRenderItem = ({ item }: { item: FeedItemType }) => this.getFeedItem(item);
317 317
 
318
-  getRenderSectionHeader = (
319
-    data: { section: SectionListData<FeedItemType> },
320
-    isLoading: boolean
321
-  ) => {
318
+  getRenderSectionHeader = (data: {
319
+    section: SectionListData<FeedItemType>;
320
+  }) => {
322 321
     const { props } = this;
322
+    const icon = data.section.icon;
323 323
     if (data.section.data.length > 0) {
324 324
       return (
325 325
         <Headline style={styles.sectionHeader}>{data.section.title}</Headline>
@@ -335,16 +335,14 @@ class HomeScreen extends React.Component<PropsType, StateType> {
335 335
         >
336 336
           {data.section.title}
337 337
         </Headline>
338
-        {isLoading ? (
339
-          <ActivityIndicator style={styles.activityIndicator} />
340
-        ) : (
338
+        {icon ? (
341 339
           <MaterialCommunityIcons
342
-            name="access-point-network-off"
340
+            name={icon}
343 341
             size={100}
344 342
             color={props.theme.colors.textDisabled}
345 343
             style={GENERAL_STYLES.center}
346 344
           />
347
-        )}
345
+        ) : null}
348 346
       </View>
349 347
     );
350 348
   };
@@ -406,6 +404,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
406 404
   ): Array<{
407 405
     title: string;
408 406
     data: [] | Array<FeedItemType>;
407
+    icon?: string;
409 408
     id: string;
410 409
   }> => {
411 410
     if (fetchedData) {
@@ -433,6 +432,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
433 432
           ? i18n.t('screens.home.feedLoading')
434 433
           : i18n.t('screens.home.feedError'),
435 434
         data: [],
435
+        icon: isLoading ? undefined : 'access-point-network-off',
436 436
         id: SECTIONS_ID[1],
437 437
       },
438 438
     ];
@@ -473,7 +473,6 @@ class HomeScreen extends React.Component<PropsType, StateType> {
473 473
             renderItem={this.getRenderItem}
474 474
             itemHeight={FEED_ITEM_HEIGHT}
475 475
             onScroll={this.onScroll}
476
-            showError={false}
477 476
             renderSectionHeader={this.getRenderSectionHeader}
478 477
             renderListHeaderComponent={this.getListHeader}
479 478
           />

+ 1
- 1
src/screens/Planex/GroupSelectionScreen.tsx View File

@@ -259,7 +259,7 @@ function GroupSelectionScreen() {
259 259
       createDataset={createDataset}
260 260
       refreshOnFocus={true}
261 261
       renderItem={getRenderItem}
262
-      updateData={currentSearchString + favoriteGroups.length}
262
+      extraData={currentSearchString + favoriteGroups.length}
263 263
       cache={groups}
264 264
       onCacheUpdate={setGroups}
265 265
     />

+ 1
- 1
src/screens/Proxiwash/ProxiwashScreen.tsx View File

@@ -512,7 +512,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
512 512
             renderSectionHeader={this.getRenderSectionHeader}
513 513
             autoRefreshTime={REFRESH_TIME}
514 514
             refreshOnFocus={true}
515
-            updateData={state.machinesWatched.length}
515
+            extraData={state.machinesWatched.length}
516 516
           />
517 517
         </View>
518 518
         <MascotPopup

+ 1
- 1
src/screens/Services/Proximo/ProximoListScreen.tsx View File

@@ -367,7 +367,7 @@ function ProximoListScreen(props: Props) {
367 367
         createDataset={createDataset}
368 368
         refreshOnFocus={true}
369 369
         renderItem={getRenderItem}
370
-        updateData={currentSearchString + currentSortMode}
370
+        extraData={currentSearchString + currentSortMode}
371 371
         itemHeight={LIST_ITEM_HEIGHT}
372 372
         cache={articles}
373 373
         onCacheUpdate={setArticles}

+ 1
- 1
src/screens/Services/SelfMenuScreen.tsx View File

@@ -201,7 +201,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
201 201
         refreshOnFocus={true}
202 202
         renderItem={this.getRenderItem}
203 203
         renderSectionHeader={this.getRenderSectionHeader}
204
-        stickyHeader={true}
204
+        stickySectionHeadersEnabled={true}
205 205
       />
206 206
     );
207 207
   }

Loading…
Cancel
Save