Browse Source

Improved flow typing of home screen and associated components

Arnaud Vergnet 4 years ago
parent
commit
581ea516ae

+ 3
- 2
App.js View File

@@ -6,12 +6,13 @@ import LocaleManager from './src/managers/LocaleManager';
6 6
 import AsyncStorageManager from "./src/managers/AsyncStorageManager";
7 7
 import CustomIntroSlider from "./src/components/Overrides/CustomIntroSlider";
8 8
 import {SplashScreen} from 'expo';
9
+import type {CustomTheme} from "./src/managers/ThemeManager";
9 10
 import ThemeManager from './src/managers/ThemeManager';
10 11
 import {NavigationContainer} from '@react-navigation/native';
11 12
 import {createStackNavigator} from '@react-navigation/stack';
12 13
 import DrawerNavigator from './src/navigation/DrawerNavigator';
13 14
 import {initExpoToken} from "./src/utils/Notifications";
14
-import {Provider as PaperProvider, Theme} from 'react-native-paper';
15
+import {Provider as PaperProvider} from 'react-native-paper';
15 16
 import AprilFoolsManager from "./src/managers/AprilFoolsManager";
16 17
 import Update from "./src/constants/Update";
17 18
 import ConnectionManager from "./src/managers/ConnectionManager";
@@ -30,7 +31,7 @@ type State = {
30 31
     showIntro: boolean,
31 32
     showUpdate: boolean,
32 33
     showAprilFools: boolean,
33
-    currentTheme: Theme | null,
34
+    currentTheme: CustomTheme | null,
34 35
 };
35 36
 
36 37
 const Stack = createStackNavigator();

+ 7
- 6
src/components/Amicale/Vote/VoteResults.js View File

@@ -1,16 +1,17 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Avatar, Card, List, ProgressBar, Subheading, Theme, withTheme} from "react-native-paper";
4
+import {Avatar, Card, List, ProgressBar, Subheading, withTheme} from "react-native-paper";
5 5
 import {FlatList, StyleSheet} from "react-native";
6 6
 import i18n from 'i18n-js';
7 7
 import type {team} from "../../../screens/Amicale/VoteScreen";
8
+import type {CustomTheme} from "../../../managers/ThemeManager";
8 9
 
9 10
 
10 11
 type Props = {
11 12
     teams: Array<team>,
12 13
     dateEnd: string,
13
-    theme: Theme,
14
+    theme: CustomTheme,
14 15
 }
15 16
 
16 17
 class VoteResults extends React.Component<Props> {
@@ -38,9 +39,9 @@ class VoteResults extends React.Component<Props> {
38 39
         }
39 40
     }
40 41
 
