Browse Source

Improved doc and typing, improved API connection handling

Arnaud Vergnet 3 years ago
parent
commit
b813aa0b83

+ 4
- 2
src/constants/Update.js View File

1
+// @flow
2
+
1
 import i18n from "i18n-js";
3
 import i18n from "i18n-js";
2
 
4
 
3
 /**
5
 /**
43
         this.titleList = [];
45
         this.titleList = [];
44
         this.descriptionList = [];
46
         this.descriptionList = [];
45
         for (let i = 0; i < Update.slidesNumber; i++) {
47
         for (let i = 0; i < Update.slidesNumber; i++) {
46
-            this.titleList.push(i18n.t('intro.updateSlide'+ i + '.title'))
47
-            this.descriptionList.push(i18n.t('intro.updateSlide'+ i + '.text'))
48
+            this.titleList.push(i18n.t('intro.updateSlide' + i + '.title'))
49
+            this.descriptionList.push(i18n.t('intro.updateSlide' + i + '.text'))
48
         }
50
         }
49
     }
51
     }
50
 
52
 

+ 37
- 10
src/managers/AprilFoolsManager.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import type {Machine} from "../screens/Proxiwash/ProxiwashScreen";
4
+
3
 /**
5
 /**
4
- * Singleton class used to manage themes
6
+ * Singleton class used to manage april fools
5
  */
7
  */
