Browse Source

Update services screens to use TypeScript

Arnaud Vergnet 1 year ago
parent
commit
38afbf02a3

src/screens/Services/SelfMenuScreen.js → src/screens/Services/SelfMenuScreen.tsx View File

@@ -17,8 +17,6 @@
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 {View} from 'react-native';
24 22
 import {Card, Text, withTheme} from 'react-native-paper';
@@ -26,32 +24,31 @@ import {StackNavigationProp} from '@react-navigation/stack';
26 24
 import i18n from 'i18n-js';
27 25
 import DateManager from '../../managers/DateManager';
28 26
 import WebSectionList from '../../components/Screens/WebSectionList';
29
-import type {CustomThemeType} from '../../managers/ThemeManager';
30 27
 import type {SectionListDataType} from '../../components/Screens/WebSectionList';
31 28
 
32 29
 const DATA_URL =
33 30
   'https://etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json';
34 31
 
35 32
 type PropsType = {
36
-  navigation: StackNavigationProp,
37
-  theme: CustomThemeType,
33
+  navigation: StackNavigationProp<any>;
34
+  theme: ReactNativePaper.Theme;
38 35
 };
39 36
 
40 37
 export type RuFoodCategoryType = {
41
-  name: string,
42
-  dishes: Array<{name: string}>,
38
+  name: string;
39
+  dishes: Array<{name: string}>;
43 40
 };
44 41
 
45 42
 type RuMealType = {
46
-  name: string,
47
-  foodcategory: Array<RuFoodCategoryType>,
43
+  name: string;
44
+  foodcategory: Array<RuFoodCategoryType>;
48 45
 };
49 46
 
50 47
 type RawRuMenuType = {
51
-  restaurant_id: number,
52
-  id: number,
53
-  date: string,
54
-  meal: Array<RuMealType>,
48
+  restaurant_id: number;
49
+  id: number;
50
+  date: string;
51
+  meal: Array<RuMealType>;
55 52
 };
56 53
 
57 54
 /**
@@ -77,7 +74,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
77 74
   createDataset = (
78 75
     fetchedData: Array<RawRuMenuType>,
79 76
   ): SectionListDataType<RuFoodCategoryType> => {
80
-    let result = [];
77
+    let result: SectionListDataType<RuFoodCategoryType> = [];
81 78
     if (fetchedData == null || fetchedData.length === 0) {
82 79
       result = [
83 80
         {
@@ -104,11 +101,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
104 101
    * @param section The section to render the header from
105 102
    * @return {*}
106 103
    */
