Browse Source

Update home screens to use TypeScript

Arnaud Vergnet 1 year ago
parent
commit
c198a40148

+ 4
- 4
src/components/Home/SmallDashboardItem.tsx View File

@@ -23,9 +23,9 @@ import {Dimensions, Image, View} from 'react-native';
23 23
 import * as Animatable from 'react-native-animatable';
24 24
 
25 25
 type PropsType = {
26
-  image: string | null;
27
-  onPress: () => void | null;
28
-  badgeCount: number | null;
26
+  image?: string | number;
27
+  onPress?: () => void;
28
+  badgeCount?: number;
29 29
 };
30 30
 
31 31
 /**
@@ -50,7 +50,7 @@ function SmallDashboardItem(props: PropsType) {
50 50
         }}>
51 51
         {image ? (
52 52
           <Image
53
-            source={{uri: image}}
53
+            source={typeof image === 'string' ? {uri: image} : image}
54 54
             style={{
55 55
               width: '80%',
56 56
               height: '80%',

src/screens/Home/FeedItemScreen.js → src/screens/Home/FeedItemScreen.tsx View File

@@ -17,11 +17,9 @@
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 21
 import {Linking, Image} from 'react-native';
24
-import {Card, Text, withTheme} from 'react-native-paper';
22
+import {Card, Text} from 'react-native-paper';
25 23
 import Autolink from 'react-native-autolink';
26 24
 import {StackNavigationProp} from '@react-navigation/stack';
27 25
 import MaterialHeaderButtons, {
@@ -31,12 +29,14 @@ import CustomTabBar from '../../components/Tabbar/CustomTabBar';
31 29
 import type {FeedItemType} from './HomeScreen';
32 30
 import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
33 31
 import ImageGalleryButton from '../../components/Media/ImageGalleryButton';
34
-import NewsSourcesConstants from '../../constants/NewsSourcesConstants';
32
+import NewsSourcesConstants, {
33
+  AvailablePages,
34
+} from '../../constants/NewsSourcesConstants';
35 35
 import type {NewsSourceType} from '../../constants/NewsSourcesConstants';
36 36
 
37 37
 type PropsType = {
38
-  navigation: StackNavigationProp,
39
-  route: {params: {data: FeedItemType, date: string}},
38
+  navigation: StackNavigationProp<any>;
39
+  route: {params: {data: FeedItemType; date: string}};
40 40
 };
41 41
 
42 42
 /**
@@ -72,7 +72,7 @@ class FeedItemScreen extends React.Component<PropsType> {
72 72
    *
73 73
    * @returns {*}
74 74
    */
