Browse Source

Update Planex screens to use TypeScript

Arnaud Vergnet 3 years ago
parent
commit
742cb1802d
2 changed files with 77 additions and 62 deletions
  1. 35
    30
      src/screens/Planex/GroupSelectionScreen.tsx
  2. 42
    32
      src/screens/Planex/PlanexScreen.tsx

src/screens/Planex/GroupSelectionScreen.js → src/screens/Planex/GroupSelectionScreen.tsx View File

17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
  */
18
  */
19
 
19
 
20
-// @flow
21
-
22
 import * as React from 'react';
20
 import * as React from 'react';
23
 import {Platform} from 'react-native';
21
 import {Platform} from 'react-native';
24
 import i18n from 'i18n-js';
22
 import i18n from 'i18n-js';
32
 const LIST_ITEM_HEIGHT = 70;
30
 const LIST_ITEM_HEIGHT = 70;
33
 
31
 
34
 export type PlanexGroupType = {
32
 export type PlanexGroupType = {
35
-  name: string,
36
-  id: number,
33
+  name: string;
34
+  id: number;
37
 };
35
 };
38
 
36
 
39
 export type PlanexGroupCategoryType = {
37
 export type PlanexGroupCategoryType = {
40
-  name: string,
41
-  id: number,
42
-  content: Array<PlanexGroupType>,
38
+  name: string;
39
+  id: number;
40
+  content: Array<PlanexGroupType>;
43
 };
41
 };
44
 
42
 
45
 type PropsType = {
43
 type PropsType = {
46
-  navigation: StackNavigationProp,
44
+  navigation: StackNavigationProp<any>;
47
 };
45
 };
48
 
46
 
49
 type StateType = {
47
 type StateType = {
50
-  currentSearchString: string,
51
-  favoriteGroups: Array<PlanexGroupType>,
48
+  currentSearchString: string;
49
+  favoriteGroups: Array<PlanexGroupType>;
52
 };
50
 };
53
 
51
 
54
 function sortName(
52
 function sortName(
55
   a: PlanexGroupType | PlanexGroupCategoryType,
53
   a: PlanexGroupType | PlanexGroupCategoryType,
56
   b: PlanexGroupType | PlanexGroupCategoryType,
54
   b: PlanexGroupType | PlanexGroupCategoryType,
57
 ): number {
55
 ): number {
58
-  if (a.name.toLowerCase() < b.name.toLowerCase()) return -1;
59
-  if (a.name.toLowerCase() > b.name.toLowerCase()) return 1;
56
+  if (a.name.toLowerCase() < b.name.toLowerCase()) {
57
+    return -1;
58
+  }
59
+  if (a.name.toLowerCase() > b.name.toLowerCase()) {
60
+    return 1;
61
+  }
60
   return 0;
62
   return 0;
61
 }
63
 }
62
 
64
 
96
    *
98
    *
97
    * @return {*}
99
    * @return {*}
98
    */
100
    */
