Merge branch 'dev'

This commit is contained in:
keplyx 2020-02-01 21:46:53 +01:00
commit 5939319df2
39 changed files with 676 additions and 457 deletions

4
App.js
View file

@ -69,7 +69,7 @@ export default class App extends React.Component<Props, State> {
showUpdate: false,
});
AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.showIntro.key, '0');
AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.showUpdate4.key, '0');
AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.showUpdate5.key, '0');
}
async loadAssetsAsync() {
@ -93,7 +93,7 @@ export default class App extends React.Component<Props, State> {
isLoading: false,
currentTheme: ThemeManager.getCurrentTheme(),
showIntro: AsyncStorageManager.getInstance().preferences.showIntro.current === '1',
showUpdate: AsyncStorageManager.getInstance().preferences.showUpdate4.current === '1'
showUpdate: AsyncStorageManager.getInstance().preferences.showUpdate5.current === '1'
// showIntro: true
});
// Status bar goes dark if set too fast

View file

@ -1,3 +1,55 @@
# Changelog
Pas de version officielle.
Pensez à garder l'appli à jour pour profiter des dernières fonctionnalités !
- **v1.4.0** - _01/02/2020_
- Correction d'un crash lors du rafraichissement de planex
- Correction de bugs divers
- Ajout d'un accès rapide à BlueMind et l'ENT
- Amélioration de l'apparence du menu gauche
- Amélioration de l'affichage de Planex
- **v1.3.3** - _29/01/2020_
- Ajout d'une barre de recherche dans Proximo
- Amélioration de l'interface Proximo
- Ajout d'un accès rapide au site des Élus Étudiants
- Amélioration du mode plein écran de Planex
- Correction d'un problème de Planex mettant des cours sans couleur de fond
- _Notes de développement :_
- Yohan SIMARD rejoint le projet
- Passage de Expo SDK 33 à SDK 36
- Passage de React Native 59 à 61
- Mise à jour d'autres librairies
- **v1.3.0** - _08/11/2019_
- Ajout du support du mode paysage dans l'écran Planex pour une vue de la semaine entière
- Ajout d'une page pour visualiser les salles en libre accès et réserver une Bib'Box
- Ajout de Tutor'INSA sur la dashboard pour un accès rapide
- Ouverture des sites web dans l'appli a la place d'utiliser le navigateur externe
- Correction de quelques bugs
- **v1.2.0** - _01/11/2019_
- Ajout d'une dashboard sur la page d'accueil pour un accès rapide aux informations les plus importantes.
- Corrections de bugs
- **v1.1.1** - _28/09/2019_
- Amélioration de la page Menu du RU
- Suppression de l'affichage des articles en rupture de stock dans la page Proximo
- Ajout de fonctionnalités de debug
- **v1.1.0** - _17/09/2019_
- Améliorations diverses de l'interface
- Ajout de l'écran planning des événements
- **v1.0.3** - _13/09/2019_
- Correction d'un crash sur l'écran du Proximo si l'utilisateur refuse les notifications
- Ajout de la possibilité de choisir un écran de démarrage
- **v1.0.2** - _12/09/2019_
- Amélioration de l'interface du Proximo
- Ajout de la possibilité de cliquer sur un article du Proximo pour afficher plus de détails
- **v1.0.0** - _27/08/2019_
- Première version officielle créée par Arnaud VERGNET

View file

