|
@@ -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
|
};
|