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