75
-  getHeaderButton = (): React.Node => {
75
+  getHeaderButton = () => {
76 76
     return (
77 77
       <MaterialHeaderButtons>
78 78
         <Item
@@ -85,20 +85,16 @@ class FeedItemScreen extends React.Component<PropsType> {
85 85
     );
86 86
   };
87 87
 
88
-  render(): React.Node {
89
-    const {navigation} = this.props;
90
-    const hasImage =
91
-      this.displayData.image !== '' && this.displayData.image != null;
88
+  render() {
92 89
     const pageSource: NewsSourceType =
93
-      NewsSourcesConstants[this.displayData.page_id];
90
+      NewsSourcesConstants[this.displayData.page_id as AvailablePages];
94 91
     return (
95 92
       <CollapsibleScrollView style={{margin: 5}} hasTab>
96 93
         <Card.Title
97 94
           title={pageSource.name}
98 95
           subtitle={this.date}
99
-          left={(): React.Node => (
96
+          left={() => (
100 97
             <Image
101
-              size={48}
102 98
               source={pageSource.icon}
103 99
               style={{
104 100
                 width: 48,
@@ -107,9 +103,8 @@ class FeedItemScreen extends React.Component<PropsType> {
107 103
             />
108 104
           )}
109 105
         />
110
-        {hasImage ? (
106
+        {this.displayData.image ? (
111 107
           <ImageGalleryButton
112
-            navigation={navigation}
113 108
             images={[{url: this.displayData.image}]}
114 109
             style={{
115 110
               width: 250,
@@ -124,6 +119,7 @@ class FeedItemScreen extends React.Component<PropsType> {
124 119
             <Autolink
125 120
               text={this.displayData.message}
126 121
               hashtag="facebook"
122
+              // @ts-ignore
127 123
               component={Text}
128 124
             />
129 125
           ) : null}
@@ -133,4 +129,4 @@ class FeedItemScreen extends React.Component<PropsType> {
133 129
   }
134 130
 }
135 131
 
136
-export default withTheme(FeedItemScreen);
132
+export default FeedItemScreen;

src/screens/Home/HomeScreen.js → src/screens/Home/HomeScreen.tsx View File

@@ -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
         />

src/screens/Home/ScannerScreen.js → src/screens/Home/ScannerScreen.tsx View File

@@ -17,11 +17,9 @@
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 21
 import {Linking, Platform, StyleSheet, View} from 'react-native';
24
-import {Button, Text, withTheme} from 'react-native-paper';
22
+import {Button, Text} from 'react-native-paper';
25 23
 import {RNCamera} from 'react-native-camera';
26 24
 import {BarcodeMask} from '@nartc/react-native-barcode-mask';
27 25
 import i18n from 'i18n-js';
@@ -34,11 +32,11 @@ import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
34 32
 import MascotPopup from '../../components/Mascot/MascotPopup';
35 33
 
36 34
 type StateType = {
37
-  hasPermission: boolean,
38
-  scanned: boolean,
39
-  dialogVisible: boolean,
40
-  mascotDialogVisible: boolean,
41
-  loading: boolean,
35
+  hasPermission: boolean;
36
+  scanned: boolean;
37
+  dialogVisible: boolean;
38
+  mascotDialogVisible: boolean;
39
+  loading: boolean;
42 40
 };
43 41
 
44 42
 const styles = StyleSheet.create({
@@ -54,9 +52,11 @@ const styles = StyleSheet.create({
54 52
   },
55 53
 });
56 54
 
57
-class ScannerScreen extends React.Component<null, StateType> {
55
+type PermissionResults = 'unavailable' | 'denied' | 'blocked' | 'granted';
56
+
57
+class ScannerScreen extends React.Component<{}, StateType> {
58 58
   constructor() {
59
-    super();
59
+    super({});
60 60
     this.state = {
61 61
       hasPermission: false,
62 62
       scanned: false,
@@ -75,7 +75,7 @@ class ScannerScreen extends React.Component<null, StateType> {
75 75
    *
76 76
    * @returns {*}
77 77
    */
78
-  getPermissionScreen(): React.Node {
78
+  getPermissionScreen() {
79 79
     return (
80 80
       <View style={{marginLeft: 10, marginRight: 10}}>
81 81
         <Text>{i18n.t('screens.scanner.permissions.error')}</Text>
@@ -101,15 +101,13 @@ class ScannerScreen extends React.Component<null, StateType> {
101 101
    *
102 102
    * @returns {*}
103 103
    */
104
-  getScanner(): React.Node {
104
+  getScanner() {
105 105
     const {state} = this;
106 106
     return (
107 107
       <RNCamera
108
-        onBarCodeRead={state.scanned ? null : this.onCodeScanned}
108
+        onBarCodeRead={state.scanned ? undefined : this.onCodeScanned}
109 109
         type={RNCamera.Constants.Type.back}
110
-        barCodeScannerSettings={{
111
-          barCodeTypes: [RNCamera.Constants.BarCodeType.qr],
112
-        }}
110
+        barCodeTypes={['qr']}
113 111
         style={StyleSheet.absoluteFill}
114 112
         captureAudio={false}>
115 113
         <BarcodeMask
@@ -128,9 +126,11 @@ class ScannerScreen extends React.Component<null, StateType> {
128 126
    * Requests permission to use the camera
129 127
    */
130 128
   requestPermissions = () => {
131
-    if (Platform.OS === 'android')
129
+    if (Platform.OS === 'android') {
132 130
       request(PERMISSIONS.ANDROID.CAMERA).then(this.updatePermissionStatus);
133
-    else request(PERMISSIONS.IOS.CAMERA).then(this.updatePermissionStatus);
131
+    } else {
132
+      request(PERMISSIONS.IOS.CAMERA).then(this.updatePermissionStatus);
133
+    }
134 134
   };
135 135
 
136 136
   /**
@@ -138,7 +138,7 @@ class ScannerScreen extends React.Component<null, StateType> {
138 138
    *
139 139
    * @param result
140 140
    */
141
-  updatePermissionStatus = (result: RESULTS) => {
141
+  updatePermissionStatus = (result: PermissionResults) => {
142 142
     this.setState({
143 143
       hasPermission: result === RESULTS.GRANTED,
144 144
     });
@@ -147,7 +147,6 @@ class ScannerScreen extends React.Component<null, StateType> {
147 147
   /**
148 148
    * Shows a dialog indicating the user the scanned code was invalid
149 149
    */
150
-  // eslint-disable-next-line react/sort-comp
151 150
   showErrorDialog() {
152 151
     this.setState({
153 152
       dialogVisible: true,
@@ -199,14 +198,15 @@ class ScannerScreen extends React.Component<null, StateType> {
199 198
    * @param data The scanned value
200 199
    */
201 200
   onCodeScanned = ({data}: {data: string}) => {
202
-    if (!URLHandler.isUrlValid(data)) this.showErrorDialog();
203
-    else {
201
+    if (!URLHandler.isUrlValid(data)) {
202
+      this.showErrorDialog();
203
+    } else {
204 204
       this.showOpeningDialog();
205 205
       Linking.openURL(data);
206 206
     }
207 207
   };
208 208
 
209
-  render(): React.Node {
209
+  render() {
210 210
     const {state} = this;
211 211
     return (
212 212
       <View
@@ -228,7 +228,6 @@ class ScannerScreen extends React.Component<null, StateType> {
228 228
           message={i18n.t('screens.scanner.mascotDialog.message')}
229 229
           icon="camera-iris"
230 230
           buttons={{
231
-            action: null,
232 231
             cancel: {
233 232
               message: i18n.t('screens.scanner.mascotDialog.button'),
234 233
               icon: 'check',
@@ -253,4 +252,4 @@ class ScannerScreen extends React.Component<null, StateType> {
253 252
   }
254 253
 }
255 254
 
256
-export default withTheme(ScannerScreen);
255
+export default ScannerScreen;

Loading…
Cancel
Save