@ -10,7 +10,7 @@
"android",
"web"
],
"version": "1.3.3",
"version": "1.4.0",
"orientation": "portrait",
"primaryColor": "#be1522",
"icon": "./assets/android.icon.png",
@ -36,7 +36,7 @@
},
"android": {
"package": "fr.amicaleinsat.application",
"versionCode": 11,
"versionCode": 12,
"icon": "./assets/android.icon.png",
"adaptiveIcon": {
"foregroundImage": "./assets/android.adaptive-icon.png",

View file

@ -5,7 +5,7 @@ import {Container} from "native-base";
import CustomHeader from "./CustomHeader";
import CustomSideMenu from "./CustomSideMenu";
import CustomMaterialIcon from "./CustomMaterialIcon";
import {Platform, View} from "react-native";
import {Platform, StatusBar, View} from "react-native";
import ThemeManager from "../utils/ThemeManager";
import Touchable from "react-native-platform-touchable";
import {ScreenOrientation} from "expo";
@ -32,9 +32,6 @@ type State = {
export default class BaseContainer extends React.Component<Props, State> {
willBlurSubscription: function;
willFocusSubscription: function;
static defaultProps = {
headerRightButton: <View/>,
hasTabs: false,
@ -43,8 +40,8 @@ export default class BaseContainer extends React.Component<Props, State> {
enableRotation: false,
hideHeaderOnLandscape: false,
};
willBlurSubscription: function;
willFocusSubscription: function;
state = {
isOpen: false,
isHeaderVisible: true,
@ -66,7 +63,7 @@ export default class BaseContainer extends React.Component<Props, State> {
componentDidMount() {
this.willFocusSubscription = this.props.navigation.addListener(
'willFocus',
payload => {
() => {
if (this.props.enableRotation) {
ScreenOrientation.unlockAsync();
ScreenOrientation.addOrientationChangeListener((OrientationChangeEvent) => {
@ -80,13 +77,14 @@ export default class BaseContainer extends React.Component<Props, State> {
key: this.props.navigation.state.key,
});
this.props.navigation.dispatch(setParamsAction);
StatusBar.setHidden(isLandscape);
}
});
}
});
this.willBlurSubscription = this.props.navigation.addListener(
'willBlur',
payload => {
() => {
if (this.props.enableRotation)
ScreenOrientation.lockAsync(ScreenOrientation.Orientation.PORTRAIT);
this.setState({isOpen: false});
@ -122,7 +120,7 @@ export default class BaseContainer extends React.Component<Props, State> {
rightButton={this.props.headerRightButton}
hasTabs={this.props.hasTabs}
hasBackButton={this.props.hasBackButton}/>
: <View style={{paddingTop: 20}}/>}
: <View/>}
{this.props.children}
</Container>
);

View file

@ -1,7 +1,7 @@
// @flow
import * as React from "react";
import {Body, Header, Input, Item, Left, Right, Title, Form} from "native-base";
import {Body, Header, Input, Item, Left, Right, Title} from "native-base";
import {Platform, StyleSheet, View} from "react-native";
import {getStatusBarHeight} from "react-native-status-bar-height";
import Touchable from 'react-native-platform-touchable';
@ -93,19 +93,12 @@ export default class CustomHeader extends React.Component<Props> {
{this.props.hasSearchField ?
this.getSearchBar() :
<Title style={{
paddingLeft: 10
paddingLeft: 10,
color: ThemeManager.getCurrentThemeVariables().toolbarTextColor
}}>{this.props.title}</Title>}
</Body>
<Right style={{flex: this.props.hasSearchField ? 0 : 1}}>
{this.props.rightButton}
{this.props.hasBackButton ? <View/> :
<Touchable
style={{padding: 6}}
onPress={() => this.props.navigation.navigate('SettingsScreen')}>
<CustomMaterialIcon
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
icon="settings"/>
</Touchable>}
</Right>
</Header>);
}

View file

@ -105,7 +105,7 @@ export default class CustomIntroSlider extends React.Component<Props> {
key: '1',
title: i18n.t('intro.updateSlide.title'),
text: i18n.t('intro.updateSlide.text'),
icon: 'school',
icon: 'email',
colors: ['#e01928', '#be1522'],
},
]

View file

@ -101,7 +101,11 @@ export default class DashboardItem extends React.Component<Props> {
div: {color: ThemeManager.getCurrentThemeVariables().textColor},
}}/>
<LinearGradient
colors={['rgba(255,255,255,0)', ThemeManager.getCurrentThemeVariables().cardDefaultBg]}
colors={[
// Fix for ios gradient: transparent color must match final color
ThemeManager.getNightMode() ? 'rgba(42,42,42,0)' : 'rgba(255,255,255,0)',
ThemeManager.getCurrentThemeVariables().cardDefaultBg
]}
start={{x: 0, y: 0}}
end={{x: 0, y: 0.6}}
// end={[0, 0.6]}

View file

@ -35,13 +35,6 @@ export default class FetchedDataSectionList extends React.Component<Props, State
lastRefresh: Date;
minTimeBetweenRefresh = 60;
constructor(fetchUrl: string, refreshTime: number) {
super();
this.webDataManager = new WebDataManager(fetchUrl);
this.refreshTime = refreshTime;
}
state = {
refreshing: false,
firstLoading: true,
@ -49,6 +42,12 @@ export default class FetchedDataSectionList extends React.Component<Props, State
machinesWatched: [],
};
constructor(fetchUrl: string, refreshTime: number) {
super();
this.webDataManager = new WebDataManager(fetchUrl);
this.refreshTime = refreshTime;
}
/**
* Get the translation for the header in the current language
* @return {string}
@ -76,13 +75,13 @@ export default class FetchedDataSectionList extends React.Component<Props, State
componentDidMount() {
this.willFocusSubscription = this.props.navigation.addListener(
'willFocus',
payload => {
() => {
this.onScreenFocus();
}
);
this.willBlurSubscription = this.props.navigation.addListener(
'willBlur',
payload => {
() => {
this.onScreenBlur();
}
);
@ -136,7 +135,7 @@ export default class FetchedDataSectionList extends React.Component<Props, State
});
this.lastRefresh = new Date();
})
.catch((err) => {
.catch(() => {
this.setState({
fetchedData: {},
refreshing: false,

View file

@ -2,12 +2,11 @@
import * as React from 'react';
import {Dimensions, FlatList, Image, Linking, Platform, StyleSheet} from 'react-native';
import {Badge, Container, Content, Left, ListItem, Right, Text} from "native-base";
import {Badge, Container, Left, ListItem, Right, Text} from "native-base";
import i18n from "i18n-js";
import CustomMaterialIcon from '../components/CustomMaterialIcon';
import ThemeManager from "../utils/ThemeManager";
const deviceHeight = Dimensions.get("window").height;
const deviceWidth = Dimensions.get("window").width;
const drawerCover = require("../assets/drawer-cover.png");
@ -41,10 +40,14 @@ export default class SideBar extends React.Component<Props, State> {
// Dataset used to render the drawer
// If the link field is defined, clicking on the item will open the link
this.dataSet = [
{
name: i18n.t('sidenav.divider1'),
route: "Divider1"
},
{
name: "Amicale",
route: "AmicaleScreen",
icon: "web",
icon: "alpha-a-box",
},
{
name: "Élus Étudiants",
@ -61,6 +64,20 @@ export default class SideBar extends React.Component<Props, State> {
route: "TutorInsaScreen",
icon: "school",
},
{
name: i18n.t('sidenav.divider2'),
route: "Divider2"
},
{
name: i18n.t('screens.bluemind'),
route: "BlueMindScreen",
icon: "email",
},
{
name: i18n.t('screens.ent'),
route: "EntScreen",
icon: "notebook",
},
{
name: i18n.t('screens.availableRooms'),
route: "AvailableRoomScreen",
@ -71,28 +88,26 @@ export default class SideBar extends React.Component<Props, State> {
route: "SelfMenuScreen",
icon: "silverware-fork-knife",
},
{
name: i18n.t('sidenav.divider3'),
route: "Divider3"
},
{
name: i18n.t('screens.settings'),
route: "SettingsScreen",
icon: "settings",
},
{
name: i18n.t('screens.about'),
route: "AboutScreen",
icon: "information",
},
];
}
/**
* Navigate to the selected route
* @param route {string} The route name to navigate to
*/
navigateToScreen(route: string) {
this.props.navigation.navigate(route);
};
render() {
getRenderItem(item: Object) {
if (item.icon !== undefined) {
return (
<Container style={{
backgroundColor: ThemeManager.getCurrentThemeVariables().sideMenuBgColor,
}}>
<Image source={drawerCover} style={styles.drawerCover}/>
<FlatList
data={this.dataSet}
extraData={this.state}
keyExtractor={(item) => item.route}
renderItem={({item}) =>
<ListItem
button
noBorder
@ -128,7 +143,37 @@ export default class SideBar extends React.Component<Props, State> {
>{`${item.types} Types`}</Text>
</Badge>
</Right>}
</ListItem>}
</ListItem>
);
} else {
return (
<ListItem itemDivider>
<Text>{item.name}</Text>
</ListItem>
);
}
}
/**
* Navigate to the selected route
* @param route {string} The route name to navigate to
*/
navigateToScreen(route: string) {
this.props.navigation.navigate(route);
};
render() {
return (
<Container style={{
backgroundColor: ThemeManager.getCurrentThemeVariables().sideMenuBgColor,
}}>
<Image source={drawerCover} style={styles.drawerCover}/>
<FlatList
data={this.dataSet}
extraData={this.state}
keyExtractor={(item) => item.route}
renderItem={({item}) => this.getRenderItem(item)}
/>
</Container>
);

View file

@ -2,13 +2,12 @@
import * as React from 'react';
import {Linking, Platform, View} from 'react-native';
import {Spinner, Footer, Right, Left, Body, Tab, TabHeading, Text, Tabs} from 'native-base';
import {Body, Footer, Left, Right, Spinner, Tab, TabHeading, Tabs, Text} 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 BaseContainer from "../components/BaseContainer";
import {NavigationActions} from 'react-navigation';
type Props = {
navigation: Object,
@ -62,18 +61,21 @@ export default class WebViewScreen extends React.Component<Props> {
refreshWebview() {
for (let view of this.webviewArray) {
if (view !== null)
view.reload();
}
}
goBackWebview() {
for (let view of this.webviewArray) {
if (view !== null)
view.goBack();
}
}
goForwardWebview() {
for (let view of this.webviewArray) {
if (view !== null)
view.goForward();
}
}
@ -132,6 +134,7 @@ export default class WebViewScreen extends React.Component<Props> {
render() {
const nav = this.props.navigation;
this.webviewArray = [];
return (
<BaseContainer
navigation={nav}
@ -140,7 +143,8 @@ export default class WebViewScreen extends React.Component<Props> {
hasBackButton={this.props.hasHeaderBackButton}
hasSideMenu={this.props.hasSideMenu}
enableRotation={true}
hideHeaderOnLandscape={true}>
hideHeaderOnLandscape={true}
hasTabs={this.props.data.length > 1}>
{this.props.data.length === 1 ?
this.getWebview(this.props.data[0]) :
<Tabs

View file

@ -210,6 +210,7 @@ export default {
toolbarBtnTextColor: platform === PLATFORM.IOS ? '#be1522' : '#fff',
toolbarDefaultBorder: platform === PLATFORM.IOS ? '#a7a6ab' : '#be1522',
iosStatusbar: platform === PLATFORM.IOS ? 'dark-content' : 'light-content',
toolbarTextColor: platform === PLATFORM.IOS ? '#000000' : '#ffffff',
get statusBarColor() {
return color(this.toolbarDefaultBg)
.darken(0.2)
@ -250,7 +251,7 @@ export default {
// List
listBg: 'transparent',
listBorderColor: '#c9c9c9',
listDividerBg: '#f4f4f4',
listDividerBg: '#e2e2e2',
listBtnUnderlayColor: '#DDD',
listItemPadding: platform === PLATFORM.IOS ? 10 : 12,
listNoteColor: '#808080',

View file

@ -210,6 +210,7 @@ export default {
toolbarBtnTextColor: platform === PLATFORM.IOS ? '#be1522' : '#fff',
toolbarDefaultBorder: platform === PLATFORM.IOS ? '#3f3f3f' : '#be1522',
iosStatusbar: platform === PLATFORM.IOS ? 'dark-content' : 'light-content',
toolbarTextColor: '#ffffff',
get statusBarColor() {
return color(this.toolbarDefaultBg)
.darken(0.2)
@ -250,7 +251,7 @@ export default {
// List
listBg: 'transparent',
listBorderColor: '#3e3e3e',
listDividerBg: '#f4f4f4',
listDividerBg: '#222222',
listBtnUnderlayColor: '#3a3a3a',
listItemPadding: platform === PLATFORM.IOS ? 10 : 12,
listNoteColor: '#acacac',

View file

@ -9,11 +9,13 @@ import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen';
import ProxiwashAboutScreen from '../screens/Proxiwash/ProxiwashAboutScreen';
import ProximoAboutScreen from '../screens/Proximo/ProximoAboutScreen';
import SelfMenuScreen from '../screens/SelfMenuScreen';
import TutorInsaScreen from "../screens/TutorInsaScreen";
import AmicaleScreen from "../screens/AmicaleScreen";
import WiketudScreen from "../screens/WiketudScreen";
import ElusEtudScreen from "../screens/ElusEtudScreen";
import AvailableRoomScreen from "../screens/AvailableRoomScreen";
import TutorInsaScreen from "../screens/Websites/TutorInsaScreen";
import AmicaleScreen from "../screens/Websites/AmicaleScreen";
import WiketudScreen from "../screens/Websites/WiketudScreen";
import ElusEtudScreen from "../screens/Websites/ElusEtudScreen";
import BlueMindScreen from "../screens/Websites/BlueMindScreen";
import EntScreen from "../screens/Websites/EntScreen";
import AvailableRoomScreen from "../screens/Websites/AvailableRoomScreen";
import DebugScreen from '../screens/DebugScreen';
import {fromRight} from "react-navigation-transitions";
@ -35,6 +37,8 @@ function createAppContainerWithInitialRoute(initialRoute: string) {
AmicaleScreen: {screen: AmicaleScreen},
WiketudScreen: {screen: WiketudScreen},
ElusEtudScreen: {screen: ElusEtudScreen},
BlueMindScreen: {screen: BlueMindScreen},
EntScreen: {screen: EntScreen},
AvailableRoomScreen: {screen: AvailableRoomScreen},
ProxiwashAboutScreen: {screen: ProxiwashAboutScreen},
ProximoAboutScreen: {screen: ProximoAboutScreen},
@ -48,4 +52,5 @@ function createAppContainerWithInitialRoute(initialRoute: string) {
})
);
}
export {createAppContainerWithInitialRoute};

View file

@ -1,34 +0,0 @@
// @flow
import * as React from 'react';
import {createDrawerNavigator} from 'react-navigation';
import HomeScreen from '../screens/HomeScreen';
import PlanningScreen from '../screens/PlanningScreen';
import ProxiwashScreen from '../screens/Proxiwash/ProxiwashScreen';
import ProximoMainScreen from '../screens/Proximo/ProximoMainScreen';
import PlanexScreen from '../screens/PlanexScreen';
import SettingsScreen from '../screens/SettingsScreen';
import AboutScreen from '../screens/About/AboutScreen';
import Sidebar from "../components/Sidebar";
/**
* Creates the drawer navigation stack
*/
export default createDrawerNavigator({
Home: {screen: HomeScreen},
Planning: {screen: PlanningScreen,},
Proxiwash: {screen: ProxiwashScreen,},
Proximo: {screen: ProximoMainScreen,},
Planex: {screen: PlanexScreen},
Settings: {screen: SettingsScreen,},
About: {screen: AboutScreen,},
}, {
contentComponent: Sidebar,
initialRouteName: 'Home',
backBehavior: 'initialRoute',
drawerType: 'front',
useNativeAnimations: true,
}
);

View file

@ -5,10 +5,9 @@ import HomeScreen from '../screens/HomeScreen';
import PlanningScreen from '../screens/PlanningScreen';
import ProxiwashScreen from '../screens/Proxiwash/ProxiwashScreen';
import ProximoMainScreen from '../screens/Proximo/ProximoMainScreen';
import PlanexScreen from '../screens/PlanexScreen';
import PlanexScreen from '../screens/Websites/PlanexScreen';
import CustomMaterialIcon from "../components/CustomMaterialIcon";
import ThemeManager from "../utils/ThemeManager";
import AsyncStorageManager from "../utils/AsyncStorageManager";
const TAB_ICONS = {
Home: 'triangle',

View file

@ -8,8 +8,6 @@
"eject": "expo eject"
},
"dependencies": {
"@expo/vector-icons": "^10.0.0",
"@react-native-community/status-bar": "^1.0.3",
"expo": "^36.0.0",
"expo-font": "~8.0.0",
"expo-linear-gradient": "~8.0.0",
@ -27,8 +25,10 @@
"react-native-gesture-handler": "~1.5.0",
"react-native-material-menu": "^0.6.7",
"react-native-modalize": "^1.3.6",
"react-native-paper": "^3.5.1",
"react-native-platform-touchable": "^1.1.1",
"react-native-render-html": "^4.1.2",
"react-native-screens": "2.0.0-alpha.12",
"react-native-side-menu": "^1.1.3",
"react-native-status-bar-height": "^2.3.1",
"react-native-webview": "7.4.3",

View file

@ -1,7 +1,7 @@
// @flow
import * as React from 'react';
import {Body, Container, Content, ListItem, Text} from 'native-base';
import {Body, Container, ListItem, Text} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import {FlatList} from "react-native";
import i18n from "i18n-js";
@ -31,7 +31,6 @@ export default class AboutDependenciesScreen extends React.Component<Props> {
return (
<Container>
<CustomHeader hasBackButton={true} navigation={nav} title={i18n.t('aboutScreen.libs')}/>
<Content>
<FlatList
data={data}
keyExtractor={(item) => item.name}
@ -48,7 +47,6 @@ export default class AboutDependenciesScreen extends React.Component<Props> {
</Body>
</ListItem>}
/>
</Content>
</Container>
);
}

View file

@ -2,7 +2,7 @@
import * as React from 'react';
import {FlatList, Linking, Platform, View} from 'react-native';
import {Body, Card, CardItem, Container, Content, H1, Left, Right, Text, Thumbnail, Button} from 'native-base';
import {Body, Button, Card, CardItem, Container, H1, Left, Right, Text, Thumbnail} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import i18n from "i18n-js";
import appJson from '../../app';
@ -39,7 +39,7 @@ const links = {
"Application Amicale INSA Toulouse" +
"&body=" +
"Coucou !\n\n",
yohanLinkedin: 'https://www.linkedin.com/in/yohan-simard', // TODO set real link
yohanLinkedin: 'https://www.linkedin.com/in/yohan-simard',
react: 'https://facebook.github.io/react-native/',
};
@ -70,12 +70,6 @@ export default class AboutScreen extends React.Component<Props, State> {
state = {
isDebugUnlocked: AsyncStorageManager.getInstance().preferences.debugUnlocked.current === '1'
};
constructor(props: any) {
super(props);
this.modalRef = React.createRef();
}
/**
* Data to be displayed in the app card
*/
@ -118,7 +112,6 @@ export default class AboutScreen extends React.Component<Props, State> {
showOnlyDebug: true
},
];
/**
* Data to be displayed in the author card
*/
@ -142,7 +135,6 @@ export default class AboutScreen extends React.Component<Props, State> {
showChevron: true
},
];
/**
* Data to be displayed in the additional developer card
*/
@ -166,7 +158,6 @@ export default class AboutScreen extends React.Component<Props, State> {
showChevron: true
},
];
/**
* Data to be displayed in the technologies card
*/
@ -184,6 +175,111 @@ export default class AboutScreen extends React.Component<Props, State> {
showChevron: true
},
];
dataOrder: Array<Object> = [
{
id: 'app',
},
{
id: 'team',
},
{
id: 'techno',
},
];
constructor(props: any) {
super(props);
this.modalRef = React.createRef();
}
getAppCard() {
return (
<Card>
<CardItem>
<Left>
<Thumbnail square source={require('../../assets/icon.png')}/>
<Body>
<H1>{appJson.expo.name}</H1>
<Text note>
v.{appJson.expo.version}
</Text>
</Body>
</Left>
</CardItem>
<FlatList
data={this.appData}
extraData={this.state}
keyExtractor={(item) => item.icon}
listKey={(item) => "app"}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
}
/>
</Card>
);
}
getTeamCard() {
return (
<Card>
<CardItem>
<Left>
<CustomMaterialIcon
icon={'account-multiple'}
fontSize={40}
width={40}
color={ThemeManager.getCurrentThemeVariables().brandPrimary}/>
<Body>
<H1>{i18n.t('aboutScreen.team')}</H1>
</Body>
</Left>
</CardItem>
<CardItem header>
<Text>{i18n.t('aboutScreen.author')}</Text>
</CardItem>
<FlatList
data={this.authorData}
extraData={this.state}
keyExtractor={(item) => item.icon}
listKey={(item) => "team1"}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
}
/>
<CardItem header>
<Text>{i18n.t('aboutScreen.additionalDev')}</Text>
</CardItem>
<FlatList
data={this.additionalDevData}
extraData={this.state}
keyExtractor={(item) => item.icon}
listKey={(item) => "team2"}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
}
/>
</Card>
);
}
getTechnoCard() {
return (
<Card>
<CardItem header>
<Text>{i18n.t('aboutScreen.technologies')}</Text>
</CardItem>
<FlatList
data={this.technoData}
extraData={this.state}
keyExtractor={(item) => item.icon}
listKey={(item) => "techno"}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
}
/>
</Card>
);
}
/**
* Get a clickable card item to be rendered inside a card.
@ -284,86 +380,33 @@ export default class AboutScreen extends React.Component<Props, State> {
}
}
getMainCard(item: Object) {
switch (item.id) {
case 'app':
return this.getAppCard();
case 'team':
return this.getTeamCard();
case 'techno':
return this.getTechnoCard();
}
return <View/>;
}
render() {
const nav = this.props.navigation;
return (
<Container>
{this.getBugReportModal()}
<CustomHeader navigation={nav} title={i18n.t('screens.about')} hasBackButton={true}/>
<Content padder>
<Card>
<CardItem>
<Left>
<Thumbnail square source={require('../../assets/icon.png')}/>
<Body>
<H1>{appJson.expo.name}</H1>
<Text note>
v.{appJson.expo.version}
</Text>
</Body>
</Left>
</CardItem>
<FlatList
data={this.appData}
style={{padding: 5}}
data={this.dataOrder}
extraData={this.state}
keyExtractor={(item) => item.icon}
keyExtractor={(item) => item.id}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
this.getMainCard(item)
}
/>
</Card>
<Card>
<CardItem>
<Left>
<CustomMaterialIcon
icon={'account-multiple'}
fontSize={40}
width={40}
color={ThemeManager.getCurrentThemeVariables().brandPrimary}/>
<Body>
<H1>{i18n.t('aboutScreen.team')}</H1>
</Body>
</Left>
</CardItem>
<CardItem header>
<Text>{i18n.t('aboutScreen.author')}</Text>
</CardItem>
<FlatList
data={this.authorData}
extraData={this.state}
keyExtractor={(item) => item.icon}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
}
/>
<CardItem header>
<Text>{i18n.t('aboutScreen.additionalDev')}</Text>
</CardItem>
<FlatList
data={this.additionalDevData}
extraData={this.state}
keyExtractor={(item) => item.icon}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
}
/>
</Card>
<Card>
<CardItem header>
<Text>{i18n.t('aboutScreen.technologies')}</Text>
</CardItem>
<FlatList
data={this.technoData}
extraData={this.state}
keyExtractor={(item) => item.icon}
renderItem={({item}) =>
this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug)
}
/>
</Card>
</Content>
</Container>
);
}

View file

@ -3,29 +3,28 @@
import * as React from 'react';
import {
Body,
Button,
Card,
CardItem,
Container,
Content,
Form,
H1,
H3,
Input,
Item,
Label,
Left,
List,
ListItem,
Right,
Text,
Form,
Item,
Label,
Input,
Button
Text
} from "native-base";
import CustomHeader from "../components/CustomHeader";
import ThemeManager from '../utils/ThemeManager';
import i18n from "i18n-js";
import CustomMaterialIcon from "../components/CustomMaterialIcon";
import Touchable from "react-native-platform-touchable";
import {Alert, View, Clipboard, Image} from "react-native";
import {Alert, Clipboard, View} from "react-native";
import AsyncStorageManager from "../utils/AsyncStorageManager";
import NotificationsManager from "../utils/NotificationsManager";
import {Modalize} from "react-native-modalize";
@ -46,36 +45,16 @@ export default class DebugScreen extends React.Component<Props, State> {
modalRef: { current: null | Modalize };
modalInputValue = '';
constructor(props: any) {
super(props);
this.modalRef = React.createRef();
}
state = {
modalCurrentDisplayItem: {},
currentPreferences: JSON.parse(JSON.stringify(AsyncStorageManager.getInstance().preferences))
};
alertCurrentExpoToken() {
let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
console.log(token);
Alert.alert(
'Expo Token',
token,
[
{text: 'Copy', onPress: () => Clipboard.setString(token)},
{text: 'OK'}
]
);
constructor(props: any) {
super(props);
this.modalRef = React.createRef();
}
async forceExpoTokenUpdate() {
await NotificationsManager.forceExpoTokenUpdate();
this.alertCurrentExpoToken();
}
static getGeneralItem(onPressCallback: Function, icon: ?string, title: string, subtitle: string) {
return (
<ListItem
@ -102,6 +81,24 @@ export default class DebugScreen extends React.Component<Props, State> {
);
}
alertCurrentExpoToken() {
let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
console.log(token);
Alert.alert(
'Expo Token',
token,
[
{text: 'Copy', onPress: () => Clipboard.setString(token)},
{text: 'OK'}
]
);
}
async forceExpoTokenUpdate() {
await NotificationsManager.forceExpoTokenUpdate();
this.alertCurrentExpoToken();
}
showEditModal(item: Object) {
this.setState({
modalCurrentDisplayItem: item

View file

@ -2,7 +2,7 @@
import * as React from 'react';
import {Image, Linking, TouchableOpacity, View} from 'react-native';
import {Body, Button, Card, CardItem, Left, Text, Thumbnail, H1, H3} from 'native-base';
import {Body, Button, Card, CardItem, H1, Left, Text, Thumbnail} from 'native-base';
import i18n from "i18n-js";
import CustomMaterialIcon from '../components/CustomMaterialIcon';
import FetchedDataSectionList from "../components/FetchedDataSectionList";
@ -42,6 +42,16 @@ export default class HomeScreen extends FetchedDataSectionList {
super(DATA_URL, REFRESH_TIME);
}
/**
* Converts a dateString using Unix Timestamp to a formatted date
* @param dateString {string} The Unix Timestamp representation of a date
* @return {string} The formatted output date
*/
static getFormattedDate(dateString: string) {
let date = new Date(Number.parseInt(dateString) * 1000);
return date.toLocaleString();
}
getHeaderTranslation() {
return i18n.t("screens.home");
}
@ -119,17 +129,6 @@ export default class HomeScreen extends FetchedDataSectionList {
return dataset
}
/**
* Converts a dateString using Unix Timestamp to a formatted date
* @param dateString {string} The Unix Timestamp representation of a date
* @return {string} The formatted output date
*/
static getFormattedDate(dateString: string) {
let date = new Date(Number.parseInt(dateString) * 1000);
return date.toLocaleString();
}
getRenderSectionHeader(title: string) {
if (title === '') {
return <View/>;
@ -294,7 +293,7 @@ export default class HomeScreen extends FetchedDataSectionList {
let icon = 'calendar-range';
let color = ThemeManager.getCurrentThemeVariables().planningColor;
let title = i18n.t('homeScreen.dashboard.todayEventsTitle');
let subtitle = '';
let subtitle;
let futureEvents = this.getFutureEvents(content);
let isAvailable = futureEvents.length > 0;
if (isAvailable) {
@ -336,7 +335,7 @@ export default class HomeScreen extends FetchedDataSectionList {
let proximoColor = ThemeManager.getCurrentThemeVariables().proximoColor;
let proximoTitle = i18n.t('homeScreen.dashboard.proximoTitle');
let isProximoAvailable = parseInt(proximoData) > 0;
let proximoSubtitle = '';
let proximoSubtitle;
if (isProximoAvailable) {
proximoSubtitle =
<Text>
@ -358,7 +357,7 @@ export default class HomeScreen extends FetchedDataSectionList {
let menuColor = ThemeManager.getCurrentThemeVariables().menuColor;
let menuTitle = i18n.t('homeScreen.dashboard.menuTitle');
let isMenuAvailable = menuData.length > 0;
let menuSubtitle = '';
let menuSubtitle;
if (isMenuAvailable) {
menuSubtitle = i18n.t('homeScreen.dashboard.menuSubtitle');
} else
@ -497,10 +496,8 @@ export default class HomeScreen extends FetchedDataSectionList {
getRenderItem(item: Object, section: Object, data: Object) {
if (section['id'] === SECTIONS_ID[0]) {
return this.getDashboardItem(item);
} else {
return (
section['id'] === SECTIONS_ID[0] ? this.getDashboardItem(item) :
<Card style={{
flex: 0,
marginLeft: 10,
@ -558,5 +555,3 @@ export default class HomeScreen extends FetchedDataSectionList {
);
}
}
}

View file

@ -1,10 +1,9 @@
// @flow
import * as React from 'react';
import {BackHandler} from 'react-native';
import {Content, H1, H3, Text, Button} from 'native-base';
import {BackHandler, Image, View} from 'react-native';
import {Button, Content, H1, H3, Text} from 'native-base';
import i18n from "i18n-js";
import {View, Image} from "react-native";
import ThemeManager from "../utils/ThemeManager";
import {Linking} from "expo";
import BaseContainer from "../components/BaseContainer";
@ -61,6 +60,12 @@ export default class PlanningScreen extends React.Component<Props, State> {
didFocusSubscription: Function;
willBlurSubscription: Function;
state = {
modalCurrentDisplayItem: {},
refreshing: false,
agendaItems: {},
calendarShowing: false,
};
constructor(props: any) {
super(props);
@ -68,7 +73,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
this.webDataManager = new WebDataManager(FETCH_URL);
this.didFocusSubscription = props.navigation.addListener(
'didFocus',
payload =>
() =>
BackHandler.addEventListener(
'hardwareBackPress',
this.onBackButtonPressAndroid
@ -83,7 +88,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
this._onRefresh();
this.willBlurSubscription = this.props.navigation.addListener(
'willBlur',
payload =>
() =>
BackHandler.removeEventListener(
'hardwareBackPress',
this.onBackButtonPressAndroid
@ -105,13 +110,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
this.willBlurSubscription && this.willBlurSubscription.remove();
}
state = {
modalCurrentDisplayItem: {},
refreshing: false,
agendaItems: {},
calendarShowing: false,
};
getCurrentDate() {
let today = new Date();
return this.getFormattedDate(today);
@ -351,7 +349,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
getFormattedTime(event: Object) {
if (this.getEventEndTime(event) !== "")
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event)
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event);
else
return this.getEventStartTime(event);
}

View file

@ -2,7 +2,7 @@
import * as React from 'react';
import {Image, Linking, View} from 'react-native';
import {Body, Card, CardItem, Container, Content, H2, Left, Text} from 'native-base';
import {Card, CardItem, Container, Content, H2, Left, Text} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import i18n from "i18n-js";
import CustomMaterialIcon from "../../components/CustomMaterialIcon";
@ -11,14 +11,6 @@ type Props = {
navigation: Object,
};
/**
* Opens a link in the device's browser
* @param link The link to open
*/
function openWebLink(link) {
Linking.openURL(link).catch((err) => console.error('Error opening link', err));
}
/**
* Class defining an about screen. This screen shows the user information about the app and it's author.
*/

View file

@ -1,9 +1,9 @@
// @flow
import * as React from 'react';
import {Body, Container, Content, Left, ListItem, Right, Text, Thumbnail, H1, H3} from 'native-base';
import {Body, Container, Content, H1, H3, Left, ListItem, Right, Text, Thumbnail} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import {FlatList, Platform, View, Image} from "react-native";
import {FlatList, Image, Platform, View} from "react-native";
import Touchable from 'react-native-platform-touchable';
import Menu, {MenuItem} from 'react-native-material-menu';
import i18n from "i18n-js";
@ -62,13 +62,6 @@ export default class ProximoListScreen extends React.Component<Props, State> {
originalData: Array<Object>;
navData = this.props.navigation.getParam('data', []);
shouldFocusSearchBar = this.props.navigation.getParam('shouldFocusSearchBar', false);
constructor(props: any) {
super(props);
this.modalRef = React.createRef();
this.originalData = this.navData['data'];
}
state = {
currentlyDisplayedData: this.navData['data'].sort(sortPrice),
currentSortMode: sortMode.price,
@ -77,9 +70,14 @@ export default class ProximoListScreen extends React.Component<Props, State> {
sortNameIcon: '',
modalCurrentDisplayItem: {},
};
_menu: Menu;
constructor(props: any) {
super(props);
this.modalRef = React.createRef();
this.originalData = this.navData['data'];
}
/**
* Saves the reference to the sort menu for later use
*
@ -132,9 +130,6 @@ export default class ProximoListScreen extends React.Component<Props, State> {
}
break;
}
this.setState({
navData: data,
});
this.setupSortIcons(mode, isReverse);
this._menu.hide();
}
@ -297,7 +292,6 @@ export default class ProximoListScreen extends React.Component<Props, State> {
render() {
const nav = this.props.navigation;
const navType = nav.getParam('type', '{name: "Error"}');
return (
<Container>
<Modalize ref={this.modalRef}

View file

@ -2,7 +2,7 @@
import * as React from 'react';
import {Platform, View} from 'react-native'
import {Badge, Body, Left, ListItem, Right, Text} from 'native-base';
import {Body, Left, ListItem, Right, Text} from 'native-base';
import i18n from "i18n-js";
import CustomMaterialIcon from "../../components/CustomMaterialIcon";
import FetchedDataSectionList from "../../components/FetchedDataSectionList";
@ -22,6 +22,10 @@ export default class ProximoMainScreen extends FetchedDataSectionList {
super(DATA_URL, 0);
}
static sortFinalData(a: Object, b: Object) {
return a.type.id - b.type.id;
}
getHeaderTranslation() {
return i18n.t("screens.proximo");
}
@ -96,10 +100,6 @@ export default class ProximoMainScreen extends FetchedDataSectionList {
return availableArticles;
}
static sortFinalData(a: Object, b: Object) {
return a.type.id - b.type.id;
}
getRightButton() {
let searchScreenData = {
shouldFocusSearchBar: true,

View file

@ -1,7 +1,7 @@
// @flow
import * as React from 'react';
import {Image, Linking, View} from 'react-native';
import {Image, View} from 'react-native';
import {Body, Card, CardItem, Container, Content, H2, H3, Left, Tab, TabHeading, Tabs, Text} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import i18n from "i18n-js";
@ -12,14 +12,6 @@ type Props = {
navigation: Object,
};
/**
* Opens a link in the device's browser
* @param link The link to open
*/
function openWebLink(link) {
Linking.openURL(link).catch((err) => console.error('Error opening link', err));
}
/**
* Class defining an about screen. This screen shows the user information about the app and it's author.
*/

View file

@ -89,7 +89,7 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
this.setState({machinesWatched: fetchedList})
});
// Get updated watchlist after received notification
Expo.Notifications.addListener((notification) => {
Expo.Notifications.addListener(() => {
NotificationsManager.getMachineNotificationWatchlist((fetchedList) => {
this.setState({machinesWatched: fetchedList})
});

View file

@ -2,11 +2,10 @@
import * as React from 'react';
import {View} from 'react-native';
import {Text, H2, H3, Card, CardItem} from 'native-base';
import {Card, CardItem, H2, H3, Text} from 'native-base';
import ThemeManager from "../utils/ThemeManager";
import i18n from "i18n-js";
import FetchedDataSectionList from "../components/FetchedDataSectionList";
import LocaleManager from "../utils/LocaleManager";
const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json";
@ -150,7 +149,7 @@ export default class SelfMenuScreen extends FetchedDataSectionList {
flexDirection: 'column',
paddingTop: 0,
}}>
{item.dishes.map((object, i) =>
{item.dishes.map((object) =>
<View>
{object.name !== "" ?
<Text style={{

View file

@ -21,8 +21,6 @@ import i18n from "i18n-js";
import {NavigationActions, StackActions} from "react-navigation";
import CustomMaterialIcon from "../components/CustomMaterialIcon";
import AsyncStorageManager from "../utils/AsyncStorageManager";
import Touchable from "react-native-platform-touchable";
import {Platform} from "react-native";
import NotificationsManager from "../utils/NotificationsManager";
type Props = {
@ -45,6 +43,39 @@ export default class SettingsScreen extends React.Component<Props, State> {
startScreenPickerSelected: AsyncStorageManager.getInstance().preferences.defaultStartScreen.current,
};
/**
* Get a list item using the specified control
*
* @param control The custom control to use
* @param icon The icon name to display on the list item
* @param title The text to display as this list item title
* @param subtitle The text to display as this list item subtitle
* @returns {React.Node}
*/
static getGeneralItem(control: React.Node, icon: string, title: string, subtitle: string) {
return (
<ListItem
thumbnail
>
<Left>
<CustomMaterialIcon icon={icon}/>
</Left>
<Body>
<Text>
{title}
</Text>
<Text note>
{subtitle}
</Text>
</Body>
<Right>
{control}
</Right>
</ListItem>
);
}
/**
* Save the value for the proxiwash reminder notification time
*
@ -179,57 +210,11 @@ export default class SettingsScreen extends React.Component<Props, State> {
);
}
/**
* Get a list item using the specified control
*
* @param control The custom control to use
* @param icon The icon name to display on the list item
* @param title The text to display as this list item title
* @param subtitle The text to display as this list item subtitle
* @returns {React.Node}
*/
static getGeneralItem(control: React.Node, icon: string, title: string, subtitle: string) {
return (
<ListItem
thumbnail
>
<Left>
<CustomMaterialIcon icon={icon}/>
</Left>
<Body>
<Text>
{title}
</Text>
<Text note>
{subtitle}
</Text>
</Body>
<Right>
{control}
</Right>
</ListItem>
);
}
getRightButton() {
return (
<Touchable
style={{padding: 6}}
onPress={() => this.props.navigation.navigate('AboutScreen')}>
<CustomMaterialIcon
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
icon="information"/>
</Touchable>
);
}
render() {
const nav = this.props.navigation;
return (
<Container>
<CustomHeader navigation={nav} title={i18n.t('screens.settings')} hasBackButton={true}
rightButton={this.getRightButton()}/>
<CustomHeader navigation={nav} title={i18n.t('screens.settings')} hasBackButton={true}/>
<Content padder>
<Card>
<CardItem header>

View file

@ -1,8 +1,7 @@
// @flow
import * as React from 'react';
import ThemeManager from "../utils/ThemeManager";
import WebViewScreen from "../components/WebViewScreen";
import WebViewScreen from "../../components/WebViewScreen";
type Props = {
navigation: Object,

View file

@ -1,7 +1,7 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../components/WebViewScreen";
import WebViewScreen from "../../components/WebViewScreen";
import i18n from "i18n-js";
type Props = {

View file

@ -0,0 +1,52 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../components/WebViewScreen";
import i18n from "i18n-js";
type Props = {
navigation: Object,
}
const URL = 'https://etud-mel.insa-toulouse.fr/webmail/';
const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/bluemind/customMobile.css';
/**
* Class defining the app's planex screen.
* This screen uses a webview to render the planex page
*/
export default class BlueMindScreen extends React.Component<Props> {
customInjectedJS: string;
constructor() {
super();
// Breaks website on ios
this.customInjectedJS = '';
// '$("head").append(\'<meta name="viewport" content="width=device-width, initial-scale=1.0">\');' +
// '$("head").append(\'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\');true;';
}
render() {
const nav = this.props.navigation;
return (
<WebViewScreen
navigation={nav}
data={[
{
url: URL,
icon: '',
name: '',
customJS: this.customInjectedJS
},
]}
headerTitle={i18n.t('screens.bluemind')}
hasHeaderBackButton={true}
hasSideMenu={false}/>
);
}
}

View file

@ -1,8 +1,7 @@
// @flow
import * as React from 'react';
import ThemeManager from "../utils/ThemeManager";
import WebViewScreen from "../components/WebViewScreen";
import WebViewScreen from "../../components/WebViewScreen";
type Props = {
navigation: Object,

View file

@ -0,0 +1,90 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../components/WebViewScreen";
import i18n from "i18n-js";
type Props = {
navigation: Object,
}
const URL = 'https://ent.insa-toulouse.fr/';
const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/ent/customMobile.css';
// let stylesheet = document.createElement('link');
// stylesheet.type = 'text/css';
// stylesheet.rel = 'stylesheet';
// stylesheet.href = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/ent/customMobile.css';
// let mobileSpec = document.createElement('meta');
// mobileSpec.name = 'viewport';
// mobileSpec.content = 'width=device-width, initial-scale=1.0';
// document.getElementsByTagName('head')[0].appendChild(mobileSpec);
// // document.getElementsByTagName('head')[0].appendChild(stylesheet);
// document.getElementsByClassName('preference-items')[0].style.display = 'none';
// document.getElementsByClassName('logoInsa')[0].style.display = 'none';
// document.getElementsByClassName('logoPress')[0].style.display = 'none';
// document.getElementsByClassName('ent')[0].style.display = 'none';
// document.getElementById('portal-page-header').style.margin = 0;
// document.querySelectorAll('.uportal-navigation-category').forEach(element => {
// element.style.cssText = "width: 100%; display: flex; height: 50px;";
// if (element.children.length > 0)
// element.children[0].style.margin = 'auto';
// });
// true;
/**
* Class defining the app's ent screen.
* This screen uses a webview to render the ent page
*/
export default class EntScreen extends React.Component<Props> {
customInjectedJS: string;
constructor() {
super();
this.customInjectedJS =
'let stylesheet = document.createElement(\'link\');\n' +
'stylesheet.type = \'text/css\';\n' +
'stylesheet.rel = \'stylesheet\';\n' +
'stylesheet.href = \'' + CUSTOM_CSS_GENERAL + '\';\n' +
'let mobileSpec = document.createElement(\'meta\');\n' +
'mobileSpec.name = \'viewport\';\n' +
'mobileSpec.content = \'width=device-width, initial-scale=1.0\';\n' +
'document.getElementsByTagName(\'head\')[0].appendChild(mobileSpec);\n' +
'document.getElementsByTagName(\'head\')[0].appendChild(stylesheet);\n' +
'document.getElementsByClassName(\'preference-items\')[0].style.display = \'none\';\n' +
'document.getElementsByClassName(\'logoInsa\')[0].style.display = \'none\';\n' +
'document.getElementsByClassName(\'logoPress\')[0].style.display = \'none\';\n' +
'document.getElementsByClassName(\'ent\')[0].style.display = \'none\';\n' +
'document.getElementById(\'portal-page-header\').style.margin = 0;\n' +
'document.querySelectorAll(\'.uportal-navigation-category\').forEach(element => {\n' +
' element.style.cssText = "width: 100%; display: flex; height: 50px;";\n' +
' if (element.children.length > 0)\n' +
' element.children[0].style.margin = \'auto\';\n' +
'});' +
'true;';
}
render() {
const nav = this.props.navigation;
return (
<WebViewScreen
navigation={nav}
data={[
{
url: URL,
icon: '',
name: '',
customJS: this.customInjectedJS
},
]}
headerTitle={i18n.t('screens.ent')}
hasHeaderBackButton={true}
hasSideMenu={false}/>
);
}
}

View file

@ -1,9 +1,8 @@
// @flow
import * as React from 'react';
import ThemeManager from "../utils/ThemeManager";
import WebViewScreen from "../components/WebViewScreen";
import i18n from "i18n-js";
import ThemeManager from "../../utils/ThemeManager";
import WebViewScreen from "../../components/WebViewScreen";
type Props = {
navigation: Object,
@ -12,28 +11,33 @@ type Props = {
const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/planex/customMobile2.css';
const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/planex/customMobile3.css';
const CUSTOM_CSS_NIGHTMODE = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/planex/customDark2.css';
// // JS + JQuery functions used to remove alpha from events. Copy paste in browser console for quick testing
// // Remove alpha from given Jquery node
// function removeAlpha(node) {
// console.log(node);
// let bg = node.css("background-color");
// if (bg.match("^rgba")) {
// let a = bg.slice(5).split(',');
// let newBg ='rgb(' + a[0] + ',' + parseInt(a[1]) + ',' + parseInt(a[2]) + ')';
// // Fix for tooltips with broken background
// if (parseInt(a[0]) === parseInt(a[1]) && parseInt(a[1]) === parseInt(a[2]) && parseInt(a[2]) === 0) {
// a[0] = a[1] = a[2] = '255';
// }
// let newBg ='rgb(' + a[0] + ',' + a[1] + ',' + a[2] + ')';
// node.css("background-color", newBg);
// }
// }
// // Observe for planning DOM changes
// let observer = new MutationObserver(function(mutations) {
// for (let i = 0; i < mutations.length; i++) {
// if (mutations[i]['addedNodes'].length > 0 && $(mutations[i]['addedNodes'][0]).hasClass("fc-event"))
// if (mutations[i]['addedNodes'].length > 0 &&
// ($(mutations[i]['addedNodes'][0]).hasClass("fc-event") || $(mutations[i]['addedNodes'][0]).hasClass("tooltiptopicevent")))
// removeAlpha($(mutations[i]['addedNodes'][0]))
// }
// });
// observer.observe(document.querySelector(".fc-body"), {attributes: false, childList: true, characterData: false, subtree:true});
// // observer.observe(document.querySelector(".fc-body"), {attributes: false, childList: true, characterData: false, subtree:true});
// observer.observe(document.querySelector("body"), {attributes: false, childList: true, characterData: false, subtree:true});
// // Run remove alpha a first time on whole planning. Useful when code injected after planning fully loaded.
// $(".fc-event-container .fc-event").each(function(index) {
// removeAlpha($(this));
@ -42,21 +46,28 @@ const CUSTOM_CSS_NIGHTMODE = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_
// Watch for changes in the calendar and call the remove alpha function
const OBSERVE_MUTATIONS_INJECTED =
'function removeAlpha(node) {\n' +
' console.log(node);\n' +
' let bg = node.css("background-color");\n' +
' if (bg.match("^rgba")) {\n' +
' let a = bg.slice(5).split(\',\');\n' +
' let newBg =\'rgb(\' + a[0] + \',\' + parseInt(a[1]) + \',\' + parseInt(a[2]) + \')\';\n' +
' // Fix for tooltips with broken background\n' +
' if (parseInt(a[0]) === parseInt(a[1]) && parseInt(a[1]) === parseInt(a[2]) && parseInt(a[2]) === 0) {\n' +
' a[0] = a[1] = a[2] = \'255\';\n' +
' }\n' +
' let newBg =\'rgb(\' + a[0] + \',\' + a[1] + \',\' + a[2] + \')\';\n' +
' node.css("background-color", newBg);\n' +
' }\n' +
'}' +
'}\n' +
'// Observe for planning DOM changes\n' +
'let observer = new MutationObserver(function(mutations) {\n' +
' for (let i = 0; i < mutations.length; i++) {\n' +
' if (mutations[i][\'addedNodes\'].length > 0 && $(mutations[i][\'addedNodes\'][0]).hasClass("fc-event"))\n' +
' if (mutations[i][\'addedNodes\'].length > 0 &&\n' +
' ($(mutations[i][\'addedNodes\'][0]).hasClass("fc-event") || $(mutations[i][\'addedNodes\'][0]).hasClass("tooltiptopicevent")))\n' +
' removeAlpha($(mutations[i][\'addedNodes\'][0]))\n' +
' }\n' +
'});\n' +
'observer.observe(document.querySelector(".fc-body"), {attributes: false, childList: true, characterData: false, subtree:true});\n' +
'// observer.observe(document.querySelector(".fc-body"), {attributes: false, childList: true, characterData: false, subtree:true});\n' +
'observer.observe(document.querySelector("body"), {attributes: false, childList: true, characterData: false, subtree:true});\n' +
'// Run remove alpha a first time on whole planning. Useful when code injected after planning fully loaded.\n' +
'$(".fc-event-container .fc-event").each(function(index) {\n' +
' removeAlpha($(this));\n' +
'});';
@ -73,17 +84,13 @@ export default class PlanexScreen extends React.Component<Props> {
this.customInjectedJS =
'$(document).ready(function() {' +
OBSERVE_MUTATIONS_INJECTED +
'$("head").append(\'<meta name="viewport" content="width=device-width, initial-scale=1.0">\');' +
'$("head").append(\'<meta name="viewport" content="width=device-width, initial-scale=0.9">\');' +
'$("head").append(\'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\');';
if (ThemeManager.getNightMode())
this.customInjectedJS += '$("head").append(\'<link rel="stylesheet" href="' + CUSTOM_CSS_NIGHTMODE + '" type="text/css"/>\');';
this.customInjectedJS +=
'$(".fc-toolbar .fc-center").append(\'<p id="rotateToLandscape" style="color: ' + ThemeManager.getCurrentThemeVariables().brandPrimary + '">' +
i18n.t("planexScreen.rotateToLandscape") + '</p>\');' +
'$(".fc-toolbar .fc-center").append(\'<p id="rotateToPortrait" style="color: ' + ThemeManager.getCurrentThemeVariables().brandPrimary + '">' +
i18n.t("planexScreen.rotateToPortrait") + '</p>\');' +
'removeAlpha();' +
'});true;'; // Prevent crash on ios

View file

@ -1,8 +1,7 @@
// @flow
import * as React from 'react';
import ThemeManager from "../utils/ThemeManager";
import WebViewScreen from "../components/WebViewScreen";
import WebViewScreen from "../../components/WebViewScreen";
type Props = {
navigation: Object,

View file

@ -1,8 +1,7 @@
// @flow
import * as React from 'react';
import ThemeManager from "../utils/ThemeManager";
import WebViewScreen from "../components/WebViewScreen";
import WebViewScreen from "../../components/WebViewScreen";
type Props = {
navigation: Object,

View file

@ -7,9 +7,16 @@
"menuSelf": "RU Menu",
"settings": "Settings",
"availableRooms": "Available rooms",
"bluemind": "INSA Mails",
"ent": "INSA ENT",
"about": "About",
"debug": "Debug"
},
"sidenav": {
"divider1": "Student websites",
"divider2": "Services",
"divider3": "Personalisation"
},
"intro": {
"slide1": {
"title": "Welcome to CAMPUS",
@ -41,7 +48,7 @@
},
"updateSlide": {
"title": "New in this update!",
"text": "Get ready for your exams with Tutor'INSA! Book a Bib'Box or find an empty room to study, available in the side menu."
"text": "Never miss an email anymore! Acces your INSA webmail from the app using the left menu.\nPlanex has also seen some improvements!\n\nSome of your remarks where taken into account for this update, more to come.\nThanks for your feedback on the survey! "
},
"buttons": {
"next": "Next",

View file

@ -7,9 +7,16 @@
"menuSelf": "Menu du RU",
"settings": "Paramètres",
"availableRooms": "Salles dispo",
"bluemind": "Mails INSA",
"ent": "ENT INSA",
"about": "À Propos",
"debug": "Debug"
},
"sidenav": {
"divider1": "Sites étudiants",
"divider2": "Services",
"divider3": "Personnalisation"
},
"intro": {
"slide1": {
"title": "Bienvenue sur CAMPUS",
@ -41,7 +48,7 @@
},
"updateSlide": {
"title": "Nouveau dans cette mise à jour !",
"text": "Préparez vos exams avec Tutor'INSA! Réservez une Bib'Box ou trouvez une salle libre pour travailler, disponible dans le menu à gauche. "
"text": "Ne ratez plus jamais un email ! Accédez à vos mails INSA depuis le menu à gauche.\nPlanex a aussi été un peu amélioré !\n\nUne partie de vos remarques ont été prises en compte pour cette mise à jour, d'autres sont à venir.\nMerci pour votre retour lors du sondage !"
},
"buttons": {
"next": "Suivant",

View file

@ -29,8 +29,8 @@ export default class AsyncStorageManager {
default: '1',
current: '',
},
showUpdate4: {
key: 'showUpdate4',
showUpdate5: {
key: 'showUpdate5',
default: '1',
current: '',
},