|
@@ -17,10 +17,8 @@
|
17
|
17
|
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
18
|
18
|
*/
|
19
|
19
|
|
20
|
|
-// @flow
|
21
|
|
-
|
22
|
20
|
import * as React from 'react';
|
23
|
|
-import {FlatList} from 'react-native';
|
|
21
|
+import {FlatList, NativeScrollEvent, NativeSyntheticEvent} from 'react-native';
|
24
|
22
|
import i18n from 'i18n-js';
|
25
|
23
|
import {ActivityIndicator, Headline, withTheme} from 'react-native-paper';
|
26
|
24
|
import {CommonActions} from '@react-navigation/native';
|
|
@@ -38,7 +36,6 @@ import MaterialHeaderButtons, {
|
38
|
36
|
Item,
|
39
|
37
|
} from '../../components/Overrides/CustomHeaderButton';
|
40
|
38
|
import AnimatedFAB from '../../components/Animations/AnimatedFAB';
|
41
|
|
-import type {CustomThemeType} from '../../managers/ThemeManager';
|
42
|
39
|
import ConnectionManager from '../../managers/ConnectionManager';
|
43
|
40
|
import LogoutDialog from '../../components/Amicale/LogoutDialog';
|
44
|
41
|
import AsyncStorageManager from '../../managers/AsyncStorageManager';
|
|
@@ -59,40 +56,40 @@ const SECTIONS_ID = ['dashboard', 'news_feed'];
|
59
|
56
|
const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
|
60
|
57
|
|
61
|
58
|
export type FeedItemType = {
|
62
|
|
- id: string,
|
63
|
|
- message: string,
|
64
|
|
- url: string,
|
65
|
|
- image: string | null,
|
66
|
|
- video: string | null,
|
67
|
|
- link: string | null,
|
68
|
|
- time: number,
|
69
|
|
- page_id: string,
|
|
59
|
+ id: string;
|
|
60
|
+ message: string;
|
|
61
|
+ url: string;
|
|
62
|
+ image: string | null;
|
|
63
|
+ video: string | null;
|
|
64
|
+ link: string | null;
|
|
65
|
+ time: number;
|
|
66
|
+ page_id: string;
|
70
|
67
|
};
|
71
|
68
|
|
72
|
69
|
export type FullDashboardType = {
|
73
|
|
- today_menu: Array<{[key: string]: {...}}>,
|
74
|
|
- proximo_articles: number,
|
75
|
|
- available_dryers: number,
|
76
|
|
- available_washers: number,
|
77
|
|
- today_events: Array<PlanningEventType>,
|
78
|
|
- available_tutorials: number,
|
|
70
|
+ today_menu: Array<{[key: string]: object}>;
|
|
71
|
+ proximo_articles: number;
|
|
72
|
+ available_dryers: number;
|
|
73
|
+ available_washers: number;
|
|
74
|
+ today_events: Array<PlanningEventType>;
|
|
75
|
+ available_tutorials: number;
|
79
|
76
|
};
|
80
|
77
|
|
81
|
78
|
type RawNewsFeedType = {[key: string]: Array<FeedItemType>};
|
82
|
79
|
|
83
|
80
|
type RawDashboardType = {
|
84
|
|
- news_feed: RawNewsFeedType,
|
85
|
|
- dashboard: FullDashboardType,
|
|
81
|
+ news_feed: RawNewsFeedType;
|
|
82
|
+ dashboard: FullDashboardType;
|
86
|
83
|
};
|
87
|
84
|
|
88
|
85
|
type PropsType = {
|
89
|
|
- navigation: StackNavigationProp,
|
90
|
|
- route: {params: {nextScreen: string, data: {...}}},
|
91
|
|
- theme: CustomThemeType,
|
|
86
|
+ navigation: StackNavigationProp<any>;
|
|
87
|
+ route: {params: {nextScreen: string; data: object}};
|
|
88
|
+ theme: ReactNativePaper.Theme;
|
92
|
89
|
};
|
93
|
90
|
|
94
|
91
|
type StateType = {
|
95
|
|
- dialogVisible: boolean,
|
|
92
|
+ dialogVisible: boolean;
|
96
|
93
|
};
|
97
|
94
|
|
98
|
95
|
/**
|
|
@@ -103,10 +100,12 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
103
|
100
|
b.time - a.time;
|
104
|
101
|
|
105
|
102
|
static generateNewsFeed(rawFeed: RawNewsFeedType): Array<FeedItemType> {
|
106
|
|
- const finalFeed = [];
|
|
103
|
+ const finalFeed: Array<FeedItemType> = [];
|
107
|
104
|
Object.keys(rawFeed).forEach((key: string) => {
|
108
|
105
|
const category: Array<FeedItemType> | null = rawFeed[key];
|
109
|
|
- if (category != null && category.length > 0) finalFeed.push(...category);
|
|
106
|
+ if (category != null && category.length > 0) {
|
|
107
|
+ finalFeed.push(...category);
|
|
108
|
+ }
|
110
|
109
|
});
|
111
|
110
|
finalFeed.sort(HomeScreen.sortFeedTime);
|
112
|
111
|
return finalFeed;
|
|
@@ -164,7 +163,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
164
|
163
|
*
|
165
|
164
|
* @returns {*}
|
166
|
165
|
*/
|
167
|
|
- getHeaderButton = (): React.Node => {
|
|
166
|
+ getHeaderButton = () => {
|
168
|
167
|
const {props} = this;
|
169
|
168
|
let onPressLog = (): void =>
|
170
|
169
|
props.navigation.navigate('login', {nextScreen: 'profile'});
|
|
@@ -201,7 +200,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
201
|
200
|
* @param content
|
202
|
201
|
* @return {*}
|
203
|
202
|
*/
|
204
|
|
- getDashboardEvent(content: Array<PlanningEventType>): React.Node {
|
|
203
|
+ getDashboardEvent(content: Array<PlanningEventType>) {
|
205
|
204
|
const futureEvents = getFutureEvents(content);
|
206
|
205
|
const displayEvent = getDisplayEvent(futureEvents);
|
207
|
206
|
// const clickPreviewAction = () =>
|
|
@@ -222,29 +221,13 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
222
|
221
|
}
|
223
|
222
|
|
224
|
223
|
/**
|
225
|
|
- * Gets a dashboard item with action buttons
|
226
|
|
- *
|
227
|
|
- * @returns {*}
|
228
|
|
- */
|
229
|
|
- getDashboardActions(): React.Node {
|
230
|
|
- const {props} = this;
|
231
|
|
- return (
|
232
|
|
- <ActionsDashBoardItem
|
233
|
|
- navigation={props.navigation}
|
234
|
|
- isLoggedIn={this.isLoggedIn}
|
235
|
|
- />
|
236
|
|
- );
|
237
|
|
- }
|
238
|
|
-
|
239
|
|
- /**
|
240
|
224
|
* Gets a dashboard item with a row of shortcut buttons.
|
241
|
225
|
*
|
242
|
226
|
* @param content
|
243
|
227
|
* @return {*}
|
244
|
228
|
*/
|
245
|
|
- getDashboardRow(content: Array<ServiceItemType | null>): React.Node {
|
|
229
|
+ getDashboardRow(content: Array<ServiceItemType | null>) {
|
246
|
230
|
return (
|
247
|
|
- // $FlowFixMe
|
248
|
231
|
<FlatList
|
249
|
232
|
data={content}
|
250
|
233
|
renderItem={this.getDashboardRowRenderItem}
|
|
@@ -265,12 +248,8 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
265
|
248
|
* @param item
|
266
|
249
|
* @returns {*}
|
267
|
250
|
*/
|
268
|
|
- getDashboardRowRenderItem = ({
|
269
|
|
- item,
|
270
|
|
- }: {
|
271
|
|
- item: ServiceItemType | null,
|
272
|
|
- }): React.Node => {
|
273
|
|
- if (item != null)
|
|
251
|
+ getDashboardRowRenderItem = ({item}: {item: ServiceItemType | null}) => {
|
|
252
|
+ if (item != null) {
|
274
|
253
|
return (
|
275
|
254
|
<SmallDashboardItem
|
276
|
255
|
image={item.image}
|
|
@@ -278,11 +257,12 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
278
|
257
|
badgeCount={
|
279
|
258
|
this.currentDashboard != null && item.badgeFunction != null
|
280
|
259
|
? item.badgeFunction(this.currentDashboard)
|
281
|
|
- : null
|
|
260
|
+ : undefined
|
282
|
261
|
}
|
283
|
262
|
/>
|
284
|
263
|
);
|
285
|
|
- return <SmallDashboardItem image={null} onPress={null} badgeCount={null} />;
|
|
264
|
+ }
|
|
265
|
+ return <SmallDashboardItem />;
|
286
|
266
|
};
|
287
|
267
|
|
288
|
268
|
/**
|
|
@@ -291,15 +271,8 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
291
|
271
|
* @param item The feed item to display
|
292
|
272
|
* @return {*}
|
293
|
273
|
*/
|
294
|
|
- getFeedItem(item: FeedItemType): React.Node {
|
295
|
|
- const {props} = this;
|
296
|
|
- return (
|
297
|
|
- <FeedItem
|
298
|
|
- navigation={props.navigation}
|
299
|
|
- item={item}
|
300
|
|
- height={FEED_ITEM_HEIGHT}
|
301
|
|
- />
|
302
|
|
- );
|
|
274
|
+ getFeedItem(item: FeedItemType) {
|
|
275
|
+ return <FeedItem item={item} height={FEED_ITEM_HEIGHT} />;
|
303
|
276
|
}
|
304
|
277
|
|
305
|
278
|
/**
|
|
@@ -309,20 +282,19 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
309
|
282
|
* @param section The current section
|
310
|
283
|
* @return {*}
|
311
|
284
|
*/
|
312
|
|
- getRenderItem = ({item}: {item: FeedItemType}): React.Node =>
|
313
|
|
- this.getFeedItem(item);
|
|
285
|
+ getRenderItem = ({item}: {item: FeedItemType}) => this.getFeedItem(item);
|
314
|
286
|
|
315
|
287
|
getRenderSectionHeader = (
|
316
|
288
|
data: {
|
317
|
289
|
section: {
|
318
|
|
- data: Array<{...}>,
|
319
|
|
- title: string,
|
320
|
|
- },
|
|
290
|
+ data: Array<object>;
|
|
291
|
+ title: string;
|
|
292
|
+ };
|
321
|
293
|
},
|
322
|
294
|
isLoading: boolean,
|
323
|
|
- ): React.Node => {
|
|
295
|
+ ) => {
|
324
|
296
|
const {props} = this;
|
325
|
|
- if (data.section.data.length > 0)
|
|
297
|
+ if (data.section.data.length > 0) {
|
326
|
298
|
return (
|
327
|
299
|
<Headline
|
328
|
300
|
style={{
|
|
@@ -333,6 +305,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
333
|
305
|
{data.section.title}
|
334
|
306
|
</Headline>
|
335
|
307
|
);
|
|
308
|
+ }
|
336
|
309
|
return (
|
337
|
310
|
<View>
|
338
|
311
|
<Headline
|
|
@@ -367,12 +340,14 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
367
|
340
|
);
|
368
|
341
|
};
|
369
|
342
|
|
370
|
|
- getListHeader = (fetchedData: RawDashboardType): React.Node => {
|
|
343
|
+ getListHeader = (fetchedData: RawDashboardType) => {
|
371
|
344
|
let dashboard = null;
|
372
|
|
- if (fetchedData != null) dashboard = fetchedData.dashboard;
|
|
345
|
+ if (fetchedData != null) {
|
|
346
|
+ dashboard = fetchedData.dashboard;
|
|
347
|
+ }
|
373
|
348
|
return (
|
374
|
349
|
<Animatable.View animation="fadeInDown" duration={500} useNativeDriver>
|
375
|
|
- {this.getDashboardActions()}
|
|
350
|
+ <ActionsDashBoardItem />
|
376
|
351
|
{this.getDashboardRow(this.dashboardManager.getCurrentDashboard())}
|
377
|
352
|
{this.getDashboardEvent(
|
378
|
353
|
dashboard == null ? [] : dashboard.today_events,
|
|
@@ -418,20 +393,22 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
418
|
393
|
fetchedData: RawDashboardType | null,
|
419
|
394
|
isLoading: boolean,
|
420
|
395
|
): Array<{
|
421
|
|
- title: string,
|
422
|
|
- data: [] | Array<FeedItemType>,
|
423
|
|
- id: string,
|
|
396
|
+ title: string;
|
|
397
|
+ data: [] | Array<FeedItemType>;
|
|
398
|
+ id: string;
|
424
|
399
|
}> => {
|
425
|
400
|
// fetchedData = DATA;
|
426
|
401
|
if (fetchedData != null) {
|
427
|
|
- if (fetchedData.news_feed != null)
|
|
402
|
+ if (fetchedData.news_feed != null) {
|
428
|
403
|
this.currentNewFeed = HomeScreen.generateNewsFeed(
|
429
|
404
|
fetchedData.news_feed,
|
430
|
405
|
);
|
431
|
|
- if (fetchedData.dashboard != null)
|
|
406
|
+ }
|
|
407
|
+ if (fetchedData.dashboard != null) {
|
432
|
408
|
this.currentDashboard = fetchedData.dashboard;
|
|
409
|
+ }
|
433
|
410
|
}
|
434
|
|
- if (this.currentNewFeed.length > 0)
|
|
411
|
+ if (this.currentNewFeed.length > 0) {
|
435
|
412
|
return [
|
436
|
413
|
{
|
437
|
414
|
title: i18n.t('screens.home.feedTitle'),
|
|
@@ -439,6 +416,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
439
|
416
|
id: SECTIONS_ID[1],
|
440
|
417
|
},
|
441
|
418
|
];
|
|
419
|
+ }
|
442
|
420
|
return [
|
443
|
421
|
{
|
444
|
422
|
title: isLoading
|
|
@@ -455,8 +433,10 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
455
|
433
|
props.navigation.navigate('planning');
|
456
|
434
|
};
|
457
|
435
|
|
458
|
|
- onScroll = (event: SyntheticEvent<EventTarget>) => {
|
459
|
|
- if (this.fabRef.current != null) this.fabRef.current.onScroll(event);
|
|
436
|
+ onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
437
|
+ if (this.fabRef.current) {
|
|
438
|
+ this.fabRef.current.onScroll(event);
|
|
439
|
+ }
|
460
|
440
|
};
|
461
|
441
|
|
462
|
442
|
/**
|
|
@@ -470,7 +450,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
470
|
450
|
});
|
471
|
451
|
};
|
472
|
452
|
|
473
|
|
- render(): React.Node {
|
|
453
|
+ render() {
|
474
|
454
|
const {props, state} = this;
|
475
|
455
|
return (
|
476
|
456
|
<View style={{flex: 1}}>
|
|
@@ -521,7 +501,6 @@ class HomeScreen extends React.Component<PropsType, StateType> {
|
521
|
501
|
onPress={this.openScanner}
|
522
|
502
|
/>
|
523
|
503
|
<LogoutDialog
|
524
|
|
- navigation={props.navigation}
|
525
|
504
|
visible={state.dialogVisible}
|
526
|
505
|
onDismiss={this.hideDisconnectDialog}
|
527
|
506
|
/>
|