forked from vergnet/application-amicale
		
	Implemented new RU menu screen
This commit is contained in:
		
							parent
							
								
									8c779e0ed6
								
							
						
					
					
						commit
						2ef349755a
					
				
					 6 changed files with 203 additions and 76 deletions
				
			
		
							
								
								
									
										4
									
								
								app.json
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								app.json
									
									
									
									
									
								
							|  | @ -10,7 +10,7 @@ | ||||||
|       "android", |       "android", | ||||||
|       "web" |       "web" | ||||||
|     ], |     ], | ||||||
|     "version": "1.0.3", |     "version": "1.1.0", | ||||||
|     "orientation": "portrait", |     "orientation": "portrait", | ||||||
|     "primaryColor": "#be1522", |     "primaryColor": "#be1522", | ||||||
|     "icon": "./assets/android.icon.png", |     "icon": "./assets/android.icon.png", | ||||||
|  | @ -36,7 +36,7 @@ | ||||||
|     }, |     }, | ||||||
|     "android": { |     "android": { | ||||||
|       "package": "fr.amicaleinsat.application", |       "package": "fr.amicaleinsat.application", | ||||||
|       "versionCode": 6, |       "versionCode": 7, | ||||||
|       "icon": "./assets/android.icon.png", |       "icon": "./assets/android.icon.png", | ||||||
|       "adaptiveIcon": { |       "adaptiveIcon": { | ||||||
|         "foregroundImage": "./assets/android.adaptive-icon.png", |         "foregroundImage": "./assets/android.adaptive-icon.png", | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ type Props = { | ||||||
|     headerRightButton: React.Node, |     headerRightButton: React.Node, | ||||||
|     children: React.Node, |     children: React.Node, | ||||||
|     hasTabs: boolean, |     hasTabs: boolean, | ||||||
|  |     hasBackButton: boolean | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type State = { | type State = { | ||||||
|  | @ -30,6 +31,7 @@ export default class BaseContainer extends React.Component<Props, State> { | ||||||
|     static defaultProps = { |     static defaultProps = { | ||||||
|         headerRightButton: <View/>, |         headerRightButton: <View/>, | ||||||
|         hasTabs: false, |         hasTabs: false, | ||||||
|  |         hasBackButton: false, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -90,7 +92,8 @@ export default class BaseContainer extends React.Component<Props, State> { | ||||||
|                                 </Touchable> |                                 </Touchable> | ||||||
|                             } |                             } | ||||||
|                             rightButton={this.props.headerRightButton} |                             rightButton={this.props.headerRightButton} | ||||||
|                             hasTabs={this.props.hasTabs}/> |                             hasTabs={this.props.hasTabs} | ||||||
|  |                             hasBackButton={this.props.hasBackButton}/> | ||||||
|                         {this.props.children} |                         {this.props.children} | ||||||
|                     </Container> |                     </Container> | ||||||
|                 </CustomSideMenu> |                 </CustomSideMenu> | ||||||
|  |  | ||||||
|  | @ -260,6 +260,10 @@ export default class FetchedDataSectionList extends React.Component<Props, State | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     hasBackButton() { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     getRightButton() { |     getRightButton() { | ||||||
|         return <View/> |         return <View/> | ||||||
|     } |     } | ||||||
|  | @ -277,6 +281,7 @@ export default class FetchedDataSectionList extends React.Component<Props, State | ||||||
|         return ( |         return ( | ||||||
|             <SectionList |             <SectionList | ||||||
|                 sections={dataset} |                 sections={dataset} | ||||||
|  |                 stickySectionHeadersEnabled | ||||||
|                 refreshControl={ |                 refreshControl={ | ||||||
|                     <RefreshControl |                     <RefreshControl | ||||||
|                         refreshing={this.state.refreshing} |                         refreshing={this.state.refreshing} | ||||||
|  | @ -345,7 +350,9 @@ export default class FetchedDataSectionList extends React.Component<Props, State | ||||||
|             <BaseContainer |             <BaseContainer | ||||||
|                 navigation={nav} headerTitle={this.getHeaderTranslation()} |                 navigation={nav} headerTitle={this.getHeaderTranslation()} | ||||||
|                 headerRightButton={this.getRightButton()} |                 headerRightButton={this.getRightButton()} | ||||||
|                 hasTabs={this.hasTabs()}> |                 hasTabs={this.hasTabs()} | ||||||
|  |                 hasBackButton={this.hasBackButton()} | ||||||
|  |             > | ||||||
|                 {this.hasTabs() ? |                 {this.hasTabs() ? | ||||||
|                     <Tabs |                     <Tabs | ||||||
|                         tabContainerStyle={{ |                         tabContainerStyle={{ | ||||||
|  |  | ||||||
|  | @ -1,92 +1,159 @@ | ||||||
| // @flow
 | // @flow
 | ||||||
| 
 | 
 | ||||||
| import * as React from 'react'; | import * as React from 'react'; | ||||||
| import {Platform, View} from 'react-native'; | import {View} from 'react-native'; | ||||||
| import {Container, Spinner} from 'native-base'; | import {Text, H2, H3, Card, CardItem} from 'native-base'; | ||||||
| import WebView from "react-native-webview"; |  | ||||||
| import Touchable from "react-native-platform-touchable"; |  | ||||||
| import CustomMaterialIcon from "../components/CustomMaterialIcon"; |  | ||||||
| import ThemeManager from "../utils/ThemeManager"; | import ThemeManager from "../utils/ThemeManager"; | ||||||
| import CustomHeader from "../components/CustomHeader"; |  | ||||||
| import i18n from "i18n-js"; | import i18n from "i18n-js"; | ||||||
|  | import FetchedDataSectionList from "../components/FetchedDataSectionList"; | ||||||
|  | import LocaleManager from "../utils/LocaleManager"; | ||||||
| 
 | 
 | ||||||
| type Props = { | const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json"; | ||||||
|     navigation: Object, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const RU_URL = 'http://m.insa-toulouse.fr/ru.html'; |  | ||||||
| const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/RU/customGeneral.css'; |  | ||||||
| const CUSTOM_CSS_LIGHT = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/RU/customLight.css'; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Class defining the app's planex screen. |  * Class defining the app's menu screen. | ||||||
|  * This screen uses a webview to render the planex page |  * This screen fetches data from etud to render the RU menu | ||||||
|  */ |  */ | ||||||
| export default class SelfMenuScreen extends React.Component<Props> { | export default class SelfMenuScreen extends FetchedDataSectionList { | ||||||
| 
 | 
 | ||||||
|     webview: WebView; |     // Hard code strings as toLocaleDateString does not work on current android JS engine
 | ||||||
|     customInjectedJS: string; |     daysOfWeek = []; | ||||||
|  |     monthsOfYear = []; | ||||||
| 
 | 
 | ||||||
|     constructor() { |     constructor() { | ||||||
|         super(); |         super(DATA_URL, 0); | ||||||
|         this.customInjectedJS = |         this.daysOfWeek.push(i18n.t("date.daysOfWeek.monday")); | ||||||
|             'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' + |         this.daysOfWeek.push(i18n.t("date.daysOfWeek.tuesday")); | ||||||
|             'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\';'; |         this.daysOfWeek.push(i18n.t("date.daysOfWeek.wednesday")); | ||||||
|         if (!ThemeManager.getNightMode()) |         this.daysOfWeek.push(i18n.t("date.daysOfWeek.thursday")); | ||||||
|             this.customInjectedJS += 'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_LIGHT + '" type="text/css"/>\';'; |         this.daysOfWeek.push(i18n.t("date.daysOfWeek.friday")); | ||||||
|  |         this.daysOfWeek.push(i18n.t("date.daysOfWeek.saturday")); | ||||||
|  |         this.daysOfWeek.push(i18n.t("date.daysOfWeek.sunday")); | ||||||
|  | 
 | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.january")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.february")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.march")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.april")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.may")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.june")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.july")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.august")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.september")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.october")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.november")); | ||||||
|  |         this.monthsOfYear.push(i18n.t("date.monthsOfYear.december")); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     getRefreshButton() { |     getHeaderTranslation() { | ||||||
|         return ( |         return i18n.t("screens.menuSelf"); | ||||||
|             <Touchable |  | ||||||
|                 style={{padding: 6}} |  | ||||||
|                 onPress={() => this.refreshWebview()}> |  | ||||||
|                 <CustomMaterialIcon |  | ||||||
|                     color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"} |  | ||||||
|                     icon="refresh"/> |  | ||||||
|             </Touchable> |  | ||||||
|         ); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     refreshWebview() { |  | ||||||
|         this.webview.reload(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     render() { |     getUpdateToastTranslations() { | ||||||
|         const nav = this.props.navigation; |         return [i18n.t("homeScreen.listUpdated"), i18n.t("homeScreen.listUpdateFail")]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     getKeyExtractor(item: Object) { | ||||||
|  |         return item !== undefined ? item.name : undefined; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     hasBackButton() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     createDataset(fetchedData: Object) { | ||||||
|  |         let result = []; | ||||||
|  |         // Prevent crash by giving a default value when fetchedData is empty (not yet available)
 | ||||||
|  |         if (Object.keys(fetchedData).length === 0) { | ||||||
|  |             result = [ | ||||||
|  |                 { | ||||||
|  |                     title: '', | ||||||
|  |                     data: {}, | ||||||
|  |                     extraData: super.state, | ||||||
|  |                     keyExtractor: this.getKeyExtractor | ||||||
|  |                 } | ||||||
|  |             ]; | ||||||
|  |         } | ||||||
|  |         // fetched data is an array here
 | ||||||
|  |         for (let i = 0; i < fetchedData.length; i++) { | ||||||
|  |             result.push( | ||||||
|  |                 { | ||||||
|  |                     title: this.getFormattedDate(fetchedData[i].date), | ||||||
|  |                     data: fetchedData[i].meal[0].foodcategory, | ||||||
|  |                     extraData: super.state, | ||||||
|  |                     keyExtractor: this.getKeyExtractor | ||||||
|  |                 } | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         return result | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     getFormattedDate(dateString: string) { | ||||||
|  |         let dateArray = dateString.split('-'); | ||||||
|  |         let date = new Date(); | ||||||
|  |         date.setFullYear(parseInt(dateArray[0]), parseInt(dateArray[1]) - 1, parseInt(dateArray[2])); | ||||||
|  |         return this.daysOfWeek[date.getDay() - 1] + " " + date.getDate() + " " + this.monthsOfYear[date.getMonth()] + " " + date.getFullYear(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     getRenderSectionHeader(title: String) { | ||||||
|         return ( |         return ( | ||||||
|             <Container> |             <Card style={{ | ||||||
|                 <CustomHeader navigation={nav} title={i18n.t('screens.menuSelf')} hasBackButton={true} |                 marginLeft: 10, | ||||||
|                               rightButton={this.getRefreshButton()}/> |                 marginRight: 10, | ||||||
|                 <WebView |                 marginTop: 10, | ||||||
|                     ref={ref => (this.webview = ref)} |                 marginBottom: 10, | ||||||
|                     source={{uri: RU_URL}} |             }}> | ||||||
|                     style={{ |                 <H2 style={{ | ||||||
|                         width: '100%', |                     textAlign: 'center', | ||||||
|                         height: '100%', |                     marginTop: 10, | ||||||
|                     }} |                     marginBottom: 10 | ||||||
|                     startInLoadingState={true} |                 }}>{title}</H2> | ||||||
|                     injectedJavaScript={this.customInjectedJS} |             </Card> | ||||||
|                     javaScriptEnabled={true} |  | ||||||
|                     renderLoading={() => |  | ||||||
|                         <View style={{ |  | ||||||
|                             backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor, |  | ||||||
|                             position: 'absolute', |  | ||||||
|                             top: 0, |  | ||||||
|                             right: 0, |  | ||||||
|                             width: '100%', |  | ||||||
|                             height: '100%', |  | ||||||
|                             flex: 1, |  | ||||||
|                             alignItems: 'center', |  | ||||||
|                             justifyContent: 'center' |  | ||||||
|                         }}> |  | ||||||
|                             <Spinner/> |  | ||||||
|                         </View> |  | ||||||
|                     } |  | ||||||
|                 /> |  | ||||||
|             </Container> |  | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     getRenderItem(item: Object, section: Object, data: Object) { | ||||||
|  |         return ( | ||||||
|  |             <Card style={{ | ||||||
|  |                 flex: 0, | ||||||
|  |                 marginLeft: 20, | ||||||
|  |                 marginRight: 20 | ||||||
|  |             }}> | ||||||
|  |                 <CardItem style={{ | ||||||
|  |                     paddingBottom: 0, | ||||||
|  |                     flexDirection: 'column' | ||||||
|  |                 }}> | ||||||
|  |                     <H3 style={{ | ||||||
|  |                         marginTop: 10, | ||||||
|  |                         marginBottom: 0, | ||||||
|  |                         color: ThemeManager.getCurrentThemeVariables().listNoteColor | ||||||
|  |                     }}>{item.name}</H3> | ||||||
|  |                     <View style={{ | ||||||
|  |                         width: '80%', | ||||||
|  |                         marginLeft: 'auto', | ||||||
|  |                         marginRight: 'auto', | ||||||
|  |                         borderBottomWidth: 1, | ||||||
|  |                         borderBottomColor: ThemeManager.getCurrentThemeVariables().listBorderColor, | ||||||
|  |                         marginTop: 10, | ||||||
|  |                         marginBottom: 5, | ||||||
|  |                     }}/> | ||||||
|  |                 </CardItem> | ||||||
|  |                 <CardItem style={{ | ||||||
|  |                     flexDirection: 'column', | ||||||
|  |                     paddingTop: 0, | ||||||
|  |                 }}> | ||||||
|  |                     {item.dishes.map((object, i) => | ||||||
|  |                         <View> | ||||||
|  |                             {object.name !== "" ? | ||||||
|  |                                 <Text style={{ | ||||||
|  |                                     marginTop: 5, | ||||||
|  |                                     marginBottom: 5 | ||||||
|  |                                 }}>{object.name.toLowerCase()}</Text> | ||||||
|  |                                 : <View/>} | ||||||
|  |                         </View>)} | ||||||
|  |                 </CardItem> | ||||||
|  |             </Card> | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -151,5 +151,30 @@ | ||||||
|   "general": { |   "general": { | ||||||
|     "loading": "Loading...", |     "loading": "Loading...", | ||||||
|     "networkError": "Unable to contact servers. Make sure you are connected to Internet." |     "networkError": "Unable to contact servers. Make sure you are connected to Internet." | ||||||
|  |   }, | ||||||
|  |   "date": { | ||||||
|  |     "daysOfWeek": { | ||||||
|  |       "monday": "Monday", | ||||||
|  |       "tuesday": "Tuesday", | ||||||
|  |       "wednesday": "Wednesday", | ||||||
|  |       "thursday": "Thursday", | ||||||
|  |       "friday": "Friday", | ||||||
|  |       "saturday": "Saturday", | ||||||
|  |       "sunday": "Sunday" | ||||||
|  |     }, | ||||||
|  |     "monthsOfYear": { | ||||||
|  |       "january": "January", | ||||||
|  |       "february": "February", | ||||||
|  |       "march": "March", | ||||||
|  |       "april": "April", | ||||||
|  |       "may": "May", | ||||||
|  |       "june": "June", | ||||||
|  |       "july": "July", | ||||||
|  |       "august": "August", | ||||||
|  |       "september": "September", | ||||||
|  |       "october": "October", | ||||||
|  |       "november": "November", | ||||||
|  |       "december": "December" | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
|     "planning": "Planning", |     "planning": "Planning", | ||||||
|     "proxiwash": "Proxiwash", |     "proxiwash": "Proxiwash", | ||||||
|     "proximo": "Proximo", |     "proximo": "Proximo", | ||||||
|     "menuSelf": "Menu Ru", |     "menuSelf": "Menu du RU", | ||||||
|     "settings": "Paramètres", |     "settings": "Paramètres", | ||||||
|     "about": "À Propos", |     "about": "À Propos", | ||||||
|     "debug": "Debug" |     "debug": "Debug" | ||||||
|  | @ -153,5 +153,30 @@ | ||||||
|   "general": { |   "general": { | ||||||
|     "loading": "Chargement...", |     "loading": "Chargement...", | ||||||
|     "networkError": "Impossible de contacter les serveurs. Assurez vous d'être connecté à internet." |     "networkError": "Impossible de contacter les serveurs. Assurez vous d'être connecté à internet." | ||||||
|  |   }, | ||||||
|  |   "date": { | ||||||
|  |     "daysOfWeek": { | ||||||
|  |       "monday": "Lundi", | ||||||
|  |       "tuesday": "Mardi", | ||||||
|  |       "wednesday": "Mercredi", | ||||||
|  |       "thursday": "Jeudi", | ||||||
|  |       "friday": "Vendredi", | ||||||
|  |       "saturday": "Samedi", | ||||||
|  |       "sunday": "Dimanche" | ||||||
|  |     }, | ||||||
|  |     "monthsOfYear": { | ||||||
|  |       "january": "Janvier", | ||||||
|  |       "february": "Février", | ||||||
|  |       "march": "Mars", | ||||||
|  |       "april": "Avril", | ||||||
|  |       "may": "Mai", | ||||||
|  |       "june": "Juin", | ||||||
|  |       "july": "Juillet", | ||||||
|  |       "august": "Août", | ||||||
|  |       "september": "Septembre", | ||||||
|  |       "october": "Octobre", | ||||||
|  |       "november": "Novembre", | ||||||
|  |       "december": "Décembre" | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue