Browse Source

Implemented new RU menu screen

keplyx 2 years ago
parent
commit
2ef349755a
6 changed files with 201 additions and 74 deletions
  1. 2
    2
      app.json
  2. 4
    1
      components/BaseContainer.js
  3. 8
    1
      components/FetchedDataSectionList.js
  4. 136
    69
      screens/SelfMenuScreen.js
  5. 25
    0
      translations/en.json
  6. 26
    1
      translations/fr.json

+ 2
- 2
app.json View File

@@ -10,7 +10,7 @@
10 10
       "android",
11 11
       "web"
12 12
     ],
13
-    "version": "1.0.3",
13
+    "version": "1.1.0",
14 14
     "orientation": "portrait",
15 15
     "primaryColor": "#be1522",
16 16
     "icon": "./assets/android.icon.png",
@@ -36,7 +36,7 @@
36 36
     },
37 37
     "android": {
38 38
       "package": "fr.amicaleinsat.application",
39
-      "versionCode": 6,
39
+      "versionCode": 7,
40 40
       "icon": "./assets/android.icon.png",
41 41
       "adaptiveIcon": {
42 42
         "foregroundImage": "./assets/android.adaptive-icon.png",

+ 4
- 1
components/BaseContainer.js View File

@@ -16,6 +16,7 @@ type Props = {
16 16
     headerRightButton: React.Node,
17 17
     children: React.Node,
18 18
     hasTabs: boolean,
19
+    hasBackButton: boolean
19 20
 }
20 21
 
21 22
 type State = {
@@ -30,6 +31,7 @@ export default class BaseContainer extends React.Component<Props, State> {
30 31
     static defaultProps = {
31 32
         headerRightButton: <View/>,
32 33
         hasTabs: false,
34
+        hasBackButton: false,
33 35
     };
34 36
 
35 37
 
@@ -90,7 +92,8 @@ export default class BaseContainer extends React.Component<Props, State> {
90 92
                                 </Touchable>
91 93
                             }
92 94
                             rightButton={this.props.headerRightButton}
93
-                            hasTabs={this.props.hasTabs}/>
95
+                            hasTabs={this.props.hasTabs}
96
+                            hasBackButton={this.props.hasBackButton}/>
94 97
                         {this.props.children}
95 98
                     </Container>
96 99
                 </CustomSideMenu>

+ 8
- 1
components/FetchedDataSectionList.js View File

@@ -260,6 +260,10 @@ export default class FetchedDataSectionList extends React.Component<Props, State
260 260
         return false;
261 261
     }
262 262
 
263
+    hasBackButton() {
264
+        return false;
265
+    }
266
+
263 267
     getRightButton() {
264 268
         return <View/>
265 269
     }
@@ -277,6 +281,7 @@ export default class FetchedDataSectionList extends React.Component<Props, State
277 281
         return (
278 282
             <SectionList
279 283
                 sections={dataset}
284
+                stickySectionHeadersEnabled
280 285
                 refreshControl={
281 286
                     <RefreshControl
282 287
                         refreshing={this.state.refreshing}
@@ -345,7 +350,9 @@ export default class FetchedDataSectionList extends React.Component<Props, State
345 350
             <BaseContainer
346 351
                 navigation={nav} headerTitle={this.getHeaderTranslation()}
347 352
                 headerRightButton={this.getRightButton()}
348
-                hasTabs={this.hasTabs()}>
353
+                hasTabs={this.hasTabs()}
354
+                hasBackButton={this.hasBackButton()}
355
+            >
349 356
                 {this.hasTabs() ?
350 357
                     <Tabs
351 358
                         tabContainerStyle={{

+ 136
- 69
screens/SelfMenuScreen.js View File

@@ -1,92 +1,159 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Platform, View} from 'react-native';
5
-import {Container, Spinner} from 'native-base';
6
-import WebView from "react-native-webview";
7
-import Touchable from "react-native-platform-touchable";
8
-import CustomMaterialIcon from "../components/CustomMaterialIcon";
4
+import {View} from 'react-native';
5
+import {Text, H2, H3, Card, CardItem} from 'native-base';
9 6
 import ThemeManager from "../utils/ThemeManager";
10
-import CustomHeader from "../components/CustomHeader";
11 7
 import i18n from "i18n-js";
8
+import FetchedDataSectionList from "../components/FetchedDataSectionList";
9
+import LocaleManager from "../utils/LocaleManager";
12 10
 
13
-type Props = {
14
-    navigation: Object,
15
-}
16
-
17
-
18
-const RU_URL = 'http://m.insa-toulouse.fr/ru.html';
19
-const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/RU/customGeneral.css';
20
-const CUSTOM_CSS_LIGHT = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/RU/customLight.css';
11
+const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json";
21 12
 
22 13
 /**
23
- * Class defining the app's planex screen.
24
- * This screen uses a webview to render the planex page
14
+ * Class defining the app's menu screen.
15
+ * This screen fetches data from etud to render the RU menu
25 16
  */
26
-export default class SelfMenuScreen extends React.Component<Props> {
17
+export default class SelfMenuScreen extends FetchedDataSectionList {
27 18
 
28
-    webview: WebView;
29
-    customInjectedJS: string;
19
+    // Hard code strings as toLocaleDateString does not work on current android JS engine
20
+    daysOfWeek = [];
21
+    monthsOfYear = [];
30 22
 
31 23
     constructor() {
32
-        super();
33
-        this.customInjectedJS =
34
-            'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
35
-            'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\';';
36
-        if (!ThemeManager.getNightMode())
37
-            this.customInjectedJS += 'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_LIGHT + '" type="text/css"/>\';';
24
+        super(DATA_URL, 0);
25
+        this.daysOfWeek.push(i18n.t("date.daysOfWeek.monday"));
26
+        this.daysOfWeek.push(i18n.t("date.daysOfWeek.tuesday"));
27
+        this.daysOfWeek.push(i18n.t("date.daysOfWeek.wednesday"));
28
+        this.daysOfWeek.push(i18n.t("date.daysOfWeek.thursday"));
29
+        this.daysOfWeek.push(i18n.t("date.daysOfWeek.friday"));
30
+        this.daysOfWeek.push(i18n.t("date.daysOfWeek.saturday"));
31
+        this.daysOfWeek.push(i18n.t("date.daysOfWeek.sunday"));
32
+
33
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.january"));
34
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.february"));
35
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.march"));
36
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.april"));
37
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.may"));
38
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.june"));
39
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.july"));
40
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.august"));
41
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.september"));
42
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.october"));
43
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.november"));
44
+        this.monthsOfYear.push(i18n.t("date.monthsOfYear.december"));
45
+    }
46
+
47
+    getHeaderTranslation() {
48
+        return i18n.t("screens.menuSelf");
49
+    }
50
+
51
+    getUpdateToastTranslations() {
52
+        return [i18n.t("homeScreen.listUpdated"), i18n.t("homeScreen.listUpdateFail")];
53
+    }
54
+
55
+    getKeyExtractor(item: Object) {
56
+        return item !== undefined ? item.name : undefined;
57
+    }
58
+
59
+    hasBackButton() {
60
+        return true;
61
+    }
62
+
63
+    createDataset(fetchedData: Object) {
64
+        let result = [];
65
+        // Prevent crash by giving a default value when fetchedData is empty (not yet available)
66
+        if (Object.keys(fetchedData).length === 0) {
67
+            result = [
68
+                {
69
+                    title: '',
70
+                    data: {},
71
+                    extraData: super.state,
72
+                    keyExtractor: this.getKeyExtractor
73
+                }
74
+            ];
75
+        }
76
+        // fetched data is an array here
77
+        for (let i = 0; i < fetchedData.length; i++) {
78
+            result.push(
79
+                {
80
+                    title: this.getFormattedDate(fetchedData[i].date),
81
+                    data: fetchedData[i].meal[0].foodcategory,
82
+                    extraData: super.state,
83
+                    keyExtractor: this.getKeyExtractor
84
+                }
85
+            );
86
+        }
87
+        return result
38 88
     }
39 89
 
40
-    getRefreshButton() {
90
+    getFormattedDate(dateString: string) {
91
+        let dateArray = dateString.split('-');
92
+        let date = new Date();
93
+        date.setFullYear(parseInt(dateArray[0]), parseInt(dateArray[1]) - 1, parseInt(dateArray[2]));
94
+        return this.daysOfWeek[date.getDay() - 1] + " " + date.getDate() + " " + this.monthsOfYear[date.getMonth()] + " " + date.getFullYear();
95
+    }
96
+
97
+    getRenderSectionHeader(title: String) {
41 98
         return (
42
-            <Touchable
43
-                style={{padding: 6}}
44
-                onPress={() => this.refreshWebview()}>
45
-                <CustomMaterialIcon
46
-                    color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
47
-                    icon="refresh"/>
48
-            </Touchable>
99
+            <Card style={{
100
+                marginLeft: 10,
101
+                marginRight: 10,
102
+                marginTop: 10,
103
+                marginBottom: 10,
104
+            }}>
105
+                <H2 style={{
106
+                    textAlign: 'center',
107
+                    marginTop: 10,
108
+                    marginBottom: 10
109
+                }}>{title}</H2>
110
+            </Card>
49 111
         );
50
-    };
51
-
52
-    refreshWebview() {
53
-        this.webview.reload();
54 112
     }
55 113
 
56
-    render() {
57
-        const nav = this.props.navigation;
114
+    getRenderItem(item: Object, section: Object, data: Object) {
58 115
         return (
59
-            <Container>
60
-                <CustomHeader navigation={nav} title={i18n.t('screens.menuSelf')} hasBackButton={true}
61
-                              rightButton={this.getRefreshButton()}/>
62
-                <WebView
63
-                    ref={ref => (this.webview = ref)}
64
-                    source={{uri: RU_URL}}
65
-                    style={{
66
-                        width: '100%',
67
-                        height: '100%',
68
-                    }}
69
-                    startInLoadingState={true}
70
-                    injectedJavaScript={this.customInjectedJS}
71
-                    javaScriptEnabled={true}
72
-                    renderLoading={() =>
73
-                        <View style={{
74
-                            backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor,
75
-                            position: 'absolute',
76
-                            top: 0,
77
-                            right: 0,
78
-                            width: '100%',
79
-                            height: '100%',
80
-                            flex: 1,
81
-                            alignItems: 'center',
82
-                            justifyContent: 'center'
83
-                        }}>
84
-                            <Spinner/>
85
-                        </View>
86
-                    }
87
-                />
88
-            </Container>
116
+            <Card style={{
117
+                flex: 0,
118
+                marginLeft: 20,
119
+                marginRight: 20
120
+            }}>
121
+                <CardItem style={{
122
+                    paddingBottom: 0,
123
+                    flexDirection: 'column'
124
+                }}>
125
+                    <H3 style={{
126
+                        marginTop: 10,
127
+                        marginBottom: 0,
128
+                        color: ThemeManager.getCurrentThemeVariables().listNoteColor
129
+                    }}>{item.name}</H3>
130
+                    <View style={{
131
+                        width: '80%',
132
+                        marginLeft: 'auto',
133
+                        marginRight: 'auto',
134
+                        borderBottomWidth: 1,
135
+                        borderBottomColor: ThemeManager.getCurrentThemeVariables().listBorderColor,
136
+                        marginTop: 10,
137
+                        marginBottom: 5,
138
+                    }}/>
139
+                </CardItem>
140
+                <CardItem style={{
141
+                    flexDirection: 'column',
142
+                    paddingTop: 0,
143
+                }}>
144
+                    {item.dishes.map((object, i) =>
145
+                        <View>
146
+                            {object.name !== "" ?
147
+                                <Text style={{
148
+                                    marginTop: 5,
149
+                                    marginBottom: 5
150
+                                }}>{object.name.toLowerCase()}</Text>
151
+                                : <View/>}
152
+                        </View>)}
153
+                </CardItem>
154
+            </Card>
89 155
         );
90 156
     }
157
+
91 158
 }
92 159
 

+ 25
- 0
translations/en.json View File

@@ -151,5 +151,30 @@
151 151
   "general": {
152 152
     "loading": "Loading...",
153 153
     "networkError": "Unable to contact servers. Make sure you are connected to Internet."
154
+  },
155
+  "date": {
156
+    "daysOfWeek": {
157
+      "monday": "Monday",
158
+      "tuesday": "Tuesday",
159
+      "wednesday": "Wednesday",
160
+      "thursday": "Thursday",
161
+      "friday": "Friday",
162
+      "saturday": "Saturday",
163
+      "sunday": "Sunday"
164
+    },
165
+    "monthsOfYear": {
166
+      "january": "January",
167
+      "february": "February",
168
+      "march": "March",
169
+      "april": "April",
170
+      "may": "May",
171
+      "june": "June",
172
+      "july": "July",
173
+      "august": "August",
174
+      "september": "September",
175
+      "october": "October",
176
+      "november": "November",
177
+      "december": "December"
178
+    }
154 179
   }
155 180
 }

+ 26
- 1
translations/fr.json View File

@@ -4,7 +4,7 @@
4 4
     "planning": "Planning",
5 5
     "proxiwash": "Proxiwash",
6 6
     "proximo": "Proximo",
7
-    "menuSelf": "Menu Ru",
7
+    "menuSelf": "Menu du RU",
8 8
     "settings": "Paramètres",
9 9
     "about": "À Propos",
10 10
     "debug": "Debug"
@@ -153,5 +153,30 @@
153 153
   "general": {
154 154
     "loading": "Chargement...",
155 155
     "networkError": "Impossible de contacter les serveurs. Assurez vous d'être connecté à internet."
156
+  },
157
+  "date": {
158
+    "daysOfWeek": {
159
+      "monday": "Lundi",
160
+      "tuesday": "Mardi",
161
+      "wednesday": "Mercredi",
162
+      "thursday": "Jeudi",
163
+      "friday": "Vendredi",
164
+      "saturday": "Samedi",
165
+      "sunday": "Dimanche"
166
+    },
167
+    "monthsOfYear": {
168
+      "january": "Janvier",
169
+      "february": "Février",
170
+      "march": "Mars",
171
+      "april": "Avril",
172
+      "may": "Mai",
173
+      "june": "Juin",
174
+      "july": "Juillet",
175
+      "august": "Août",
176
+      "september": "Septembre",
177
+      "october": "Octobre",
178
+      "november": "Novembre",
179
+      "december": "Décembre"
180
+    }
156 181
   }
157 182
 }

Loading…
Cancel
Save