107
-  getRenderSectionHeader = ({
108
-    section,
109
-  }: {
110
-    section: {title: string},
111
-  }): React.Node => {
104
+  getRenderSectionHeader = ({section}: {section: {title: string}}) => {
112 105
     return (
113 106
       <Card
114 107
         style={{
@@ -141,7 +134,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
141 134
    * @param item The item to render
142 135
    * @return {*}
143 136
    */
144
-  getRenderItem = ({item}: {item: RuFoodCategoryType}): React.Node => {
137
+  getRenderItem = ({item}: {item: RuFoodCategoryType}) => {
145 138
     const {theme} = this.props;
146 139
     return (
147 140
       <Card
@@ -163,7 +156,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
163 156
           }}
164 157
         />
165 158
         <Card.Content>
166
-          {item.dishes.map((object: {name: string}): React.Node =>
159
+          {item.dishes.map((object: {name: string}) =>
167 160
             object.name !== '' ? (
168 161
               <Text
169 162
                 style={{
@@ -188,7 +181,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
188 181
    */
189 182
   getKeyExtractor = (item: RuFoodCategoryType): string => item.name;
190 183
 
191
-  render(): React.Node {
184
+  render() {
192 185
     const {navigation} = this.props;
193 186
     return (
194 187
       <WebSectionList

src/screens/Services/ServicesScreen.js → src/screens/Services/ServicesScreen.tsx View File

@@ -17,8 +17,6 @@
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 {Image, View} from 'react-native';
24 22
 import {
@@ -32,7 +30,6 @@ import {
32 30
 import i18n from 'i18n-js';
33 31
 import {StackNavigationProp} from '@react-navigation/stack';
34 32
 import CardList from '../../components/Lists/CardList/CardList';
35
-import type {CustomThemeType} from '../../managers/ThemeManager';
36 33
 import MaterialHeaderButtons, {
37 34
   Item,
38 35
 } from '../../components/Overrides/CustomHeaderButton';
@@ -46,8 +43,8 @@ import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatLis
46 43
 import type {ServiceCategoryType} from '../../managers/ServicesManager';
47 44
 
48 45
 type PropsType = {
49
-  navigation: StackNavigationProp,
50
-  theme: CustomThemeType,
46
+  navigation: StackNavigationProp<any>;
47
+  theme: ReactNativePaper.Theme;
51 48
 };
52 49
 
53 50
 class ServicesScreen extends React.Component<PropsType> {
@@ -68,7 +65,7 @@ class ServicesScreen extends React.Component<PropsType> {
68 65
     });
69 66
   }
70 67
 
71
-  getAboutButton = (): React.Node => (
68
+  getAboutButton = () => (
72 69
     <MaterialHeaderButtons>
73 70
       <Item
74 71
         title="information"
@@ -92,12 +89,11 @@ class ServicesScreen extends React.Component<PropsType> {
92 89
    * @param source The source image to display. Can be a string for icons or a number for local images
93 90
    * @returns {*}
94 91
    */
95
-  getListTitleImage(source: string | number): React.Node {
92
+  getListTitleImage(source: string | number) {
96 93
     const {props} = this;
97
-    if (typeof source === 'number')
94
+    if (typeof source === 'number') {
98 95
       return (
99 96
         <Image
100
-          size={48}
101 97
           source={source}
102 98
           style={{
103 99
             width: 48,
@@ -105,6 +101,7 @@ class ServicesScreen extends React.Component<PropsType> {
105 101
           }}
106 102
         />
107 103
       );
104
+    }
108 105
     return (
109 106
       <Avatar.Icon
110 107
         size={48}
@@ -121,7 +118,7 @@ class ServicesScreen extends React.Component<PropsType> {
121 118
    * @param item
122 119
    * @returns {*}
123 120
    */
124
-  getRenderItem = ({item}: {item: ServiceCategoryType}): React.Node => {
121
+  getRenderItem = ({item}: {item: ServiceCategoryType}) => {
125 122
     const {props} = this;
126 123
     return (
127 124
       <TouchableRipple
@@ -136,8 +133,8 @@ class ServicesScreen extends React.Component<PropsType> {
136 133
           <Card.Title
137 134
             title={item.title}
138 135
             subtitle={item.subtitle}
139
-            left={(): React.Node => this.getListTitleImage(item.image)}
140
-            right={(): React.Node => <List.Icon icon="chevron-right" />}
136
+            left={() => this.getListTitleImage(item.image)}
137
+            right={() => <List.Icon icon="chevron-right" />}
141 138
           />
142 139
           <CardList dataset={item.content} isHorizontal />
143 140
         </View>
@@ -147,14 +144,14 @@ class ServicesScreen extends React.Component<PropsType> {
147 144
 
148 145
   keyExtractor = (item: ServiceCategoryType): string => item.title;
149 146
 
150
-  render(): React.Node {
147
+  render() {
151 148
     return (
152 149
       <View>
153 150
         <CollapsibleFlatList
154 151
           data={this.finalDataset}
155 152
           renderItem={this.getRenderItem}
156 153
           keyExtractor={this.keyExtractor}
157
-          ItemSeparatorComponent={(): React.Node => <Divider />}
154
+          ItemSeparatorComponent={() => <Divider />}
158 155
           hasTab
159 156
         />
160 157
         <MascotPopup
@@ -163,7 +160,6 @@ class ServicesScreen extends React.Component<PropsType> {
163 160
           message={i18n.t('screens.services.mascotDialog.message')}
164 161
           icon="cloud-question"
165 162
           buttons={{
166
-            action: null,
167 163
             cancel: {
168 164
               message: i18n.t('screens.services.mascotDialog.button'),
169 165
               icon: 'check',

src/screens/Services/ServicesSectionScreen.js → src/screens/Services/ServicesSectionScreen.tsx View File

@@ -17,28 +17,25 @@
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 {Collapsible} from 'react-navigation-collapsible';
24 22
 import {CommonActions} from '@react-navigation/native';
25 23
 import {StackNavigationProp} from '@react-navigation/stack';
26 24
 import CardList from '../../components/Lists/CardList/CardList';
27
-import CustomTabBar from '../../components/Tabbar/CustomTabBar';
28
-import withCollapsible from '../../utils/withCollapsible';
29 25
 import type {ServiceCategoryType} from '../../managers/ServicesManager';
30 26
 
31 27
 type PropsType = {
32
-  navigation: StackNavigationProp,
33
-  route: {params: {data: ServiceCategoryType | null}},
34
-  collapsibleStack: Collapsible,
28
+  navigation: StackNavigationProp<any>;
29
+  route: {params: {data: ServiceCategoryType | null}};
30
+  collapsibleStack: Collapsible;
35 31
 };
36 32
 
37 33
 class ServicesSectionScreen extends React.Component<PropsType> {
38
-  finalDataset: ServiceCategoryType;
34
+  finalDataset: null | ServiceCategoryType;
39 35
 
40 36
   constructor(props: PropsType) {
41 37
     super(props);
38
+    this.finalDataset = null;
42 39
     this.handleNavigationParams();
43 40
   }
44 41
 
@@ -47,38 +44,24 @@ class ServicesSectionScreen extends React.Component<PropsType> {
47 44
    */
48 45
   handleNavigationParams() {
49 46
     const {props} = this;
50
-    if (props.route.params != null) {
51
-      if (props.route.params.data != null) {
52
-        this.finalDataset = props.route.params.data;
53
-        // reset params to prevent infinite loop
54
-        props.navigation.dispatch(CommonActions.setParams({data: null}));
55
-        props.navigation.setOptions({
56
-          headerTitle: this.finalDataset.title,
57
-        });
58
-      }
47
+    if (props.route.params.data) {
48
+      this.finalDataset = props.route.params.data;
49
+      // reset params to prevent infinite loop
50
+      props.navigation.dispatch(CommonActions.setParams({data: null}));
51
+      props.navigation.setOptions({
52
+        headerTitle: this.finalDataset.title,
53
+      });
59 54
     }
60 55
   }
61 56
 
62
-  render(): React.Node {
63
-    const {props} = this;
64
-    const {
65
-      containerPaddingTop,
66
-      scrollIndicatorInsetTop,
67
-      onScroll,
68
-    } = props.collapsibleStack;
57
+  render() {
58
+    if (!this.finalDataset) {
59
+      return null;
60
+    }
69 61
     return (
70
-      <CardList
71
-        dataset={this.finalDataset.content}
72
-        isHorizontal={false}
73
-        onScroll={onScroll}
74
-        contentContainerStyle={{
75
-          paddingTop: containerPaddingTop,
76
-          paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20,
77
-        }}
78
-        scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
79
-      />
62
+      <CardList dataset={this.finalDataset.content} isHorizontal={false} />
80 63
     );
81 64
   }
82 65
 }
83 66
 
84
-export default withCollapsible(ServicesSectionScreen);
67
+export default ServicesSectionScreen;

src/screens/Services/WebsiteScreen.js → src/screens/Services/WebsiteScreen.tsx View File

@@ -17,8 +17,6 @@
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 {StackNavigationProp} from '@react-navigation/stack';
24 22
 import WebViewScreen from '../../components/Screens/WebViewScreen';
@@ -26,21 +24,24 @@ import AvailableWebsites from '../../constants/AvailableWebsites';
26 24
 import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen';
27 25
 
28 26
 type PropsType = {
29
-  navigation: StackNavigationProp,
30
-  route: {params: {host: string, path: string | null, title: string}},
27
+  navigation: StackNavigationProp<any>;
28
+  route: {params: {host: string; path: string | null; title: string}};
31 29
 };
32 30
 
33
-const ENABLE_MOBILE_STRING = `<meta name="viewport" content="width=device-width, initial-scale=1.0">`;
31
+const ENABLE_MOBILE_STRING =
32
+  '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
34 33
 
35
-const AVAILABLE_ROOMS_STYLE = `<style>body,body>.container2{padding-top:0;width:100%}b,body>.container2>h1,body>.container2>h3,br,header{display:none}.table-bordered td,.table-bordered th{border:none;border-right:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.table{padding:0;margin:0;width:200%;max-width:200%;display:block}tbody{display:block;width:100%}thead{display:block;width:100%}.table tbody tr,tbody tr[bgcolor],thead tr{width:100%;display:inline-flex}.table tbody td,.table thead td[colspan]{padding:0;flex:1;height:50px;margin:0}.table tbody td[bgcolor=white],.table thead td,.table>tbody>tr>td:nth-child(1){flex:0 0 150px;height:50px}</style>`;
36
-const BIB_STYLE = `<style>.hero-unit,.navbar,footer{display:none}.hero-unit-form,.hero-unit2,.hero-unit3{background-color:#fff;box-shadow:none;padding:0;margin:0}.hero-unit-form h4{font-size:2rem;line-height:2rem}.btn{font-size:1.5rem;line-height:1.5rem;padding:20px}.btn-danger{background-image:none;background-color:#be1522}.table{font-size:.8rem}.table td{padding:0;height:18.2333px;border:none;border-bottom:1px solid #c1c1c1}.table td[style="max-width:55px;"]{max-width:110px!important}.table-bordered{min-width:50px}th{height:50px}.table-bordered{border-collapse:collapse}</style>`;
34
+const AVAILABLE_ROOMS_STYLE =
35
+  '<style>body,body>.container2{padding-top:0;width:100%}b,body>.container2>h1,body>.container2>h3,br,header{display:none}.table-bordered td,.table-bordered th{border:none;border-right:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.table{padding:0;margin:0;width:200%;max-width:200%;display:block}tbody{display:block;width:100%}thead{display:block;width:100%}.table tbody tr,tbody tr[bgcolor],thead tr{width:100%;display:inline-flex}.table tbody td,.table thead td[colspan]{padding:0;flex:1;height:50px;margin:0}.table tbody td[bgcolor=white],.table thead td,.table>tbody>tr>td:nth-child(1){flex:0 0 150px;height:50px}</style>';
36
+const BIB_STYLE =
37
+  '<style>.hero-unit,.navbar,footer{display:none}.hero-unit-form,.hero-unit2,.hero-unit3{background-color:#fff;box-shadow:none;padding:0;margin:0}.hero-unit-form h4{font-size:2rem;line-height:2rem}.btn{font-size:1.5rem;line-height:1.5rem;padding:20px}.btn-danger{background-image:none;background-color:#be1522}.table{font-size:.8rem}.table td{padding:0;height:18.2333px;border:none;border-bottom:1px solid #c1c1c1}.table td[style="max-width:55px;"]{max-width:110px!important}.table-bordered{min-width:50px}th{height:50px}.table-bordered{border-collapse:collapse}</style>';
37 38
 
38 39
 const BIB_BACK_BUTTON =
39
-  `<div style='width: 100%; display: flex'>` +
40
+  "<div style='width: 100%; display: flex'>" +
40 41
   `<a style='margin: auto' href='${AvailableWebsites.websites.BIB}'>` +
41
-  `<button id='customBackButton' class='btn btn-primary'>Retour</button>` +
42
-  `</a>` +
43
-  `</div>`;
42
+  "<button id='customBackButton' class='btn btn-primary'>Retour</button>" +
43
+  '</a>' +
44
+  '</div>';
44 45
 
45 46
 class WebsiteScreen extends React.Component<PropsType> {
46 47
   fullUrl: string;
@@ -53,6 +54,8 @@ class WebsiteScreen extends React.Component<PropsType> {
53 54
 
54 55
   constructor(props: PropsType) {
55 56
     super(props);
57
+    this.fullUrl = '';
58
+    this.host = '';
56 59
     props.navigation.addListener('focus', this.onScreenFocus);
57 60
     this.injectedJS = {};
58 61
     this.customPaddingFunctions = {};
@@ -63,7 +66,7 @@ class WebsiteScreen extends React.Component<PropsType> {
63 66
     this.injectedJS[AvailableWebsites.websites.BIB] =
64 67
       `document.querySelector('head').innerHTML += '${ENABLE_MOBILE_STRING}';` +
65 68
       `document.querySelector('head').innerHTML += '${BIB_STYLE}';` +
66
-      `if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)` +
69
+      'if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)' +
67 70
       `$(".hero-unit-form").append("${BIB_BACK_BUTTON}");true;`;
68 71
 
69 72
     this.customPaddingFunctions[AvailableWebsites.websites.BLUEMIND] = (
@@ -72,7 +75,7 @@ class WebsiteScreen extends React.Component<PropsType> {
72 75
       return (
73 76
         `$('head').append('${ENABLE_MOBILE_STRING}');` +
74 77
         `$('.minwidth').css('top', ${padding}` +
75
-        `$('#mailview-bottom').css('min-height', 500);`
78
+        "$('#mailview-bottom').css('min-height', 500);"
76 79
       );
77 80
     };
78 81
     this.customPaddingFunctions[AvailableWebsites.websites.WIKETUD] = (
@@ -103,20 +106,26 @@ class WebsiteScreen extends React.Component<PropsType> {
103 106
       if (this.host != null && path != null) {
104 107
         path = path.replace(this.host, '');
105 108
         this.fullUrl = this.host + path;
106
-      } else this.fullUrl = this.host;
109
+      } else {
110
+        this.fullUrl = this.host;
111
+      }
107 112
 
108
-      if (title != null) navigation.setOptions({title});
113
+      if (title != null) {
114
+        navigation.setOptions({title});
115
+      }
109 116
     }
110 117
   }
111 118
 
112
-  render(): React.Node {
119
+  render() {
113 120
     const {navigation} = this.props;
114 121
     let injectedJavascript = '';
115 122
     let customPadding = null;
116
-    if (this.host != null && this.injectedJS[this.host] != null)
123
+    if (this.host != null && this.injectedJS[this.host] != null) {
117 124
       injectedJavascript = this.injectedJS[this.host];
118
-    if (this.host != null && this.customPaddingFunctions[this.host] != null)
125
+    }
126
+    if (this.host != null && this.customPaddingFunctions[this.host] != null) {
119 127
       customPadding = this.customPaddingFunctions[this.host];
128
+    }
120 129
 
121 130
     if (this.fullUrl != null) {
122 131
       return (

Loading…
Cancel
Save