99
-  getSearchBar = (): React.Node => {
101
+  getSearchBar = () => {
100
     return (
102
     return (
103
+      // @ts-ignore
101
       <Searchbar
104
       <Searchbar
102
         placeholder={i18n.t('screens.proximo.search')}
105
         placeholder={i18n.t('screens.proximo.search')}
103
         onChangeText={this.onSearchStringChange}
106
         onChangeText={this.onSearchStringChange}
111
    * @param item The article to render
114
    * @param item The article to render
112
    * @return {*}
115
    * @return {*}
113
    */
116
    */
114
-  getRenderItem = ({item}: {item: PlanexGroupCategoryType}): React.Node => {
117
+  getRenderItem = ({item}: {item: PlanexGroupCategoryType}) => {
115
     const {currentSearchString, favoriteGroups} = this.state;
118
     const {currentSearchString, favoriteGroups} = this.state;
116
     if (
119
     if (
117
       this.shouldDisplayAccordion(item) ||
120
       this.shouldDisplayAccordion(item) ||
138
    * @return {*}
141
    * @return {*}
139
    * */
142
    * */
140
   createDataset = (fetchedData: {
143
   createDataset = (fetchedData: {
141
-    [key: string]: PlanexGroupCategoryType,
142
-  }): Array<{title: string, data: Array<PlanexGroupCategoryType>}> => {
144
+    [key: string]: PlanexGroupCategoryType;
145
+  }): Array<{title: string; data: Array<PlanexGroupCategoryType>}> => {
143
     return [
146
     return [
144
       {
147
       {
145
         title: '',
148
         title: '',
190
     let isFav = false;
193
     let isFav = false;
191
     const {favoriteGroups} = this.state;
194
     const {favoriteGroups} = this.state;
192
     favoriteGroups.forEach((favGroup: PlanexGroupType) => {
195
     favoriteGroups.forEach((favGroup: PlanexGroupType) => {
193
-      if (group.id === favGroup.id) isFav = true;
196
+      if (group.id === favGroup.id) {
197
+        isFav = true;
198
+      }
194
     });
199
     });
195
     return isFav;
200
     return isFav;
196
   }
201
   }
202
    * @param group The group to add/remove to favorites
207
    * @param group The group to add/remove to favorites
203
    */
208
    */
204
   updateGroupFavorites(group: PlanexGroupType) {
209
   updateGroupFavorites(group: PlanexGroupType) {
205
-    if (this.isGroupInFavorites(group)) this.removeGroupFromFavorites(group);
206
-    else this.addGroupToFavorites(group);
210
+    if (this.isGroupInFavorites(group)) {
211
+      this.removeGroupFromFavorites(group);
212
+    } else {
213
+      this.addGroupToFavorites(group);
214
+    }
207
   }
215
   }
208
 
216
 
209
   /**
217
   /**
232
    * @returns {[]}
240
    * @returns {[]}
233
    */
241
    */
234
   generateData(fetchedData: {
242
   generateData(fetchedData: {
235
-    [key: string]: PlanexGroupCategoryType,
243
+    [key: string]: PlanexGroupCategoryType;
236
   }): Array<PlanexGroupCategoryType> {
244
   }): Array<PlanexGroupCategoryType> {
237
     const {favoriteGroups} = this.state;
245
     const {favoriteGroups} = this.state;
238
-    const data = [];
239
-    // eslint-disable-next-line flowtype/no-weak-types
240
-    (Object.values(fetchedData): Array<any>).forEach(
241
-      (category: PlanexGroupCategoryType) => {
242
-        data.push(category);
243
-      },
244
-    );
246
+    const data: Array<PlanexGroupCategoryType> = [];
247
+    Object.values(fetchedData).forEach((category: PlanexGroupCategoryType) => {
248
+      data.push(category);
249
+    });
245
     data.sort(sortName);
250
     data.sort(sortName);
246
     data.unshift({
251
     data.unshift({
247
       name: i18n.t('screens.planex.favorites'),
252
       name: i18n.t('screens.planex.favorites'),
258
    */
263
    */
259
   removeGroupFromFavorites(group: PlanexGroupType) {
264
   removeGroupFromFavorites(group: PlanexGroupType) {
260
     this.setState((prevState: StateType): {
265
     this.setState((prevState: StateType): {
261
-      favoriteGroups: Array<PlanexGroupType>,
266
+      favoriteGroups: Array<PlanexGroupType>;
262
     } => {
267
     } => {
263
       const {favoriteGroups} = prevState;
268
       const {favoriteGroups} = prevState;
264
       for (let i = 0; i < favoriteGroups.length; i += 1) {
269
       for (let i = 0; i < favoriteGroups.length; i += 1) {
282
    */
287
    */
283
   addGroupToFavorites(group: PlanexGroupType) {
288
   addGroupToFavorites(group: PlanexGroupType) {
284
     this.setState((prevState: StateType): {
289
     this.setState((prevState: StateType): {
285
-      favoriteGroups: Array<PlanexGroupType>,
290
+      favoriteGroups: Array<PlanexGroupType>;
286
     } => {
291
     } => {
287
       const {favoriteGroups} = prevState;
292
       const {favoriteGroups} = prevState;
288
       favoriteGroups.push(group);
293
       favoriteGroups.push(group);
295
     });
300
     });
296
   }
301
   }
297
 
302
 
298
-  render(): React.Node {
303
+  render() {
299
     const {props, state} = this;
304
     const {props, state} = this;
300
     return (
305
     return (
301
       <WebSectionList
306
       <WebSectionList

src/screens/Planex/PlanexScreen.js → src/screens/Planex/PlanexScreen.tsx View File

22
 import * as React from 'react';
22
 import * as React from 'react';
23
 import {Title, withTheme} from 'react-native-paper';
23
 import {Title, withTheme} from 'react-native-paper';
24
 import i18n from 'i18n-js';
24
 import i18n from 'i18n-js';
25
-import {View} from 'react-native';
25
+import {NativeScrollEvent, NativeSyntheticEvent, View} from 'react-native';
26
 import {CommonActions} from '@react-navigation/native';
26
 import {CommonActions} from '@react-navigation/native';
27
 import {StackNavigationProp} from '@react-navigation/stack';
27
 import {StackNavigationProp} from '@react-navigation/stack';
28
 import Autolink from 'react-native-autolink';
28
 import Autolink from 'react-native-autolink';
29
-import type {CustomThemeType} from '../../managers/ThemeManager';
30
 import ThemeManager from '../../managers/ThemeManager';
29
 import ThemeManager from '../../managers/ThemeManager';
31
 import WebViewScreen from '../../components/Screens/WebViewScreen';
30
 import WebViewScreen from '../../components/Screens/WebViewScreen';
32
 import AsyncStorageManager from '../../managers/AsyncStorageManager';
31
 import AsyncStorageManager from '../../managers/AsyncStorageManager';
40
 import MascotPopup from '../../components/Mascot/MascotPopup';
39
 import MascotPopup from '../../components/Mascot/MascotPopup';
41
 
40
 
42
 type PropsType = {
41
 type PropsType = {
43
-  navigation: StackNavigationProp,
44
-  route: {params: {group: PlanexGroupType}},
45
-  theme: CustomThemeType,
42
+  navigation: StackNavigationProp<any>;
43
+  route: {params: {group: PlanexGroupType}};
44
+  theme: ReactNativePaper.Theme;
46
 };
45
 };
47
 
46
 
48
 type StateType = {
47
 type StateType = {
49
-  dialogVisible: boolean,
50
-  dialogTitle: string | React.Node,
51
-  dialogMessage: string,
52
-  currentGroup: PlanexGroupType,
48
+  dialogVisible: boolean;
49
+  dialogTitle: string | React.ReactNode;
50
+  dialogMessage: string;
51
+  currentGroup: PlanexGroupType;
53
 };
52
 };
54
 
53
 
55
 const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
54
 const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
154
     super(props);
153
     super(props);
155
     this.webScreenRef = React.createRef();
154
     this.webScreenRef = React.createRef();
156
     this.barRef = React.createRef();
155
     this.barRef = React.createRef();
157
-
158
-    let currentGroup = AsyncStorageManager.getString(
156
+    this.customInjectedJS = '';
157
+    let currentGroupString = AsyncStorageManager.getString(
159
       AsyncStorageManager.PREFERENCES.planexCurrentGroup.key,
158
       AsyncStorageManager.PREFERENCES.planexCurrentGroup.key,
160
     );
159
     );
161
-    if (currentGroup === '')
162
-      currentGroup = {name: 'SELECT GROUP', id: -1, isFav: false};
163
-    else {
164
-      currentGroup = JSON.parse(currentGroup);
160
+    let currentGroup: PlanexGroupType;
161
+    if (currentGroupString === '') {
162
+      currentGroup = {name: 'SELECT GROUP', id: -1};
163
+    } else {
164
+      currentGroup = JSON.parse(currentGroupString);
165
       props.navigation.setOptions({title: currentGroup.name});
165
       props.navigation.setOptions({title: currentGroup.name});
166
     }
166
     }
167
     this.state = {
167
     this.state = {
189
    */
189
    */
190
   shouldComponentUpdate(nextProps: PropsType): boolean {
190
   shouldComponentUpdate(nextProps: PropsType): boolean {
191
     const {props, state} = this;
191
     const {props, state} = this;
192
-    if (nextProps.theme.dark !== props.theme.dark)
192
+    if (nextProps.theme.dark !== props.theme.dark) {
193
       this.generateInjectedJS(state.currentGroup.id);
193
       this.generateInjectedJS(state.currentGroup.id);
194
+    }
194
     return true;
195
     return true;
195
   }
196
   }
196
 
197
 
199
    *
200
    *
200
    * @returns {*}
201
    * @returns {*}
201
    */
202
    */
202
-  getWebView(): React.Node {
203
+  getWebView() {
203
     const {props, state} = this;
204
     const {props, state} = this;
204
     const showWebview = state.currentGroup.id !== -1;
205
     const showWebview = state.currentGroup.id !== -1;
205
 
206
 
246
    * Or "setGroup" with the group id as data to set the selected group
247
    * Or "setGroup" with the group id as data to set the selected group
247
    * @param data Data to pass to the action
248
    * @param data Data to pass to the action
248
    */
249
    */
249
-  sendMessage = (action: string, data: string) => {
250
+  sendMessage = (action: string, data?: string) => {
250
     let command;
251
     let command;
251
-    if (action === 'setGroup') command = `displayAde(${data})`;
252
-    else command = `$('#calendar').fullCalendar('${action}', '${data}')`;
253
-    if (this.webScreenRef.current != null)
254
-      this.webScreenRef.current.injectJavaScript(`${command};true;`); // Injected javascript must end with true
252
+    if (action === 'setGroup') {
253
+      command = `displayAde(${data})`;
254
+    } else {
255
+      command = `$('#calendar').fullCalendar('${action}', '${data}')`;
256
+    }
257
+    if (this.webScreenRef.current != null) {
258
+      this.webScreenRef.current.injectJavaScript(`${command};true;`);
259
+    } // Injected javascript must end with true
255
   };
260
   };
256
 
261
 
257
   /**
262
   /**
261
    */
266
    */
262
   onMessage = (event: {nativeEvent: {data: string}}) => {
267
   onMessage = (event: {nativeEvent: {data: string}}) => {
263
     const data: {
268
     const data: {
264
-      start: string,
265
-      end: string,
266
-      title: string,
267
-      color: string,
269
+      start: string;
270
+      end: string;
271
+      title: string;
272
+      color: string;
268
     } = JSON.parse(event.nativeEvent.data);
273
     } = JSON.parse(event.nativeEvent.data);
269
     const startDate = dateToString(new Date(data.start), true);
274
     const startDate = dateToString(new Date(data.start), true);
270
     const endDate = dateToString(new Date(data.end), true);
275
     const endDate = dateToString(new Date(data.end), true);
272
     const endString = getTimeOnlyString(endDate);
277
     const endString = getTimeOnlyString(endDate);
273
 
278
 
274
     let msg = `${DateManager.getInstance().getTranslatedDate(startDate)}\n`;
279
     let msg = `${DateManager.getInstance().getTranslatedDate(startDate)}\n`;
275
-    if (startString != null && endString != null)
280
+    if (startString != null && endString != null) {
276
       msg += `${startString} - ${endString}`;
281
       msg += `${startString} - ${endString}`;
282
+    }
277
     this.showDialog(data.title, msg);
283
     this.showDialog(data.title, msg);
278
   };
284
   };
279
 
285
 
286
   showDialog = (title: string, message: string) => {
292
   showDialog = (title: string, message: string) => {
287
     this.setState({
293
     this.setState({
288
       dialogVisible: true,
294
       dialogVisible: true,
289
-      dialogTitle: <Autolink text={title} component={Title}/>,
295
+      // @ts-ignore
296
+      dialogTitle: <Autolink text={title} component={Title} />,
290
       dialogMessage: message,
297
       dialogMessage: message,
291
     });
298
     });
292
   };
299
   };
305
    *
312
    *
306
    * @param event
313
    * @param event
307
    */
314
    */
308
-  onScroll = (event: SyntheticEvent<EventTarget>) => {
309
-    if (this.barRef.current != null) this.barRef.current.onScroll(event);
315
+  onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
316
+    if (this.barRef.current != null) {
317
+      this.barRef.current.onScroll(event);
318
+    }
310
   };
319
   };
311
 
320
 
312
   /**
321
   /**
354
       DateManager.isWeekend(new Date()) ? 'calendar.next()' : ''
363
       DateManager.isWeekend(new Date()) ? 'calendar.next()' : ''
355
     }${INJECT_STYLE}`;
364
     }${INJECT_STYLE}`;
356
 
365
 
357
-    if (ThemeManager.getNightMode())
366
+    if (ThemeManager.getNightMode()) {
358
       this.customInjectedJS += `$('head').append('<style>${CUSTOM_CSS_DARK}</style>');`;
367
       this.customInjectedJS += `$('head').append('<style>${CUSTOM_CSS_DARK}</style>');`;
368
+    }
359
 
369
 
360
     this.customInjectedJS += 'removeAlpha();});true;'; // Prevents crash on ios
370
     this.customInjectedJS += 'removeAlpha();});true;'; // Prevents crash on ios
361
   }
371
   }
362
 
372
 
363
-  render(): React.Node {
373
+  render() {
364
     const {props, state} = this;
374
     const {props, state} = this;
365
     return (
375
     return (
366
       <View style={{flex: 1}}>
376
       <View style={{flex: 1}}>

Loading…
Cancel
Save