6
 export default class AprilFoolsManager {
8
 export default class AprilFoolsManager {
7
 
9
 
8
     static instance: AprilFoolsManager | null = null;
10
     static instance: AprilFoolsManager | null = null;
9
-
10
-    aprilFoolsEnabled: boolean;
11
-
12
     static fakeMachineNumber = [
11
     static fakeMachineNumber = [
13
         "",
12
         "",
14
         "cos(ln(1))",
13
         "cos(ln(1))",
24
         "1×10¹+1×10⁰",
23
         "1×10¹+1×10⁰",
25
         "Re(√192e^(iπ/6))",
24
         "Re(√192e^(iπ/6))",
26
     ];
25
     ];
26
+    aprilFoolsEnabled: boolean;
27
 
27
 
28
     constructor() {
28
     constructor() {
29
         let today = new Date();
29
         let today = new Date();
40
             AprilFoolsManager.instance;
40
             AprilFoolsManager.instance;
41
     }
41
     }
42
 
42
 
43
-    static getFakeMenuItem(menu: Object) {
43
+    /**
44
+     * Adds fake menu entries
45
+     *
46
+     * @param menu
47
+     * @returns {Object}
48
+     */
49
+    static getFakeMenuItem(menu: Array<{dishes: Array<{name: string}>}>) {
44
         menu[1]["dishes"].splice(4, 0, {name: "Coq au vin"});
50
         menu[1]["dishes"].splice(4, 0, {name: "Coq au vin"});
45
         menu[1]["dishes"].splice(2, 0, {name: "Bat'Soupe"});
51
         menu[1]["dishes"].splice(2, 0, {name: "Bat'Soupe"});
46
         menu[1]["dishes"].splice(1, 0, {name: "Pave de loup"});
52
         menu[1]["dishes"].splice(1, 0, {name: "Pave de loup"});
49
         return menu;
55
         return menu;
50
     }
56
     }
51
 
57
 
52
-    static getNewProxiwashDryerOrderedList(dryers: Array<Object>) {
53
-        if (dryers !== undefined) {
58
+    /**
59
+     * Changes proxiwash dryers order
60
+     *
61
+     * @param dryers
62
+     */
63
+    static getNewProxiwashDryerOrderedList(dryers: Array<Machine> | null) {
64
+        if (dryers != null) {
54
             let second = dryers[1];
65
             let second = dryers[1];
55
             dryers.splice(1, 1);
66
             dryers.splice(1, 1);
56
             dryers.push(second);
67
             dryers.push(second);
57
         }
68
         }
58
     }
69
     }
59
 
70
 
60
-    static getNewProxiwashWasherOrderedList(washers: Array<Object>) {
61
-        if (washers !== undefined) {
71
+    /**
72
+     * Changes proxiwash washers order
73
+     *
74
+     * @param washers
75
+     */
76
+    static getNewProxiwashWasherOrderedList(washers: Array<Machine> | null) {
77
+        if (washers != null) {
62
             let first = washers[0];
78
             let first = washers[0];
63
             let second = washers[1];
79
             let second = washers[1];
64
             let fifth = washers[4];
80
             let fifth = washers[4];
67
             washers.splice(4, 1, ninth);
83
             washers.splice(4, 1, ninth);
68
             washers.splice(1, 1, first);
84
             washers.splice(1, 1, first);
69
             washers.splice(0, 1, fifth);
85
             washers.splice(0, 1, fifth);
70
-            // washers.push(fifth);
71
         }
86
         }
72
     }
87
     }
73
 
88
 
89
+    /**
90
+     * Gets the new display number for the given machine number
91
+     *
92
+     * @param number
93
+     * @returns {string}
94
+     */
74
     static getProxiwashMachineDisplayNumber(number: number) {
95
     static getProxiwashMachineDisplayNumber(number: number) {
75
         return AprilFoolsManager.fakeMachineNumber[number];
96
         return AprilFoolsManager.fakeMachineNumber[number];
76
     }
97
     }
77
 
98
 
99
+    /**
100
+     * Gets the new and ugly april fools theme
101
+     *
102
+     * @param currentTheme
103
+     * @returns {{colors: {textDisabled: string, agendaDayTextColor: string, surface: string, background: string, dividerBackground: string, accent: string, agendaBackgroundColor: string, tabIcon: string, card: string, primary: string}}}
104
+     */
78
     static getAprilFoolsTheme(currentTheme: Object) {
105
     static getAprilFoolsTheme(currentTheme: Object) {
79
         return {
106
         return {
80
             ...currentTheme,
107
             ...currentTheme,

+ 64
- 27
src/managers/ConnectionManager.js View File

23
     #email: string;
23
     #email: string;
24
     #token: string | null;
24
     #token: string | null;
25
 
25
 
26
-    listeners: Array<Function>;
27
-
28
     constructor() {
26
     constructor() {
29
         this.#token = null;
27
         this.#token = null;
30
-        this.listeners = [];
31
     }
28
     }
32
 
29
 
33
     /**
30
     /**
34
-     * Get this class instance or create one if none is found
31
+     * Gets this class instance or create one if none is found
32
+     *
35
      * @returns {ConnectionManager}
33
      * @returns {ConnectionManager}
36
      */
34
      */
37
     static getInstance(): ConnectionManager {
35
     static getInstance(): ConnectionManager {
40
             ConnectionManager.instance;
38
             ConnectionManager.instance;
41
     }
39
     }
42
 
40
 
43
-    getToken() {
41
+    /**
42
+     * Gets the current token
43
+     *
44
+     * @returns {string | null}
45
+     */
46
+    getToken(): string | null {
44
         return this.#token;
47
         return this.#token;
45
     }
48
     }
46
 
49
 
47
-    onLoginStateChange(newState: boolean) {
48
-        for (let i = 0; i < this.listeners.length; i++) {
49
-            if (this.listeners[i] !== undefined)
50
-                this.listeners[i](newState);
51
-        }
52
-    }
53
-
54
-    addLoginStateListener(listener: Function) {
55
-        this.listeners.push(listener);
56
-    }
57
-
50
+    /**
51
+     * Tries to recover login token from the secure keychain
52
+     *
53
+     * @returns {Promise<R>}
54
+     */
58
     async recoverLogin() {
55
     async recoverLogin() {
59
         return new Promise((resolve, reject) => {
56
         return new Promise((resolve, reject) => {
60
             if (this.getToken() !== null)
57
             if (this.getToken() !== null)
64
                     .then((data) => {
61
                     .then((data) => {
65
                         if (data) {
62
                         if (data) {
66
                             this.#token = data.password;
63
                             this.#token = data.password;
67
-                            this.onLoginStateChange(true);
68
                             resolve(this.#token);
64
                             resolve(this.#token);
69
                         } else
65
                         } else
70
                             reject(false);
66
                             reject(false);
76
         });
72
         });
77
     }
73
     }
78
 
74
 
75
+    /**
76
+     * Check if the user has a valid token
77
+     *
78
+     * @returns {boolean}
79
+     */
79
     isLoggedIn() {
80
     isLoggedIn() {
80
         return this.getToken() !== null;
81
         return this.getToken() !== null;
81
     }
82
     }
82
 
83
 
84
+    /**
85
+     * Saves the login token in the secure keychain
86
+     *
87
+     * @param email
88
+     * @param token
89
+     * @returns {Promise<R>}
90
+     */
83
     async saveLogin(email: string, token: string) {
91
     async saveLogin(email: string, token: string) {
84
         return new Promise((resolve, reject) => {
92
         return new Promise((resolve, reject) => {
85
             Keychain.setInternetCredentials(SERVER_NAME, 'token', token)
93
             Keychain.setInternetCredentials(SERVER_NAME, 'token', token)
86
                 .then(() => {
94
                 .then(() => {
87
                     this.#token = token;
95
                     this.#token = token;
88
                     this.#email = email;
96
                     this.#email = email;
89
-                    this.onLoginStateChange(true);
90
                     resolve(true);
97
                     resolve(true);
91
                 })
98
                 })
92
                 .catch(() => {
99
                 .catch(() => {
95
         });
102
         });
96
     }
103
     }
97
 
104
 
105
+    /**
106
+     * Deletes the login token from the keychain
107
+     *
108
+     * @returns {Promise<R>}
109
+     */
98
     async disconnect() {
110
     async disconnect() {
99
         return new Promise((resolve, reject) => {
111
         return new Promise((resolve, reject) => {
100
             Keychain.resetInternetCredentials(SERVER_NAME)
112
             Keychain.resetInternetCredentials(SERVER_NAME)
101
                 .then(() => {
113
                 .then(() => {
102
                     this.#token = null;
114
                     this.#token = null;
103
-                    this.onLoginStateChange(false);
104
                     resolve(true);
115
                     resolve(true);
105
                 })
116
                 })
106
                 .catch(() => {
117
                 .catch(() => {
109
         });
120
         });
110
     }
121
     }
111
 
122
 
123
+
124
+    /**
125
+     * Sends the given login and password to the api.
126
+     * If the combination is valid, the login token is received and saved in the secure keychain.
127
+     * If not, the promise is rejected with the corresponding error code.
128
+     *
129
+     * @param email
130
+     * @param password
131
+     * @returns {Promise<R>}
132
+     */
112
     async connect(email: string, password: string) {
133
     async connect(email: string, password: string) {
113
         return new Promise((resolve, reject) => {
134
         return new Promise((resolve, reject) => {
114
             const data = {
135
             const data = {
117
             };
138
             };
118
             apiRequest(AUTH_PATH, 'POST', data)
139
             apiRequest(AUTH_PATH, 'POST', data)
119
                 .then((response) => {
140
                 .then((response) => {
120
-                    this.saveLogin(email, response.token)
121
-                        .then(() => {
122
-                            resolve(true);
123
-                        })
124
-                        .catch(() => {
125
-                            reject(ERROR_TYPE.TOKEN_SAVE);
126
-                        });
141
+                    if (this.isConnectionResponseValid(response)) {
142
+                        this.saveLogin(email, response.token)
143
+                            .then(() => {
144
+                                resolve(true);
145
+                            })
146
+                            .catch(() => {
147
+                                reject(ERROR_TYPE.TOKEN_SAVE);
148
+                            });
149
+                    } else
150
+                        reject(ERROR_TYPE.SERVER_ERROR);
127
                 })
151
                 })
128
                 .catch((error) => reject(error));
152
                 .catch((error) => reject(error));
129
         });
153
         });
130
     }
154
     }
131
 
155
 
132
-    isConnectionResponseValid(response: Object) {
156
+    /**
157
+     * Checks if the API connection response is correctly formatted
158
+     *
159
+     * @param response
160
+     * @returns {boolean}
161
+     */
162
+    isConnectionResponseValid(response: { [key: string]: any }) {
133
         let valid = isResponseValid(response);
163
         let valid = isResponseValid(response);
134
 
164
 
135
         if (valid && response.error === ERROR_TYPE.SUCCESS)
165
         if (valid && response.error === ERROR_TYPE.SUCCESS)
140
         return valid;
170
         return valid;
141
     }
171
     }
142
 
172
 
173
+    /**
174
+     * Sends an authenticated request with the login token to the API
175
+     *
176
+     * @param path
177
+     * @param params
178
+     * @returns {Promise<R>}
179
+     */
143
     async authenticatedRequest(path: string, params: Object) {
180
     async authenticatedRequest(path: string, params: Object) {
144
         return new Promise((resolve, reject) => {
181
         return new Promise((resolve, reject) => {
145
             if (this.getToken() !== null) {
182
             if (this.getToken() !== null) {

+ 4
- 4
src/managers/DateManager.js View File

45
             DateManager.instance;
45
             DateManager.instance;
46
     }
46
     }
47
 
47
 
48
+    static isWeekend(date: Date) {
49
+        return date.getDay() === 6 || date.getDay() === 0;
50
+    }
51
+
48
     /**
52
     /**
49
      * Gets a translated string representing the given date.
53
      * Gets a translated string representing the given date.
50
      *
54
      *
58
         return this.daysOfWeek[date.getDay()] + " " + date.getDate() + " " + this.monthsOfYear[date.getMonth()] + " " + date.getFullYear();
62
         return this.daysOfWeek[date.getDay()] + " " + date.getDate() + " " + this.monthsOfYear[date.getMonth()] + " " + date.getFullYear();
59
     }
63
     }
60
 
64
 
61
-    static isWeekend(date: Date) {
62
-        return date.getDay() === 6 || date.getDay() === 0;
63
-    }
64
-
65
 }
65
 }

+ 0
- 4
src/managers/LocaleManager.js View File

19
         i18n.translations = {fr, en};
19
         i18n.translations = {fr, en};
20
         i18n.locale = RNLocalize.findBestAvailableLanguage(["en", "fr"]).languageTag;
20
         i18n.locale = RNLocalize.findBestAvailableLanguage(["en", "fr"]).languageTag;
21
     }
21
     }
22
-
23
-    static getCurrentLocale() {
24
-        return RNLocalize.findBestAvailableLanguage(["en", "fr"]).languageTag;
25
-    }
26
 }
22
 }

+ 29
- 29
src/managers/ThemeManager.js View File

46
 
46
 
47
         // Tetris
47
         // Tetris
48
         tetrisBackground: string,
48
         tetrisBackground: string,
49
-        tetrisBorder:string,
50
-        tetrisScore:string,
51
-        tetrisI : string,
52
-        tetrisO : string,
53
-        tetrisT : string,
54
-        tetrisS : string,
55
-        tetrisZ : string,
56
-        tetrisJ : string,
57
-        tetrisL : string,
49
+        tetrisBorder: string,
50
+        tetrisScore: string,
51
+        tetrisI: string,
52
+        tetrisO: string,
53
+        tetrisT: string,
54
+        tetrisS: string,
55
+        tetrisZ: string,
56
+        tetrisJ: string,
57
+        tetrisL: string,
58
     },
58
     },
59
 }
59
 }
60
 
60
 
116
                 tutorinsaColor: '#f93943',
116
                 tutorinsaColor: '#f93943',
117
 
117
 
118
                 // Tetris
118
                 // Tetris
119
-                tetrisBackground:'#e6e6e6',
120
-                tetrisBorder:'#2f2f2f',
121
-                tetrisScore:'#e2bd33',
122
-                tetrisI : '#3cd9e6',
123
-                tetrisO : '#ffdd00',
124
-                tetrisT : '#a716e5',
125
-                tetrisS : '#09c528',
126
-                tetrisZ : '#ff0009',
127
-                tetrisJ : '#2a67e3',
128
-                tetrisL : '#da742d',
119
+                tetrisBackground: '#e6e6e6',
120
+                tetrisBorder: '#2f2f2f',
121
+                tetrisScore: '#e2bd33',
122
+                tetrisI: '#3cd9e6',
123
+                tetrisO: '#ffdd00',
124
+                tetrisT: '#a716e5',
125
+                tetrisS: '#09c528',
126
+                tetrisZ: '#ff0009',
127
+                tetrisJ: '#2a67e3',
128
+                tetrisL: '#da742d',
129
             },
129
             },
130
         };
130
         };
131
     }
131
     }
176
                 tutorinsaColor: '#f93943',
176
                 tutorinsaColor: '#f93943',
177
 
177
 
178
                 // Tetris
178
                 // Tetris
179
-                tetrisBackground:'#2c2c2c',
180
-                tetrisBorder:'#1b1b1b',
181
-                tetrisScore:'#e2d707',
182
-                tetrisI : '#30b3be',
183
-                tetrisO : '#c1a700',
184
-                tetrisT : '#9114c7',
185
-                tetrisS : '#08a121',
186
-                tetrisZ : '#b50008',
187
-                tetrisJ : '#0f37b9',
188
-                tetrisL : '#b96226',
179
+                tetrisBackground: '#2c2c2c',
180
+                tetrisBorder: '#1b1b1b',
181
+                tetrisScore: '#e2d707',
182
+                tetrisI: '#30b3be',
183
+                tetrisO: '#c1a700',
184
+                tetrisT: '#9114c7',
185
+                tetrisS: '#08a121',
186
+                tetrisZ: '#b50008',
187
+                tetrisJ: '#0f37b9',
188
+                tetrisL: '#b96226',
189
             },
189
             },
190
         };
190
         };
191
     }
191
     }

Loading…
Cancel
Save