41
-    getWinnerIds(teams: Array<team>){
42
+    getWinnerIds(teams: Array<team>) {
42 43
         let max = teams[0].votes;
43
-        this.winnerIds= [];
44
+        this.winnerIds = [];
44 45
         for (let i = 0; i < teams.length; i++) {
45 46
             if (teams[i].votes === max)
46 47
                 this.winnerIds.push(teams[i].id);
@@ -51,7 +52,7 @@ class VoteResults extends React.Component<Props> {
51 52
 
52 53
     voteKeyExtractor = (item: team) => item.id.toString();
53 54
 
54
-    resultRenderItem = ({item}: {item: team}) => {
55
+    resultRenderItem = ({item}: { item: team }) => {
55 56
         const isWinner = this.winnerIds.indexOf(item.id) !== -1;
56 57
         const isDraw = this.winnerIds.length > 1;
57 58
         const colors = this.props.theme.colors;
@@ -90,7 +91,7 @@ class VoteResults extends React.Component<Props> {
90 91
                     />}
91 92
                 />
92 93
                 <Card.Content>
93
-                    <Subheading>{i18n.t('voteScreen.results.totalVotes') + ' ' +this.totalVotes}</Subheading>
94
+                    <Subheading>{i18n.t('voteScreen.results.totalVotes') + ' ' + this.totalVotes}</Subheading>
94 95
                     {/*$FlowFixMe*/}
95 96
                     <FlatList
96 97
                         data={this.props.teams}

+ 3
- 2
src/components/Amicale/Vote/VoteWait.js View File

@@ -1,16 +1,17 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {ActivityIndicator, Card, Paragraph, Theme, withTheme} from "react-native-paper";
4
+import {ActivityIndicator, Card, Paragraph, withTheme} from "react-native-paper";
5 5
 import {StyleSheet} from "react-native";
6 6
 import i18n from 'i18n-js';
7
+import type {CustomTheme} from "../../../managers/ThemeManager";
7 8
 
8 9
 type Props = {
9 10
     startDate: string | null,
10 11
     justVoted: boolean,
11 12
     hasVoted: boolean,
12 13
     isVoteRunning: boolean,
13
-    theme: Theme,
14
+    theme: CustomTheme,
14 15
 }
15 16
 
16 17
 class VoteWait extends React.Component<Props> {

+ 3
- 2
src/components/Animations/AnimatedBottomBar.js View File

@@ -2,17 +2,18 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {StyleSheet, View} from "react-native";
5
-import {FAB, IconButton, Surface, Theme, withTheme} from "react-native-paper";
5
+import {FAB, IconButton, Surface, withTheme} from "react-native-paper";
6 6
 import AutoHideHandler from "../../utils/AutoHideHandler";
7 7
 import * as Animatable from 'react-native-animatable';
8 8
 import CustomTabBar from "../Tabbar/CustomTabBar";
9 9
 import {StackNavigationProp} from "@react-navigation/stack";
10
+import type {CustomTheme} from "../../managers/ThemeManager";
10 11
 
11 12
 const AnimatedFAB = Animatable.createAnimatableComponent(FAB);
12 13
 
13 14
 type Props = {
14 15
     navigation: StackNavigationProp,
15
-    theme: Theme,
16
+    theme: CustomTheme,
16 17
     onPress: (action: string, data: any) => void,
17 18
     seekAttention: boolean,
18 19
 }

+ 4
- 2
src/components/Home/ActionsDashboardItem.js View File

@@ -4,10 +4,12 @@ import * as React from 'react';
4 4
 import {Button, Card, withTheme} from 'react-native-paper';
5 5
 import {Platform, StyleSheet} from "react-native";
6 6
 import i18n from 'i18n-js';
7
+import {DrawerNavigationProp} from "@react-navigation/drawer";
8
+import type {CustomTheme} from "../../managers/ThemeManager";
7 9
 
8 10
 type Props = {
9
-    navigation: Object,
10
-    theme: Object,
11
+    navigation: DrawerNavigationProp,
12
+    theme: CustomTheme,
11 13
 }
12 14
 
13 15
 class ActionsDashBoardItem extends React.Component<Props> {

+ 4
- 2
src/components/Home/EventDashboardItem.js View File

@@ -4,11 +4,13 @@ import * as React from 'react';
4 4
 import {Avatar, Card, Text, withTheme} from 'react-native-paper';
5 5
 import {StyleSheet} from "react-native";
6 6
 import i18n from "i18n-js";
7
+import type {CustomTheme} from "../../managers/ThemeManager";
7 8
 
8 9
 type Props = {
9 10
     eventNumber: number;
10
-    clickAction: Function,
11
-    theme: Object,
11
+    clickAction: () => void,
12
+    theme: CustomTheme,
13
+    children?: React.Node
12 14
 }
13 15
 
14 16
 /**

+ 14
- 6
src/components/Home/FeedItem.js View File

@@ -1,15 +1,21 @@
1
+// @flow
2
+
1 3
 import * as React from 'react';
2 4
 import {Avatar, Button, Card, Text} from 'react-native-paper';
3 5
 import {View} from "react-native";
4 6
 import Autolink from "react-native-autolink";
5 7
 import i18n from "i18n-js";
6 8
 import ImageModal from 'react-native-image-modal';
9
+import {StackNavigationProp} from "@react-navigation/stack";
10
+import type {CustomTheme} from "../../managers/ThemeManager";
11
+import type {feedItem} from "../../screens/Home/HomeScreen";
7 12
 
8 13
 const ICON_AMICALE = require('../../../assets/amicale.png');
9 14
 
10 15
 type Props = {
11
-    navigation: Object,
12
-    theme: Object,
16
+    navigation: StackNavigationProp,
17
+    theme: CustomTheme,
18
+    item: feedItem,
13 19
     title: string,
14 20
     subtitle: string,
15 21
     height: number,
@@ -32,17 +38,19 @@ class FeedItem extends React.Component<Props> {
32 38
      */
33 39
     getAvatar() {
34 40
         return (
35
-            <Avatar.Image size={48} source={ICON_AMICALE}
36
-                          style={{backgroundColor: 'transparent'}}/>
41
+            <Avatar.Image
42
+                size={48} source={ICON_AMICALE}
43
+                style={{backgroundColor: 'transparent'}}/>
37 44
         );
38 45
     }
39 46
 
40 47
     onPress = () => {
41
-        this.props.navigation.navigate('feed-information',
48
+        this.props.navigation.navigate(
49
+            'feed-information',
42 50
             {
43 51
                 data: this.props.item,
44 52
                 date: this.props.subtitle
45
-            })
53
+            });
46 54
     };
47 55
 
48 56
     render() {

+ 16
- 12
src/components/Home/PreviewEventDashboardItem.js View File

@@ -6,10 +6,13 @@ import i18n from "i18n-js";
6 6
 import {Avatar, Button, Card} from 'react-native-paper';
7 7
 import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
8 8
 import CustomHTML from "../Overrides/CustomHTML";
9
+import type {CustomTheme} from "../../managers/ThemeManager";
10
+import type {event} from "../../screens/Home/HomeScreen";
9 11
 
10 12
 type Props = {
11
-    event: Object,
12
-    clickAction: Function,
13
+    event?: event,
14
+    clickAction: () => void,
15
+    theme?: CustomTheme,
13 16
 }
14 17
 
15 18
 /**
@@ -19,14 +22,15 @@ class PreviewEventDashboardItem extends React.Component<Props> {
19 22
 
20 23
     render() {
21 24
         const props = this.props;
22
-        const isEmpty = props.event === undefined
25
+        const isEmpty = props.event == null
23 26
             ? true
24
-            : isDescriptionEmpty(props.event['description']);
27
+            : isDescriptionEmpty(props.event.description);
25 28
 
26
-        if (props.event !== undefined && props.event !== null) {
27
-            const hasImage = props.event['logo'] !== '' && props.event['logo'] !== null;
29
+        if (props.event != null) {
30
+            const event = props.event;
31
+            const hasImage = event.logo !== '' && event.logo != null;
28 32
             const getImage = () => <Avatar.Image
29
-                source={{uri: props.event['logo']}}
33
+                source={{uri: event.logo}}
30 34
                 size={50}
31 35
                 style={styles.avatar}/>;
32 36
             return (
@@ -37,17 +41,17 @@ class PreviewEventDashboardItem extends React.Component<Props> {
37 41
                 >
38 42
                     {hasImage ?
39 43
                         <Card.Title
40
-                            title={props.event['title']}
41
-                            subtitle={getFormattedEventTime(props.event['date_begin'], props.event['date_end'])}
44
+                            title={event.title}
45
+                            subtitle={getFormattedEventTime(event.date_begin, event.date_end)}
42 46
                             left={getImage}
43 47
                         /> :
44 48
                         <Card.Title
45
-                            title={props.event['title']}
46
-                            subtitle={getFormattedEventTime(props.event['date_begin'], props.event['date_end'])}
49
+                            title={event.title}
50
+                            subtitle={getFormattedEventTime(event.date_begin, event.date_end)}
47 51
                         />}
48 52
                     {!isEmpty ?
49 53
                         <Card.Content style={styles.content}>
50
-                            <CustomHTML html={props.event['description']}/>
54
+                            <CustomHTML html={event.description}/>
51 55
                         </Card.Content> : null}
52 56
 
53 57
                     <Card.Actions style={styles.actions}>

+ 3
- 2
src/components/Home/SmallDashboardItem.js View File

@@ -3,15 +3,16 @@
3 3
 import * as React from 'react';
4 4
 import {Badge, IconButton, withTheme} from 'react-native-paper';
5 5
 import {View} from "react-native";
6
+import type {CustomTheme} from "../../managers/ThemeManager";
6 7
 
7 8
 
8 9
 type Props = {
9 10
     color: string,
10 11
     icon: string,
11
-    clickAction: Function,
12
+    clickAction: () => void,
12 13
     isAvailable: boolean,
13 14
     badgeNumber: number,
14
-    theme: Object,
15
+    theme: CustomTheme,
15 16
 };
16 17
 
17 18
 /**

+ 61
- 11
src/managers/ThemeManager.js View File

@@ -1,12 +1,61 @@
1 1
 // @flow
2 2
 
3 3
 import AsyncStorageManager from "./AsyncStorageManager";
4
-import {DarkTheme, DefaultTheme} from 'react-native-paper';
4
+import {DarkTheme, DefaultTheme, Theme} from 'react-native-paper';
5 5
 import AprilFoolsManager from "./AprilFoolsManager";
6 6
 import {Appearance} from 'react-native-appearance';
7 7
 
8 8
 const colorScheme = Appearance.getColorScheme();
9 9
 
10
+export type CustomTheme = {
11
+    ...Theme,
12
+    colors: {
13
+        primary: string,
14
+        accent: string,
15
+        tabIcon: string,
16
+        card: string,
17
+        dividerBackground: string,
18
+        ripple: string,
19
+        textDisabled: string,
20
+        icon: string,
21
+        subtitle: string,
22
+        success: string,
23
+        warning: string,
24
+        danger: string,
25
+
26
+        // Calendar/Agenda
27
+        agendaBackgroundColor: string,
28
+        agendaDayTextColor: string,
29
+
30
+        // PROXIWASH
31
+        proxiwashFinishedColor: string,
32
+        proxiwashReadyColor: string,
33
+        proxiwashRunningColor: string,
34
+        proxiwashRunningBgColor: string,
35
+        proxiwashBrokenColor: string,
36
+        proxiwashErrorColor: string,
37
+
38
+        // Screens
39
+        planningColor: string,
40
+        proximoColor: string,
41
+        proxiwashColor: string,
42
+        menuColor: string,
43
+        tutorinsaColor: string,
44
+
45
+        // Tetris
46
+        tetrisBackground: string,
47
+        tetrisBorder:string,
48
+        tetrisScore:string,
49
+        tetrisI : string,
50
+        tetrisO : string,
51
+        tetrisT : string,
52
+        tetrisS : string,
53
+        tetrisZ : string,
54
+        tetrisJ : string,
55
+        tetrisL : string,
56
+    },
57
+}
58
+
10 59
 /**
11 60
  * Singleton class used to manage themes
12 61
  */
@@ -22,9 +71,9 @@ export default class ThemeManager {
22 71
     /**
23 72
      * Gets the light theme
24 73
      *
25
-     * @return {Object} Object containing theme variables
74
+     * @return {CustomTheme} Object containing theme variables
26 75
      * */
27
-    static getWhiteTheme(): Object {
76
+    static getWhiteTheme(): CustomTheme {
28 77
         return {
29 78
             ...DefaultTheme,
30 79
             colors: {
@@ -41,6 +90,7 @@ export default class ThemeManager {
41 90
                 success: "#5cb85c",
42 91
                 warning: "#f0ad4e",
43 92
                 danger: "#d9534f",
93
+                cc: 'dst',
44 94
 
45 95
                 // Calendar/Agenda
46 96
                 agendaBackgroundColor: '#f3f3f4',
@@ -79,9 +129,9 @@ export default class ThemeManager {
79 129
     /**
80 130
      * Gets the dark theme
81 131
      *
82
-     * @return {Object} Object containing theme variables
132
+     * @return {CustomTheme} Object containing theme variables
83 133
      * */
84
-    static getDarkTheme(): Object {
134
+    static getDarkTheme(): CustomTheme {
85 135
         return {
86 136
             ...DarkTheme,
87 137
             colors: {
@@ -162,9 +212,9 @@ export default class ThemeManager {
162 212
     /**
163 213
      * Get the current theme based on night mode and events
164 214
      *
165
-     * @returns {Object} The current theme
215
+     * @returns {CustomTheme} The current theme
166 216
      */
167
-    static getCurrentTheme(): Object {
217
+    static getCurrentTheme(): CustomTheme {
168 218
         if (AprilFoolsManager.getInstance().isAprilFoolsEnabled())
169 219
             return AprilFoolsManager.getAprilFoolsTheme(ThemeManager.getWhiteTheme());
170 220
         else
@@ -174,9 +224,9 @@ export default class ThemeManager {
174 224
     /**
175 225
      * Get the theme based on night mode
176 226
      *
177
-     * @return {Object} The theme
227
+     * @return {CustomTheme} The theme
178 228
      */
179
-    static getBaseTheme() {
229
+    static getBaseTheme(): CustomTheme {
180 230
         if (ThemeManager.getNightMode())
181 231
             return ThemeManager.getDarkTheme();
182 232
         else
@@ -188,7 +238,7 @@ export default class ThemeManager {
188 238
      *
189 239
      * @param callback Function to call after theme change
190 240
      */
191
-    setUpdateThemeCallback(callback: ?Function) {
241
+    setUpdateThemeCallback(callback: () => void) {
192 242
         this.updateThemeCallback = callback;
193 243
     }
194 244
 
@@ -200,7 +250,7 @@ export default class ThemeManager {
200 250
     setNightMode(isNightMode: boolean) {
201 251
         let nightModeKey = AsyncStorageManager.getInstance().preferences.nightMode.key;
202 252
         AsyncStorageManager.getInstance().savePref(nightModeKey, isNightMode ? '1' : '0');
203
-        if (this.updateThemeCallback !== null)
253
+        if (this.updateThemeCallback != null)
204 254
             this.updateThemeCallback();
205 255
     }
206 256
 

+ 163
- 121
src/screens/Home/HomeScreen.js View File

@@ -1,7 +1,7 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Animated, FlatList} from 'react-native';
4
+import {FlatList} from 'react-native';
5 5
 import i18n from "i18n-js";
6 6
 import DashboardItem from "../../components/Home/EventDashboardItem";
7 7
 import WebSectionList from "../../components/Screens/WebSectionList";
@@ -14,9 +14,10 @@ import ActionsDashBoardItem from "../../components/Home/ActionsDashboardItem";
14 14
 import ConnectionManager from "../../managers/ConnectionManager";
15 15
 import {CommonActions} from '@react-navigation/native';
16 16
 import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
17
-import {AnimatedValue} from "react-native-reanimated";
18 17
 import AnimatedFAB from "../../components/Animations/AnimatedFAB";
19 18
 import AnimatedFocusView from "../../components/Animations/AnimatedFocusView";
19
+import {StackNavigationProp} from "@react-navigation/stack";
20
+import type {CustomTheme} from "../../managers/ThemeManager";
20 21
 // import DATA from "../dashboard_data.json";
21 22
 
22 23
 
@@ -31,30 +32,80 @@ const SECTIONS_ID = [
31 32
 
32 33
 const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
33 34
 
34
-type Props = {
35
-    navigation: Object,
36
-    route: Object,
37
-    theme: Object,
35
+type rawDashboard = {
36
+    news_feed: {
37
+        data: Array<feedItem>,
38
+    },
39
+    dashboard: fullDashboard,
40
+}
41
+
42
+export type feedItem = {
43
+    full_picture: string,
44
+    message: string,
45
+    permalink_url: string,
46
+    created_time: number,
47
+    id: string,
48
+};
49
+
50
+type fullDashboard = {
51
+    today_menu: Array<{ [key: string]: any }>,
52
+    proximo_articles: number,
53
+    available_machines: {
54
+        dryers: number,
55
+        washers: number,
56
+    },
57
+    today_events: Array<{ [key: string]: any }>,
58
+    available_tutorials: number,
59
+}
60
+
61
+type dashboardItem = {
62
+    id: string,
63
+    content: Array<{ [key: string]: any }>
64
+};
65
+
66
+type dashboardSmallItem = {
67
+    id: string,
68
+    data: number,
69
+    icon: string,
70
+    color: string,
71
+    onPress: () => void,
72
+    isAvailable: boolean
73
+};
74
+
75
+export type event = {
76
+    id: number,
77
+    title: string,
78
+    logo: string | null,
79
+    date_begin: string,
80
+    date_end: string,
81
+    description: string,
82
+    club: string,
83
+    category_id: number,
84
+    url: string,
38 85
 }
39 86
 
40
-type State = {
41
-    fabPosition: AnimatedValue
87
+type listSection = {
88
+    title: string,
89
+    data: Array<dashboardItem> | Array<feedItem>,
90
+    id: string
91
+};
92
+
93
+type Props = {
94
+    navigation: StackNavigationProp,
95
+    route: { params: any, ... },
96
+    theme: CustomTheme,
42 97
 }
43 98
 
44 99
 /**
45 100
  * Class defining the app's home screen
46 101
  */
47
-class HomeScreen extends React.Component<Props, State> {
102
+class HomeScreen extends React.Component<Props> {
48 103
 
49 104
     colors: Object;
50 105
 
51 106
     isLoggedIn: boolean | null;
52 107
 
53
-    fabRef: Object;
54
-
55
-    state = {
56
-        fabPosition: new Animated.Value(0),
57
-    };
108
+    fabRef: { current: null | AnimatedFAB };
58 109
 
59 110
     constructor(props) {
60 111
         super(props);
@@ -69,8 +120,8 @@ class HomeScreen extends React.Component<Props, State> {
69 120
      * @param dateString {string} The Unix Timestamp representation of a date
70 121
      * @return {string} The formatted output date
71 122
      */
72
-    static getFormattedDate(dateString: string) {
73
-        let date = new Date(Number.parseInt(dateString) * 1000);
123
+    static getFormattedDate(dateString: number) {
124
+        let date = new Date(dateString * 1000);
74 125
         return date.toLocaleString();
75 126
     }
76 127
 
@@ -92,8 +143,8 @@ class HomeScreen extends React.Component<Props, State> {
92 143
     };
93 144
 
94 145
     handleNavigationParams = () => {
95
-        if (this.props.route.params !== undefined) {
96
-            if (this.props.route.params.nextScreen !== undefined && this.props.route.params.nextScreen !== null) {
146
+        if (this.props.route.params != null) {
147
+            if (this.props.route.params.nextScreen != null) {
97 148
                 this.props.navigation.navigate(this.props.route.params.nextScreen, this.props.route.params.data);
98 149
                 // reset params to prevent infinite loop
99 150
                 this.props.navigation.dispatch(CommonActions.setParams({nextScreen: null}));
@@ -138,14 +189,14 @@ class HomeScreen extends React.Component<Props, State> {
138 189
      * @param fetchedData
139 190
      * @return {*}
140 191
      */
141
-    createDataset = (fetchedData: Object) => {
192
+    createDataset = (fetchedData: rawDashboard) => {
142 193
         // fetchedData = DATA;
143 194
         let newsData = [];
144 195
         let dashboardData = [];
145
-        if (fetchedData['news_feed'] !== undefined)
146
-            newsData = fetchedData['news_feed']['data'];
147
-        if (fetchedData['dashboard'] !== undefined)
148
-            dashboardData = this.generateDashboardDataset(fetchedData['dashboard']);
196
+        if (fetchedData.news_feed != null)
197
+            newsData = fetchedData.news_feed.data;
198
+        if (fetchedData.dashboard != null)
199
+            dashboardData = this.generateDashboardDataset(fetchedData.dashboard);
149 200
         return [
150 201
             {
151 202
                 title: '',
@@ -164,79 +215,61 @@ class HomeScreen extends React.Component<Props, State> {
164 215
      * Generates the dataset associated to the dashboard to be displayed in the FlatList as a section
165 216
      *
166 217
      * @param dashboardData
167
-     * @return {*}
218
+     * @return {Array<dashboardItem>}
168 219
      */
169
-    generateDashboardDataset(dashboardData: Object) {
170
-        let dataset = [
171
-
220
+    generateDashboardDataset(dashboardData: fullDashboard): Array<dashboardItem> {
221
+        return [
172 222
             {
173 223
                 id: 'top',
174
-                content: []
175
-            },
176
-            {
177
-                id: 'actions',
178
-                content: undefined
179
-            },
180
-            {
181
-                id: 'event',
182
-                content: undefined
183
-            },
184
-        ];
185
-        for (let [key, value: number | Object | Array<string>] of Object.entries(dashboardData)) {
186
-            switch (key) {
187
-                case 'available_machines':
188
-                    dataset[0]['content'][0] = {
224
+                content: [
225
+                    {
189 226
                         id: 'washers',
190
-                        data: value.washers,
227
+                        data: dashboardData.available_machines.washers,
191 228
                         icon: 'washing-machine',
192 229
                         color: this.colors.proxiwashColor,
193 230
                         onPress: this.onProxiwashClick,
194
-                        isAvailable: value.washers > 0
195
-                    };
196
-                    dataset[0]['content'][1] = {
197
-                        ...dataset[0]['content'][0],
231
+                        isAvailable: dashboardData.available_machines.washers > 0
232
+                    },
233
+                    {
198 234
                         id: 'dryers',
199
-                        data: value.dryers,
235
+                        data: dashboardData.available_machines.dryers,
200 236
                         icon: 'tumble-dryer',
201
-                        isAvailable: value.dryers > 0
202
-                    };
203
-                    break;
204
-                case 'available_tutorials':
205
-                    dataset[0]['content'][2] = {
206
-                        id: key,
207
-                        data: value,
237
+                        color: this.colors.proxiwashColor,
238
+                        onPress: this.onProxiwashClick,
239
+                        isAvailable: dashboardData.available_machines.dryers > 0
240
+                    },
241
+                    {
242
+                        id: 'available_tutorials',
243
+                        data: dashboardData.available_tutorials,
208 244
                         icon: 'school',
209 245
                         color: this.colors.tutorinsaColor,
210 246
                         onPress: this.onTutorInsaClick,
211
-                        isAvailable: parseInt(value) > 0
212
-                    };
213
-                    break;
214
-                case 'proximo_articles':
215
-                    dataset[0]['content'][3] = {
216
-                        id: key,
217
-                        data: value,
247
+                        isAvailable: dashboardData.available_tutorials > 0
248
+                    },
249
+                    {
250
+                        id: 'proximo_articles',
251
+                        data: dashboardData.proximo_articles,
218 252
                         icon: 'shopping',
219 253
                         color: this.colors.proximoColor,
220 254
                         onPress: this.onProximoClick,
221
-                        isAvailable: parseInt(value) > 0
222
-                    };
223
-                    break;
224
-                case 'today_menu':
225
-                    dataset[0]['content'][4] = {
226
-                        id: key,
227
-                        data: 0,
228
-                        icon: 'silverware-fork-knife',
255
+                        isAvailable: dashboardData.proximo_articles > 0
256
+                    },
257
+                    {
258
+                        id: 'silverware-fork-knife',
259
+                        data: dashboardData.today_menu,
260
+                        icon: 'shopping',
229 261
                         color: this.colors.menuColor,
230 262
                         onPress: this.onMenuClick,
231
-                        isAvailable: value.length > 0
232
-                    };
233
-                    break;
234
-                case 'today_events':
235
-                    dataset[2]['content'] = value;
236
-                    break;
237
-            }
238
-        }
239
-        return dataset
263
+                        isAvailable: dashboardData.today_menu.length > 0
264
+                    },
265
+                ]
266
+            },
267
+            {id: 'actions', content: []},
268
+            {
269
+                id: 'event',
270
+                content: dashboardData.today_events
271
+            },
272
+        ];
240 273
     }
241 274
 
242 275
     /**
@@ -245,11 +278,11 @@ class HomeScreen extends React.Component<Props, State> {
245 278
      * @param item The item to display
246 279
      * @return {*}
247 280
      */
248
-    getDashboardItem(item: Object) {
249
-        let content = item['content'];
250
-        if (item['id'] === 'event')
281
+    getDashboardItem(item: dashboardItem) {
282
+        let content = item.content;
283
+        if (item.id === 'event')
251 284
             return this.getDashboardEvent(content);
252
-        else if (item['id'] === 'top')
285
+        else if (item.id === 'top')
253 286
             return this.getDashboardRow(content);
254 287
         else
255 288
             return this.getDashboardActions();
@@ -278,14 +311,14 @@ class HomeScreen extends React.Component<Props, State> {
278 311
     /**
279 312
      * Gets the duration (in milliseconds) of an event
280 313
      *
281
-     * @param event {Object}
314
+     * @param event {event}
282 315
      * @return {number} The number of milliseconds
283 316
      */
284
-    getEventDuration(event: Object): number {
285
-        let start = stringToDate(event['date_begin']);
286
-        let end = stringToDate(event['date_end']);
317
+    getEventDuration(event: event): number {
318
+        let start = stringToDate(event.date_begin);
319
+        let end = stringToDate(event.date_end);
287 320
         let duration = 0;
288
-        if (start !== undefined && start !== null && end !== undefined && end !== null)
321
+        if (start != null && end != null)
289 322
             duration = end - start;
290 323
         return duration;
291 324
     }
@@ -297,11 +330,11 @@ class HomeScreen extends React.Component<Props, State> {
297 330
      * @param limit
298 331
      * @return {Array<Object>}
299 332
      */
300
-    getEventsAfterLimit(events: Object, limit: Date): Array<Object> {
333
+    getEventsAfterLimit(events: Array<event>, limit: Date): Array<event> {
301 334
         let validEvents = [];
302 335
         for (let event of events) {
303
-            let startDate = stringToDate(event['date_begin']);
304
-            if (startDate !== undefined && startDate !== null && startDate >= limit) {
336
+            let startDate = stringToDate(event.date_begin);
337
+            if (startDate != null && startDate >= limit) {
305 338
                 validEvents.push(event);
306 339
             }
307 340
         }
@@ -314,7 +347,7 @@ class HomeScreen extends React.Component<Props, State> {
314 347
      *
315 348
      * @param events
316 349
      */
317
-    getLongestEvent(events: Array<Object>): Object {
350
+    getLongestEvent(events: Array<event>): event {
318 351
         let longestEvent = events[0];
319 352
         let longestTime = 0;
320 353
         for (let event of events) {
@@ -332,16 +365,16 @@ class HomeScreen extends React.Component<Props, State> {
332 365
      *
333 366
      * @param events
334 367
      */
335
-    getFutureEvents(events: Array<Object>): Array<Object> {
368
+    getFutureEvents(events: Array<event>): Array<event> {
336 369
         let validEvents = [];
337 370
         let now = new Date();
338 371
         for (let event of events) {
339
-            let startDate = stringToDate(event['date_begin']);
340
-            let endDate = stringToDate(event['date_end']);
341
-            if (startDate !== undefined && startDate !== null) {
372
+            let startDate = stringToDate(event.date_begin);
373
+            let endDate = stringToDate(event.date_end);
374
+            if (startDate != null) {
342 375
                 if (startDate > now)
343 376
                     validEvents.push(event);
344
-                else if (endDate !== undefined && endDate !== null) {
377
+                else if (endDate != null) {
345 378
                     if (endDate > now || endDate < startDate) // Display event if it ends the following day
346 379
                         validEvents.push(event);
347 380
                 }
@@ -356,8 +389,8 @@ class HomeScreen extends React.Component<Props, State> {
356 389
      * @param events
357 390
      * @return {Object}
358 391
      */
359
-    getDisplayEvent(events: Array<Object>): Object {
360
-        let displayEvent = undefined;
392
+    getDisplayEvent(events: Array<event>): event | null {
393
+        let displayEvent = null;
361 394
         if (events.length > 1) {
362 395
             let eventsAfterLimit = this.getEventsAfterLimit(events, this.getTodayEventTimeLimit());
363 396
             if (eventsAfterLimit.length > 0) {
@@ -383,7 +416,7 @@ class HomeScreen extends React.Component<Props, State> {
383 416
      * @param content
384 417
      * @return {*}
385 418
      */
386
-    getDashboardEvent(content: Array<Object>) {
419
+    getDashboardEvent(content: Array<event>) {
387 420
         let futureEvents = this.getFutureEvents(content);
388 421
         let displayEvent = this.getDisplayEvent(futureEvents);
389 422
         const clickPreviewAction = () =>
@@ -394,14 +427,14 @@ class HomeScreen extends React.Component<Props, State> {
394 427
                 clickAction={this.onEventContainerClick}
395 428
             >
396 429
                 <PreviewEventDashboardItem
397
-                    event={displayEvent}
430
+                    event={displayEvent != null ? displayEvent : undefined}
398 431
                     clickAction={clickPreviewAction}
399 432
                 />
400 433
             </DashboardItem>
401 434
         );
402 435
     }
403 436
 
404
-    dashboardRowRenderItem = ({item}: Object) => {
437
+    dashboardRowRenderItem = ({item}: { item: dashboardSmallItem }) => {
405 438
         return (
406 439
             <SquareDashboardItem
407 440
                 color={item.color}
@@ -419,16 +452,18 @@ class HomeScreen extends React.Component<Props, State> {
419 452
      * @param content
420 453
      * @return {*}
421 454
      */
422
-    getDashboardRow(content: Array<Object>) {
423
-        return <FlatList
424
-            data={content}
425
-            renderItem={this.dashboardRowRenderItem}
426
-            horizontal={true}
427
-            contentContainerStyle={{
428
-                marginLeft: 'auto',
429
-                marginRight: 'auto',
430
-            }}
431
-        />;
455
+    getDashboardRow(content: Array<dashboardSmallItem>) {
456
+        return (
457
+            //$FlowFixMe
458
+            <FlatList
459
+                data={content}
460
+                renderItem={this.dashboardRowRenderItem}
461
+                horizontal={true}
462
+                contentContainerStyle={{
463
+                    marginLeft: 'auto',
464
+                    marginRight: 'auto',
465
+                }}
466
+            />);
432 467
     }
433 468
 
434 469
     /**
@@ -437,7 +472,7 @@ class HomeScreen extends React.Component<Props, State> {
437 472
      * @param item The feed item to display
438 473
      * @return {*}
439 474
      */
440
-    getFeedItem(item: Object) {
475
+    getFeedItem(item: feedItem) {
441 476
         return (
442 477
             <FeedItem
443 478
                 {...this.props}
@@ -456,27 +491,34 @@ class HomeScreen extends React.Component<Props, State> {
456 491
      * @param section The current section
457 492
      * @return {*}
458 493
      */
459
-    getRenderItem = ({item, section}: Object) => {
460
-        return (section['id'] === SECTIONS_ID[0]
461
-            ? this.getDashboardItem(item)
462
-            : this.getFeedItem(item));
494
+    getRenderItem = ({item, section}: {
495
+        item: { [key: string]: any },
496
+        section: listSection
497
+    }) => {
498
+        if (section.id === SECTIONS_ID[0]) {
499
+            const data: dashboardItem = item;
500
+            return this.getDashboardItem(data);
501
+        } else {
502
+            const data: feedItem = item;
503
+            return this.getFeedItem(data);
504
+        }
463 505
     };
464 506
 
465 507
     openScanner = () => this.props.navigation.navigate("scanner");
466 508
 
467
-    onScroll = (event: Object) => {
468
-        this.fabRef.current.onScroll(event);
509
+    onScroll = (event: SyntheticEvent<EventTarget>) => {
510
+        if (this.fabRef.current != null)
511
+            this.fabRef.current.onScroll(event);
469 512
     };
470 513
 
471 514
     render() {
472
-        const nav = this.props.navigation;
473 515
         return (
474 516
             <AnimatedFocusView
475 517
                 {...this.props}
476 518
             >
477 519
                 <WebSectionList
520
+                    {...this.props}
478 521
                     createDataset={this.createDataset}
479
-                    navigation={nav}
480 522
                     autoRefreshTime={REFRESH_TIME}
481 523
                     refreshOnFocus={true}
482 524
                     fetchUrl={DATA_URL}

Loading…
Cancel
Save