forked from vergnet/application-amicale
Merge branch 'dev'
This commit is contained in:
commit
08f98caf30
19 changed files with 364 additions and 313 deletions
11
App.js
11
App.js
|
@ -1,10 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {StatusBar, Platform} from 'react-native';
|
import {Platform, StatusBar} from 'react-native';
|
||||||
import {Root, StyleProvider} from 'native-base';
|
import {Root, StyleProvider} from 'native-base';
|
||||||
import {createAppContainerWithInitialRoute} from './navigation/AppNavigator';
|
import {createAppContainerWithInitialRoute} from './navigation/AppNavigator';
|
||||||
import ThemeManager from './utils/ThemeManager';
|
|
||||||
import LocaleManager from './utils/LocaleManager';
|
import LocaleManager from './utils/LocaleManager';
|
||||||
import * as Font from 'expo-font';
|
import * as Font from 'expo-font';
|
||||||
import {clearThemeCache} from 'native-base-shoutem-theme';
|
import {clearThemeCache} from 'native-base-shoutem-theme';
|
||||||
|
@ -12,6 +11,7 @@ import AsyncStorageManager from "./utils/AsyncStorageManager";
|
||||||
import CustomIntroSlider from "./components/CustomIntroSlider";
|
import CustomIntroSlider from "./components/CustomIntroSlider";
|
||||||
import {AppLoading} from 'expo';
|
import {AppLoading} from 'expo';
|
||||||
import NotificationsManager from "./utils/NotificationsManager";
|
import NotificationsManager from "./utils/NotificationsManager";
|
||||||
|
import ThemeManager from './utils/ThemeManager';
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
|
@ -49,12 +49,9 @@ export default class App extends React.Component<Props, State> {
|
||||||
|
|
||||||
setupStatusBar() {
|
setupStatusBar() {
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
console.log(ThemeManager.getNightMode());
|
|
||||||
if (ThemeManager.getNightMode()) {
|
if (ThemeManager.getNightMode()) {
|
||||||
console.log('setting light mode');
|
|
||||||
StatusBar.setBarStyle('light-content', true);
|
StatusBar.setBarStyle('light-content', true);
|
||||||
} else {
|
} else {
|
||||||
console.log('setting dark mode');
|
|
||||||
StatusBar.setBarStyle('dark-content', true);
|
StatusBar.setBarStyle('dark-content', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +70,6 @@ export default class App extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadAssetsAsync() {
|
async loadAssetsAsync() {
|
||||||
console.log('Starting loading assets...');
|
|
||||||
// Wait for custom fonts to be loaded before showing the app
|
// Wait for custom fonts to be loaded before showing the app
|
||||||
await Font.loadAsync({
|
await Font.loadAsync({
|
||||||
'Roboto': require('native-base/Fonts/Roboto.ttf'),
|
'Roboto': require('native-base/Fonts/Roboto.ttf'),
|
||||||
|
@ -83,18 +79,15 @@ export default class App extends React.Component<Props, State> {
|
||||||
await AsyncStorageManager.getInstance().loadPreferences();
|
await AsyncStorageManager.getInstance().loadPreferences();
|
||||||
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
||||||
await NotificationsManager.initExpoToken();
|
await NotificationsManager.initExpoToken();
|
||||||
// console.log(AsyncStorageManager.getInstance().preferences.expoToken.current);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoadFinished() {
|
onLoadFinished() {
|
||||||
// Only show intro if this is the first time starting the app
|
// Only show intro if this is the first time starting the app
|
||||||
console.log('Finished loading');
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
currentTheme: ThemeManager.getCurrentTheme(),
|
currentTheme: ThemeManager.getCurrentTheme(),
|
||||||
showIntro: AsyncStorageManager.getInstance().preferences.showIntro.current === '1',
|
showIntro: AsyncStorageManager.getInstance().preferences.showIntro.current === '1',
|
||||||
showUpdate: AsyncStorageManager.getInstance().preferences.showUpdate5.current === '1'
|
showUpdate: AsyncStorageManager.getInstance().preferences.showUpdate5.current === '1'
|
||||||
// showIntro: true
|
|
||||||
});
|
});
|
||||||
// Status bar goes dark if set too fast
|
// Status bar goes dark if set too fast
|
||||||
setTimeout(this.setupStatusBar,
|
setTimeout(this.setupStatusBar,
|
||||||
|
|
|
@ -2,6 +2,15 @@
|
||||||
|
|
||||||
Pensez à garder l'appli à jour pour profiter des dernières fonctionnalités !
|
Pensez à garder l'appli à jour pour profiter des dernières fonctionnalités !
|
||||||
|
|
||||||
|
- **v1.5.0** - _05/02/2020_
|
||||||
|
- Amélioration des performances de l'application
|
||||||
|
- Amélioration du menu gauche
|
||||||
|
- Ajout d'animations au changement d'écran
|
||||||
|
- Affichage de l'événement de l'accueil directement au clic, au lieu de juste amener sur la liste
|
||||||
|
- _Notes de développement :_
|
||||||
|
- Passage de React Navigation 3 à 4
|
||||||
|
- Mise à jour d'autres librairies
|
||||||
|
|
||||||
- **v1.4.0** - _01/02/2020_
|
- **v1.4.0** - _01/02/2020_
|
||||||
- Correction d'un crash lors du rafraichissement de planex
|
- Correction d'un crash lors du rafraichissement de planex
|
||||||
- Correction de bugs divers
|
- Correction de bugs divers
|
||||||
|
|
4
app.json
4
app.json
|
@ -10,7 +10,7 @@
|
||||||
"android",
|
"android",
|
||||||
"web"
|
"web"
|
||||||
],
|
],
|
||||||
"version": "1.4.0",
|
"version": "1.5.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": 12,
|
"versionCode": 13,
|
||||||
"icon": "./assets/android.icon.png",
|
"icon": "./assets/android.icon.png",
|
||||||
"adaptiveIcon": {
|
"adaptiveIcon": {
|
||||||
"foregroundImage": "./assets/android.adaptive-icon.png",
|
"foregroundImage": "./assets/android.adaptive-icon.png",
|
||||||
|
|
|
@ -2,5 +2,10 @@ module.exports = function(api) {
|
||||||
api.cache(true);
|
api.cache(true);
|
||||||
return {
|
return {
|
||||||
presets: ['babel-preset-expo'],
|
presets: ['babel-preset-expo'],
|
||||||
|
env: {
|
||||||
|
production: {
|
||||||
|
plugins: ['react-native-paper/babel'],
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Container} from "native-base";
|
import {Container} from "native-base";
|
||||||
import CustomHeader from "./CustomHeader";
|
import CustomHeader from "./CustomHeader";
|
||||||
import CustomSideMenu from "./CustomSideMenu";
|
|
||||||
import CustomMaterialIcon from "./CustomMaterialIcon";
|
import CustomMaterialIcon from "./CustomMaterialIcon";
|
||||||
import {Platform, StatusBar, View} from "react-native";
|
import {Platform, StatusBar, View} from "react-native";
|
||||||
import ThemeManager from "../utils/ThemeManager";
|
import ThemeManager from "../utils/ThemeManager";
|
||||||
|
@ -15,6 +14,7 @@ import {NavigationActions} from "react-navigation";
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
headerTitle: string,
|
headerTitle: string,
|
||||||
|
headerSubtitle: string,
|
||||||
headerRightButton: React.Node,
|
headerRightButton: React.Node,
|
||||||
children: React.Node,
|
children: React.Node,
|
||||||
hasTabs: boolean,
|
hasTabs: boolean,
|
||||||
|
@ -25,7 +25,6 @@ type Props = {
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
isOpen: boolean,
|
|
||||||
isHeaderVisible: boolean
|
isHeaderVisible: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,24 +38,17 @@ export default class BaseContainer extends React.Component<Props, State> {
|
||||||
hasSideMenu: true,
|
hasSideMenu: true,
|
||||||
enableRotation: false,
|
enableRotation: false,
|
||||||
hideHeaderOnLandscape: false,
|
hideHeaderOnLandscape: false,
|
||||||
|
headerSubtitle: '',
|
||||||
};
|
};
|
||||||
willBlurSubscription: function;
|
willBlurSubscription: function;
|
||||||
willFocusSubscription: function;
|
willFocusSubscription: function;
|
||||||
state = {
|
state = {
|
||||||
isOpen: false,
|
|
||||||
isHeaderVisible: true,
|
isHeaderVisible: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
toggle() {
|
toggle() {
|
||||||
this.setState({
|
this.props.navigation.toggleDrawer();
|
||||||
isOpen: !this.state.isOpen,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMenuState(isOpen: boolean) {
|
|
||||||
this.setState({isOpen});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register for blur event to close side menu on screen change
|
* Register for blur event to close side menu on screen change
|
||||||
*/
|
*/
|
||||||
|
@ -87,7 +79,6 @@ export default class BaseContainer extends React.Component<Props, State> {
|
||||||
() => {
|
() => {
|
||||||
if (this.props.enableRotation)
|
if (this.props.enableRotation)
|
||||||
ScreenOrientation.lockAsync(ScreenOrientation.Orientation.PORTRAIT);
|
ScreenOrientation.lockAsync(ScreenOrientation.Orientation.PORTRAIT);
|
||||||
this.setState({isOpen: false});
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +98,9 @@ export default class BaseContainer extends React.Component<Props, State> {
|
||||||
<Container>
|
<Container>
|
||||||
{this.state.isHeaderVisible ?
|
{this.state.isHeaderVisible ?
|
||||||
<CustomHeader
|
<CustomHeader
|
||||||
navigation={this.props.navigation} title={this.props.headerTitle}
|
navigation={this.props.navigation}
|
||||||
|
title={this.props.headerTitle}
|
||||||
|
subtitle={this.props.headerSubtitle}
|
||||||
leftButton={
|
leftButton={
|
||||||
<Touchable
|
<Touchable
|
||||||
style={{padding: 6}}
|
style={{padding: 6}}
|
||||||
|
@ -128,20 +121,6 @@ export default class BaseContainer extends React.Component<Props, State> {
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (this.getMainContainer());
|
||||||
<View style={{
|
|
||||||
backgroundColor: ThemeManager.getCurrentThemeVariables().sideMenuBgColor,
|
|
||||||
width: '100%',
|
|
||||||
height: '100%'
|
|
||||||
}}>
|
|
||||||
{this.props.hasSideMenu ?
|
|
||||||
<CustomSideMenu
|
|
||||||
navigation={this.props.navigation} isOpen={this.state.isOpen}
|
|
||||||
onChange={(isOpen) => this.updateMenuState(isOpen)}>
|
|
||||||
{this.getMainContainer()}
|
|
||||||
</CustomSideMenu> :
|
|
||||||
this.getMainContainer()}
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {Body, Header, Input, Item, Left, Right, Title} from "native-base";
|
import {Body, Header, Input, Item, Left, Right, Subtitle, Title} from "native-base";
|
||||||
import {Platform, StyleSheet, View} from "react-native";
|
import {Platform, StyleSheet, View} from "react-native";
|
||||||
import {getStatusBarHeight} from "react-native-status-bar-height";
|
import {getStatusBarHeight} from "react-native-status-bar-height";
|
||||||
import Touchable from 'react-native-platform-touchable';
|
import Touchable from 'react-native-platform-touchable';
|
||||||
import ThemeManager from "../utils/ThemeManager";
|
import ThemeManager from "../utils/ThemeManager";
|
||||||
import CustomMaterialIcon from "./CustomMaterialIcon";
|
import CustomMaterialIcon from "./CustomMaterialIcon";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
|
import {NavigationActions} from 'react-navigation';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
hasBackButton: boolean,
|
hasBackButton: boolean,
|
||||||
|
@ -17,6 +18,7 @@ type Props = {
|
||||||
leftButton: React.Node,
|
leftButton: React.Node,
|
||||||
rightButton: React.Node,
|
rightButton: React.Node,
|
||||||
title: string,
|
title: string,
|
||||||
|
subtitle: string,
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
hasTabs: boolean,
|
hasTabs: boolean,
|
||||||
};
|
};
|
||||||
|
@ -37,6 +39,7 @@ export default class CustomHeader extends React.Component<Props> {
|
||||||
searchCallback: () => null,
|
searchCallback: () => null,
|
||||||
shouldFocusSearchBar: false,
|
shouldFocusSearchBar: false,
|
||||||
title: '',
|
title: '',
|
||||||
|
subtitle: '',
|
||||||
leftButton: <View/>,
|
leftButton: <View/>,
|
||||||
rightButton: <View/>,
|
rightButton: <View/>,
|
||||||
hasTabs: false,
|
hasTabs: false,
|
||||||
|
@ -51,6 +54,7 @@ export default class CustomHeader extends React.Component<Props> {
|
||||||
|
|
||||||
getSearchBar() {
|
getSearchBar() {
|
||||||
return (
|
return (
|
||||||
|
<Body>
|
||||||
<Item
|
<Item
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
@ -65,9 +69,24 @@ export default class CustomHeader extends React.Component<Props> {
|
||||||
placeholderTextColor={ThemeManager.getCurrentThemeVariables().toolbarPlaceholderColor}
|
placeholderTextColor={ThemeManager.getCurrentThemeVariables().toolbarPlaceholderColor}
|
||||||
onChangeText={(text) => this.props.searchCallback(text)}/>
|
onChangeText={(text) => this.props.searchCallback(text)}/>
|
||||||
</Item>
|
</Item>
|
||||||
|
</Body>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getHeaderTitle() {
|
||||||
|
return (
|
||||||
|
<Body>
|
||||||
|
<Title style={{
|
||||||
|
color: ThemeManager.getCurrentThemeVariables().toolbarTextColor
|
||||||
|
}}>
|
||||||
|
{this.props.title}
|
||||||
|
</Title>
|
||||||
|
{this.props.subtitle !== '' ? <Subtitle>{this.props.subtitle}</Subtitle> : null}
|
||||||
|
</Body>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let button;
|
let button;
|
||||||
// Does the app have a back button or a burger menu ?
|
// Does the app have a back button or a burger menu ?
|
||||||
|
@ -75,10 +94,13 @@ export default class CustomHeader extends React.Component<Props> {
|
||||||
button =
|
button =
|
||||||
<Touchable
|
<Touchable
|
||||||
style={{padding: 6}}
|
style={{padding: 6}}
|
||||||
onPress={() => this.props.navigation.goBack()}>
|
onPress={() => {
|
||||||
|
const backAction = NavigationActions.back();
|
||||||
|
this.props.navigation.dispatch(backAction);
|
||||||
|
}}>
|
||||||
<CustomMaterialIcon
|
<CustomMaterialIcon
|
||||||
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
|
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
|
||||||
icon="arrow-left"/>
|
icon={Platform.OS === 'ios' ? 'chevron-left' : "arrow-left"}/>
|
||||||
</Touchable>;
|
</Touchable>;
|
||||||
else
|
else
|
||||||
button = this.props.leftButton;
|
button = this.props.leftButton;
|
||||||
|
@ -89,14 +111,9 @@ export default class CustomHeader extends React.Component<Props> {
|
||||||
<Left style={{flex: 0}}>
|
<Left style={{flex: 0}}>
|
||||||
{button}
|
{button}
|
||||||
</Left>
|
</Left>
|
||||||
<Body>
|
|
||||||
{this.props.hasSearchField ?
|
{this.props.hasSearchField ?
|
||||||
this.getSearchBar() :
|
this.getSearchBar() :
|
||||||
<Title style={{
|
this.getHeaderTitle()}
|
||||||
paddingLeft: 10,
|
|
||||||
color: ThemeManager.getCurrentThemeVariables().toolbarTextColor
|
|
||||||
}}>{this.props.title}</Title>}
|
|
||||||
</Body>
|
|
||||||
<Right style={{flex: this.props.hasSearchField ? 0 : 1}}>
|
<Right style={{flex: this.props.hasSearchField ? 0 : 1}}>
|
||||||
{this.props.rightButton}
|
{this.props.rightButton}
|
||||||
</Right>
|
</Right>
|
||||||
|
@ -104,7 +121,6 @@ export default class CustomHeader extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Fix header in status bar on Android
|
// Fix header in status bar on Android
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
header: {
|
header: {
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import SideMenu from "react-native-side-menu";
|
|
||||||
import SideBar from "./Sidebar";
|
|
||||||
import {View} from "react-native";
|
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
navigation: Object,
|
|
||||||
children: React.Node,
|
|
||||||
isOpen: boolean,
|
|
||||||
onChange: Function,
|
|
||||||
}
|
|
||||||
|
|
||||||
type State = {
|
|
||||||
shouldShowMenu: boolean, // Prevent menu from showing in transitions between tabs
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class CustomSideMenu extends React.Component<Props, State> {
|
|
||||||
|
|
||||||
state = {
|
|
||||||
shouldShowMenu: this.props.isOpen,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Stop the side menu from being shown while tab transition is playing
|
|
||||||
// => Hide the menu when behind the actual screen
|
|
||||||
onMenuMove(percent: number) {
|
|
||||||
if (percent <= 0)
|
|
||||||
this.setState({shouldShowMenu: false});
|
|
||||||
else if (this.state.shouldShowMenu === false)
|
|
||||||
this.setState({shouldShowMenu: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<SideMenu menu={
|
|
||||||
this.state.shouldShowMenu ?
|
|
||||||
<SideBar navigation={this.props.navigation}/>
|
|
||||||
: <View/>}
|
|
||||||
isOpen={this.props.isOpen}
|
|
||||||
onChange={this.props.onChange}
|
|
||||||
onSliding={(percent) => this.onMenuMove(percent)}>
|
|
||||||
{this.props.children}
|
|
||||||
</SideMenu>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +1,14 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import {createAppContainer, createStackNavigator} from 'react-navigation';
|
import {createAppContainer} from 'react-navigation';
|
||||||
import {createMaterialBottomTabNavigatorWithInitialRoute} from './MainTabNavigator';
|
import {createDrawerNavigatorWithInitialRoute} from './DrawerNavigator';
|
||||||
import SettingsScreen from '../screens/SettingsScreen';
|
|
||||||
import AboutScreen from '../screens/About/AboutScreen';
|
|
||||||
import ProximoListScreen from '../screens/Proximo/ProximoListScreen';
|
|
||||||
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/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";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a stack navigator using the drawer to handle navigation between screens
|
* Create a stack navigator using the drawer to handle navigation between screens
|
||||||
*/
|
*/
|
||||||
function createAppContainerWithInitialRoute(initialRoute: string) {
|
function createAppContainerWithInitialRoute(initialRoute: string) {
|
||||||
return createAppContainer(
|
return createAppContainer(createDrawerNavigatorWithInitialRoute(initialRoute));
|
||||||
createStackNavigator({
|
|
||||||
Main: createMaterialBottomTabNavigatorWithInitialRoute(initialRoute),
|
|
||||||
// Drawer: MainDrawerNavigator,
|
|
||||||
ProximoListScreen: {screen: ProximoListScreen},
|
|
||||||
SettingsScreen: {screen: SettingsScreen},
|
|
||||||
AboutScreen: {screen: AboutScreen},
|
|
||||||
AboutDependenciesScreen: {screen: AboutDependenciesScreen},
|
|
||||||
SelfMenuScreen: {screen: SelfMenuScreen},
|
|
||||||
TutorInsaScreen: {screen: TutorInsaScreen},
|
|
||||||
AmicaleScreen: {screen: AmicaleScreen},
|
|
||||||
WiketudScreen: {screen: WiketudScreen},
|
|
||||||
ElusEtudScreen: {screen: ElusEtudScreen},
|
|
||||||
BlueMindScreen: {screen: BlueMindScreen},
|
|
||||||
EntScreen: {screen: EntScreen},
|
|
||||||
AvailableRoomScreen: {screen: AvailableRoomScreen},
|
|
||||||
ProxiwashAboutScreen: {screen: ProxiwashAboutScreen},
|
|
||||||
ProximoAboutScreen: {screen: ProximoAboutScreen},
|
|
||||||
DebugScreen: {screen: DebugScreen},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
initialRouteName: "Main",
|
|
||||||
mode: 'card',
|
|
||||||
headerMode: "none",
|
|
||||||
transitionConfig: () => fromRight(),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {createAppContainerWithInitialRoute};
|
export {createAppContainerWithInitialRoute};
|
||||||
|
|
79
navigation/DrawerNavigator.js
Normal file
79
navigation/DrawerNavigator.js
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import { createDrawerNavigator } from 'react-navigation-drawer';
|
||||||
|
import {createMaterialBottomTabNavigatorWithInitialRoute} from './MainTabNavigator';
|
||||||
|
import SettingsScreen from '../screens/SettingsScreen';
|
||||||
|
import AboutScreen from '../screens/About/AboutScreen';
|
||||||
|
import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen';
|
||||||
|
import SelfMenuScreen from '../screens/SelfMenuScreen';
|
||||||
|
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 Sidebar from "../components/Sidebar";
|
||||||
|
import {createStackNavigator, TransitionPresets} from "react-navigation-stack";
|
||||||
|
|
||||||
|
const AboutStack = createStackNavigator({
|
||||||
|
AboutScreen: {screen: AboutScreen},
|
||||||
|
AboutDependenciesScreen: {screen: AboutDependenciesScreen},
|
||||||
|
DebugScreen: {screen: DebugScreen},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
initialRouteName: "AboutScreen",
|
||||||
|
mode: 'card',
|
||||||
|
headerMode: "none",
|
||||||
|
defaultNavigationOptions: {
|
||||||
|
gestureEnabled: true,
|
||||||
|
cardOverlayEnabled: true,
|
||||||
|
...TransitionPresets.SlideFromRightIOS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Create a stack to use animations
|
||||||
|
function createDrawerStackWithInitialRoute(initialRoute: string) {
|
||||||
|
return createStackNavigator({
|
||||||
|
Main: createMaterialBottomTabNavigatorWithInitialRoute(initialRoute),
|
||||||
|
SettingsScreen: {screen: SettingsScreen},
|
||||||
|
AboutScreen: AboutStack,
|
||||||
|
SelfMenuScreen: {screen: SelfMenuScreen},
|
||||||
|
TutorInsaScreen: {screen: TutorInsaScreen},
|
||||||
|
AmicaleScreen: {screen: AmicaleScreen},
|
||||||
|
WiketudScreen: {screen: WiketudScreen},
|
||||||
|
ElusEtudScreen: {screen: ElusEtudScreen},
|
||||||
|
BlueMindScreen: {screen: BlueMindScreen},
|
||||||
|
EntScreen: {screen: EntScreen},
|
||||||
|
AvailableRoomScreen: {screen: AvailableRoomScreen},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
initialRouteName: "Main",
|
||||||
|
mode: 'card',
|
||||||
|
headerMode: "none",
|
||||||
|
defaultNavigationOptions: {
|
||||||
|
gestureEnabled: true,
|
||||||
|
cardOverlayEnabled: true,
|
||||||
|
...TransitionPresets.SlideFromRightIOS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the drawer navigation stack
|
||||||
|
*/
|
||||||
|
function createDrawerNavigatorWithInitialRoute(initialRoute: string) {
|
||||||
|
return createDrawerNavigator({
|
||||||
|
Main: createDrawerStackWithInitialRoute(initialRoute),
|
||||||
|
}, {
|
||||||
|
contentComponent: Sidebar,
|
||||||
|
initialRouteName: 'Main',
|
||||||
|
backBehavior: 'initialRoute',
|
||||||
|
drawerType: 'front',
|
||||||
|
useNativeAnimations: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export {createDrawerNavigatorWithInitialRoute};
|
|
@ -1,10 +1,15 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import {createStackNavigator, TransitionPresets} from 'react-navigation-stack';
|
||||||
import {createMaterialBottomTabNavigator} from "react-navigation-material-bottom-tabs";
|
import {createMaterialBottomTabNavigator} from "react-navigation-material-bottom-tabs";
|
||||||
|
|
||||||
import HomeScreen from '../screens/HomeScreen';
|
import HomeScreen from '../screens/HomeScreen';
|
||||||
import PlanningScreen from '../screens/PlanningScreen';
|
import PlanningScreen from '../screens/PlanningScreen';
|
||||||
|
import PlanningDisplayScreen from '../screens/PlanningDisplayScreen';
|
||||||
import ProxiwashScreen from '../screens/Proxiwash/ProxiwashScreen';
|
import ProxiwashScreen from '../screens/Proxiwash/ProxiwashScreen';
|
||||||
|
import ProxiwashAboutScreen from '../screens/Proxiwash/ProxiwashAboutScreen';
|
||||||
import ProximoMainScreen from '../screens/Proximo/ProximoMainScreen';
|
import ProximoMainScreen from '../screens/Proximo/ProximoMainScreen';
|
||||||
|
import ProximoListScreen from "../screens/Proximo/ProximoListScreen";
|
||||||
|
import ProximoAboutScreen from "../screens/Proximo/ProximoAboutScreen";
|
||||||
import PlanexScreen from '../screens/Websites/PlanexScreen';
|
import PlanexScreen from '../screens/Websites/PlanexScreen';
|
||||||
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
||||||
import ThemeManager from "../utils/ThemeManager";
|
import ThemeManager from "../utils/ThemeManager";
|
||||||
|
@ -17,12 +22,78 @@ const TAB_ICONS = {
|
||||||
Planex: 'timetable',
|
Planex: 'timetable',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ProximoStack = createStackNavigator({
|
||||||
|
ProximoMainScreen: {screen: ProximoMainScreen},
|
||||||
|
ProximoListScreen: {screen: ProximoListScreen},
|
||||||
|
ProximoAboutScreen: {
|
||||||
|
screen: ProximoAboutScreen,
|
||||||
|
navigationOptions: () => ({
|
||||||
|
...TransitionPresets.ModalSlideFromBottomIOS,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
initialRouteName: "ProximoMainScreen",
|
||||||
|
mode: 'card',
|
||||||
|
headerMode: "none",
|
||||||
|
defaultNavigationOptions: {
|
||||||
|
gestureEnabled: true,
|
||||||
|
cardOverlayEnabled: true,
|
||||||
|
...TransitionPresets.SlideFromRightIOS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ProxiwashStack = createStackNavigator({
|
||||||
|
ProxiwashScreen: {screen: ProxiwashScreen},
|
||||||
|
ProxiwashAboutScreen: {screen: ProxiwashAboutScreen},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
initialRouteName: "ProxiwashScreen",
|
||||||
|
mode: 'card',
|
||||||
|
headerMode: "none",
|
||||||
|
defaultNavigationOptions: {
|
||||||
|
gestureEnabled: true,
|
||||||
|
cardOverlayEnabled: true,
|
||||||
|
...TransitionPresets.ModalSlideFromBottomIOS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const PlanningStack = createStackNavigator({
|
||||||
|
PlanningScreen: {screen: PlanningScreen},
|
||||||
|
PlanningDisplayScreen: {screen: PlanningDisplayScreen},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
initialRouteName: "PlanningScreen",
|
||||||
|
mode: 'card',
|
||||||
|
headerMode: "none",
|
||||||
|
defaultNavigationOptions: {
|
||||||
|
gestureEnabled: true,
|
||||||
|
cardOverlayEnabled: true,
|
||||||
|
...TransitionPresets.ModalSlideFromBottomIOS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const HomeStack = createStackNavigator({
|
||||||
|
HomeScreen: {screen: HomeScreen},
|
||||||
|
PlanningDisplayScreen: {screen: PlanningDisplayScreen},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
initialRouteName: "HomeScreen",
|
||||||
|
mode: 'card',
|
||||||
|
headerMode: "none",
|
||||||
|
defaultNavigationOptions: {
|
||||||
|
gestureEnabled: true,
|
||||||
|
cardOverlayEnabled: true,
|
||||||
|
...TransitionPresets.ModalSlideFromBottomIOS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
function createMaterialBottomTabNavigatorWithInitialRoute(initialRoute: string) {
|
function createMaterialBottomTabNavigatorWithInitialRoute(initialRoute: string) {
|
||||||
return createMaterialBottomTabNavigator({
|
return createMaterialBottomTabNavigator({
|
||||||
Home: {screen: HomeScreen},
|
Home: HomeStack,
|
||||||
Planning: {screen: PlanningScreen,},
|
Planning: PlanningStack,
|
||||||
Proxiwash: {screen: ProxiwashScreen,},
|
Proxiwash: ProxiwashStack,
|
||||||
Proximo: {screen: ProximoMainScreen,},
|
Proximo: ProximoStack,
|
||||||
Planex: {
|
Planex: {
|
||||||
screen: PlanexScreen,
|
screen: PlanexScreen,
|
||||||
navigationOptions: ({navigation}) => {
|
navigationOptions: ({navigation}) => {
|
||||||
|
|
14
package.json
14
package.json
|
@ -8,6 +8,7 @@
|
||||||
"eject": "expo eject"
|
"eject": "expo eject"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-native-community/masked-view": "0.1.5",
|
||||||
"expo": "^36.0.0",
|
"expo": "^36.0.0",
|
||||||
"expo-font": "~8.0.0",
|
"expo-font": "~8.0.0",
|
||||||
"expo-linear-gradient": "~8.0.0",
|
"expo-linear-gradient": "~8.0.0",
|
||||||
|
@ -21,19 +22,22 @@
|
||||||
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.1.tar.gz",
|
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.1.tar.gz",
|
||||||
"react-native-app-intro-slider": "^3.0.0",
|
"react-native-app-intro-slider": "^3.0.0",
|
||||||
"react-native-autolink": "^1.8.1",
|
"react-native-autolink": "^1.8.1",
|
||||||
"react-native-calendars": "^1.212.0",
|
"react-native-calendars": "^1.260.0",
|
||||||
"react-native-gesture-handler": "~1.5.0",
|
"react-native-gesture-handler": "~1.5.0",
|
||||||
"react-native-material-menu": "^0.6.7",
|
"react-native-material-menu": "^1.0.0",
|
||||||
"react-native-modalize": "^1.3.6",
|
"react-native-modalize": "^1.3.6",
|
||||||
"react-native-paper": "^3.5.1",
|
"react-native-paper": "^3.5.1",
|
||||||
"react-native-platform-touchable": "^1.1.1",
|
"react-native-platform-touchable": "^1.1.1",
|
||||||
|
"react-native-reanimated": "~1.4.0",
|
||||||
"react-native-render-html": "^4.1.2",
|
"react-native-render-html": "^4.1.2",
|
||||||
|
"react-native-safe-area-context": "0.6.0",
|
||||||
"react-native-screens": "2.0.0-alpha.12",
|
"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-status-bar-height": "^2.3.1",
|
||||||
"react-native-webview": "7.4.3",
|
"react-native-webview": "7.4.3",
|
||||||
"react-navigation": "^3.13.0",
|
"react-navigation": "^4.1.0",
|
||||||
"react-navigation-material-bottom-tabs": "^1.1.1",
|
"react-navigation-drawer": "^2.3.3",
|
||||||
|
"react-navigation-material-bottom-tabs": "^2.1.5",
|
||||||
|
"react-navigation-stack": "^2.1.0",
|
||||||
"react-navigation-transitions": "^1.0.12"
|
"react-navigation-transitions": "^1.0.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -319,14 +319,12 @@ export default class AboutScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
tryUnlockDebugMode() {
|
tryUnlockDebugMode() {
|
||||||
this.debugTapCounter = this.debugTapCounter + 1;
|
this.debugTapCounter = this.debugTapCounter + 1;
|
||||||
console.log(this.debugTapCounter);
|
|
||||||
if (this.debugTapCounter >= 4) {
|
if (this.debugTapCounter >= 4) {
|
||||||
this.unlockDebugMode();
|
this.unlockDebugMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockDebugMode() {
|
unlockDebugMode() {
|
||||||
console.log('unlocked');
|
|
||||||
this.setState({isDebugUnlocked: true});
|
this.setState({isDebugUnlocked: true});
|
||||||
let key = AsyncStorageManager.getInstance().preferences.debugUnlocked.key;
|
let key = AsyncStorageManager.getInstance().preferences.debugUnlocked.key;
|
||||||
AsyncStorageManager.getInstance().savePref(key, '1');
|
AsyncStorageManager.getInstance().savePref(key, '1');
|
||||||
|
|
|
@ -83,7 +83,6 @@ export default class DebugScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
alertCurrentExpoToken() {
|
alertCurrentExpoToken() {
|
||||||
let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
|
let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
|
||||||
console.log(token);
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
'Expo Token',
|
'Expo Token',
|
||||||
token,
|
token,
|
||||||
|
|
|
@ -310,7 +310,12 @@ export default class HomeScreen extends FetchedDataSectionList {
|
||||||
</Text>;
|
</Text>;
|
||||||
} else
|
} else
|
||||||
subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
|
subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
|
||||||
let clickAction = () => this.props.navigation.navigate('Planning');
|
let clickAction = () => {
|
||||||
|
if (isAvailable)
|
||||||
|
this.props.navigation.navigate('PlanningDisplayScreen', {data: displayEvent});
|
||||||
|
else
|
||||||
|
this.props.navigation.navigate('PlanningScreen');
|
||||||
|
};
|
||||||
|
|
||||||
let displayEvent = this.getDisplayEvent(futureEvents);
|
let displayEvent = this.getDisplayEvent(futureEvents);
|
||||||
|
|
||||||
|
|
69
screens/PlanningDisplayScreen.js
Normal file
69
screens/PlanningDisplayScreen.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {Image} from 'react-native';
|
||||||
|
import {Container, Content, H1, H3, View} from 'native-base';
|
||||||
|
import CustomHeader from "../components/CustomHeader";
|
||||||
|
import ThemeManager from "../utils/ThemeManager";
|
||||||
|
import HTML from "react-native-render-html";
|
||||||
|
import {Linking} from "expo";
|
||||||
|
import PlanningEventManager from '../utils/PlanningEventManager';
|
||||||
|
import i18n from 'i18n-js';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
navigation: Object,
|
||||||
|
};
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
export default class PlanningDisplayScreen extends React.Component<Props> {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const nav = this.props.navigation;
|
||||||
|
const displayData = nav.getParam('data', []);
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<CustomHeader
|
||||||
|
navigation={nav}
|
||||||
|
title={displayData.title}
|
||||||
|
subtitle={PlanningEventManager.getFormattedTime(displayData)}
|
||||||
|
hasBackButton={true}/>
|
||||||
|
<Content padder>
|
||||||
|
<H1>
|
||||||
|
{displayData.title}
|
||||||
|
</H1>
|
||||||
|
<H3 style={{
|
||||||
|
marginTop: 10,
|
||||||
|
color: ThemeManager.getCurrentThemeVariables().listNoteColor
|
||||||
|
}}>
|
||||||
|
{PlanningEventManager.getFormattedTime(displayData)}
|
||||||
|
</H3>
|
||||||
|
{displayData.logo !== null ?
|
||||||
|
<View style={{width: '100%', height: 300, marginTop: 20, marginBottom: 20}}>
|
||||||
|
<Image style={{flex: 1, resizeMode: "contain"}}
|
||||||
|
source={{uri: displayData.logo}}/>
|
||||||
|
</View>
|
||||||
|
: <View/>}
|
||||||
|
|
||||||
|
{displayData.description !== null ?
|
||||||
|
// Surround description with div to allow text styling if the description is not html
|
||||||
|
<HTML html={"<div>" + displayData.description + "</div>"}
|
||||||
|
tagsStyles={{
|
||||||
|
p: {
|
||||||
|
color: ThemeManager.getCurrentThemeVariables().textColor,
|
||||||
|
fontSize: ThemeManager.getCurrentThemeVariables().fontSizeBase
|
||||||
|
},
|
||||||
|
div: {color: ThemeManager.getCurrentThemeVariables().textColor}
|
||||||
|
}}
|
||||||
|
onLinkPress={(event, link) => openWebLink(link)}/>
|
||||||
|
: <View/>}
|
||||||
|
</Content>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,16 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {BackHandler, Image, View} from 'react-native';
|
import {BackHandler, Image} from 'react-native';
|
||||||
import {Button, Content, H1, H3, Text} from 'native-base';
|
import {H3, Text, View} from 'native-base';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import ThemeManager from "../utils/ThemeManager";
|
import ThemeManager from "../utils/ThemeManager";
|
||||||
import {Linking} from "expo";
|
import {Linking} from "expo";
|
||||||
import BaseContainer from "../components/BaseContainer";
|
import BaseContainer from "../components/BaseContainer";
|
||||||
import {Agenda, LocaleConfig} from 'react-native-calendars';
|
import {Agenda, LocaleConfig} from 'react-native-calendars';
|
||||||
import HTML from 'react-native-render-html';
|
|
||||||
import Touchable from 'react-native-platform-touchable';
|
import Touchable from 'react-native-platform-touchable';
|
||||||
import {Modalize} from 'react-native-modalize';
|
|
||||||
import WebDataManager from "../utils/WebDataManager";
|
import WebDataManager from "../utils/WebDataManager";
|
||||||
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
import PlanningEventManager from '../utils/PlanningEventManager';
|
||||||
|
|
||||||
LocaleConfig.locales['fr'] = {
|
LocaleConfig.locales['fr'] = {
|
||||||
monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
|
monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
|
||||||
|
@ -28,7 +26,6 @@ type Props = {
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
modalCurrentDisplayItem: Object,
|
|
||||||
refreshing: boolean,
|
refreshing: boolean,
|
||||||
agendaItems: Object,
|
agendaItems: Object,
|
||||||
calendarShowing: boolean,
|
calendarShowing: boolean,
|
||||||
|
@ -51,7 +48,6 @@ function openWebLink(link) {
|
||||||
*/
|
*/
|
||||||
export default class PlanningScreen extends React.Component<Props, State> {
|
export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
modalRef: Modalize;
|
|
||||||
agendaRef: Agenda;
|
agendaRef: Agenda;
|
||||||
webDataManager: WebDataManager;
|
webDataManager: WebDataManager;
|
||||||
|
|
||||||
|
@ -61,7 +57,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
didFocusSubscription: Function;
|
didFocusSubscription: Function;
|
||||||
willBlurSubscription: Function;
|
willBlurSubscription: Function;
|
||||||
state = {
|
state = {
|
||||||
modalCurrentDisplayItem: {},
|
|
||||||
refreshing: false,
|
refreshing: false,
|
||||||
agendaItems: {},
|
agendaItems: {},
|
||||||
calendarShowing: false,
|
calendarShowing: false,
|
||||||
|
@ -69,7 +64,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
this.modalRef = React.createRef();
|
|
||||||
this.webDataManager = new WebDataManager(FETCH_URL);
|
this.webDataManager = new WebDataManager(FETCH_URL);
|
||||||
this.didFocusSubscription = props.navigation.addListener(
|
this.didFocusSubscription = props.navigation.addListener(
|
||||||
'didFocus',
|
'didFocus',
|
||||||
|
@ -131,72 +125,11 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
return daysOfYear;
|
return daysOfYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
getModalHeader() {
|
|
||||||
return (
|
|
||||||
<View style={{marginBottom: 0}}>
|
|
||||||
<Button
|
|
||||||
onPress={() => this.modalRef.current.close()}
|
|
||||||
style={{
|
|
||||||
marginTop: 50,
|
|
||||||
marginLeft: 'auto',
|
|
||||||
}}
|
|
||||||
transparent>
|
|
||||||
<CustomMaterialIcon icon={'close'}/>
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getModalContent() {
|
|
||||||
return (
|
|
||||||
<View style={{
|
|
||||||
flex: 1,
|
|
||||||
padding: 20
|
|
||||||
}}>
|
|
||||||
<H1>
|
|
||||||
{this.state.modalCurrentDisplayItem.title}
|
|
||||||
</H1>
|
|
||||||
<H3 style={{
|
|
||||||
marginTop: 10,
|
|
||||||
color: ThemeManager.getCurrentThemeVariables().listNoteColor
|
|
||||||
}}>
|
|
||||||
{this.getFormattedTime(this.state.modalCurrentDisplayItem)}
|
|
||||||
</H3>
|
|
||||||
<Content>
|
|
||||||
{this.state.modalCurrentDisplayItem.logo !== null ?
|
|
||||||
<View style={{width: '100%', height: 200, marginTop: 20, marginBottom: 20}}>
|
|
||||||
<Image style={{flex: 1, resizeMode: "contain"}}
|
|
||||||
source={{uri: this.state.modalCurrentDisplayItem.logo}}/>
|
|
||||||
</View>
|
|
||||||
: <View/>}
|
|
||||||
|
|
||||||
{this.state.modalCurrentDisplayItem.description !== null ?
|
|
||||||
// Surround description with div to allow text styling if the description is not html
|
|
||||||
<HTML html={"<div>" + this.state.modalCurrentDisplayItem.description + "</div>"}
|
|
||||||
tagsStyles={{
|
|
||||||
p: {
|
|
||||||
color: ThemeManager.getCurrentThemeVariables().textColor,
|
|
||||||
fontSize: ThemeManager.getCurrentThemeVariables().fontSizeBase
|
|
||||||
},
|
|
||||||
div: {color: ThemeManager.getCurrentThemeVariables().textColor}
|
|
||||||
}}
|
|
||||||
onLinkPress={(event, link) => openWebLink(link)}/>
|
|
||||||
: <View/>}
|
|
||||||
</Content>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
showItemDetails(item: Object) {
|
|
||||||
this.setState({
|
|
||||||
modalCurrentDisplayItem: item,
|
|
||||||
});
|
|
||||||
if (this.modalRef.current) {
|
|
||||||
this.modalRef.current.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getRenderItem(item: Object) {
|
getRenderItem(item: Object) {
|
||||||
|
let navData = {
|
||||||
|
data: item
|
||||||
|
};
|
||||||
|
const nav = this.props.navigation;
|
||||||
return (
|
return (
|
||||||
<Touchable
|
<Touchable
|
||||||
style={{
|
style={{
|
||||||
|
@ -205,7 +138,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
marginRight: 10,
|
marginRight: 10,
|
||||||
marginTop: 17,
|
marginTop: 17,
|
||||||
}}
|
}}
|
||||||
onPress={() => this.showItemDetails(item)}>
|
onPress={() => nav.navigate('PlanningDisplayScreen', navData)}>
|
||||||
<View style={{
|
<View style={{
|
||||||
padding: 10,
|
padding: 10,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
@ -219,7 +152,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
marginBottom: 10
|
marginBottom: 10
|
||||||
}}>
|
}}>
|
||||||
{this.getFormattedTime(item)}
|
{PlanningEventManager.getFormattedTime(item)}
|
||||||
</Text>
|
</Text>
|
||||||
<H3 style={{marginBottom: 10}}>{item.title}</H3>
|
<H3 style={{marginBottom: 10}}>{item.title}</H3>
|
||||||
</View>
|
</View>
|
||||||
|
@ -296,8 +229,8 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
generateEventAgenda(eventList: Array<Object>) {
|
generateEventAgenda(eventList: Array<Object>) {
|
||||||
let agendaItems = this.generateEmptyCalendar();
|
let agendaItems = this.generateEmptyCalendar();
|
||||||
for (let i = 0; i < eventList.length; i++) {
|
for (let i = 0; i < eventList.length; i++) {
|
||||||
if (agendaItems[this.getEventStartDate(eventList[i])] !== undefined) {
|
if (agendaItems[PlanningEventManager.getEventStartDate(eventList[i])] !== undefined) {
|
||||||
this.pushEventInOrder(agendaItems, eventList[i], this.getEventStartDate(eventList[i]));
|
this.pushEventInOrder(agendaItems, eventList[i], PlanningEventManager.getEventStartDate(eventList[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setState({agendaItems: agendaItems})
|
this.setState({agendaItems: agendaItems})
|
||||||
|
@ -308,7 +241,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
agendaItems[startDate].push(event);
|
agendaItems[startDate].push(event);
|
||||||
else {
|
else {
|
||||||
for (let i = 0; i < agendaItems[startDate].length; i++) {
|
for (let i = 0; i < agendaItems[startDate].length; i++) {
|
||||||
if (this.isEventBefore(event, agendaItems[startDate][i])) {
|
if (PlanningEventManager.isEventBefore(event, agendaItems[startDate][i])) {
|
||||||
agendaItems[startDate].splice(i, 0, event);
|
agendaItems[startDate].splice(i, 0, event);
|
||||||
break;
|
break;
|
||||||
} else if (i === agendaItems[startDate].length - 1) {
|
} else if (i === agendaItems[startDate].length - 1) {
|
||||||
|
@ -319,65 +252,10 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isEventBefore(event1: Object, event2: Object) {
|
|
||||||
let date1 = new Date();
|
|
||||||
let date2 = new Date();
|
|
||||||
let timeArray = this.getEventStartTime(event1).split(":");
|
|
||||||
date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
|
||||||
timeArray = this.getEventStartTime(event2).split(":");
|
|
||||||
date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
|
||||||
return date1 < date2;
|
|
||||||
}
|
|
||||||
|
|
||||||
getEventStartDate(event: Object) {
|
|
||||||
return event.date_begin.split(" ")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
getEventStartTime(event: Object) {
|
|
||||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null)
|
|
||||||
return this.formatTime(event.date_begin.split(" ")[1]);
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
getEventEndTime(event: Object) {
|
|
||||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null)
|
|
||||||
return this.formatTime(event.date_end.split(" ")[1]);
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
getFormattedTime(event: Object) {
|
|
||||||
if (this.getEventEndTime(event) !== "")
|
|
||||||
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event);
|
|
||||||
else
|
|
||||||
return this.getEventStartTime(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
formatTime(time: string) {
|
|
||||||
let array = time.split(':');
|
|
||||||
return array[0] + ':' + array[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
onModalClosed() {
|
|
||||||
this.setState({
|
|
||||||
modalCurrentDisplayItem: {},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const nav = this.props.navigation;
|
const nav = this.props.navigation;
|
||||||
return (
|
return (
|
||||||
<BaseContainer navigation={nav} headerTitle={i18n.t('screens.planning')}>
|
<BaseContainer navigation={nav} headerTitle={i18n.t('screens.planning')}>
|
||||||
<Modalize ref={this.modalRef}
|
|
||||||
modalStyle={{
|
|
||||||
backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor,
|
|
||||||
}}
|
|
||||||
// adjustToContentHeight // Breaks when displaying full screen, half, then full again
|
|
||||||
HeaderComponent={() => this.getModalHeader()}
|
|
||||||
onClosed={() => this.onModalClosed()}>
|
|
||||||
{this.getModalContent()}
|
|
||||||
</Modalize>
|
|
||||||
<Agenda
|
<Agenda
|
||||||
// the list of items that have to be displayed in agenda. If you want to render item as empty date
|
// the list of items that have to be displayed in agenda. If you want to render item as empty date
|
||||||
// the value of date key kas to be an empty array []. If there exists no value for date key it is
|
// the value of date key kas to be an empty array []. If there exists no value for date key it is
|
||||||
|
@ -431,14 +309,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
agendaDayNumColor: ThemeManager.getCurrentThemeVariables().listNoteColor,
|
agendaDayNumColor: ThemeManager.getCurrentThemeVariables().listNoteColor,
|
||||||
agendaTodayColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
|
agendaTodayColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
|
||||||
agendaKnobColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
|
agendaKnobColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
|
||||||
// Fix for days hiding behind knob
|
|
||||||
'stylesheet.calendar.header': {
|
|
||||||
week: {
|
|
||||||
marginTop: 0,
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"screens": {
|
"screens": {
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
"planning": "Planning",
|
"planning": "Planning",
|
||||||
|
"planningDisplayScreen": "Event Details",
|
||||||
"proxiwash": "Proxiwash",
|
"proxiwash": "Proxiwash",
|
||||||
"proximo": "Proximo",
|
"proximo": "Proximo",
|
||||||
"menuSelf": "RU Menu",
|
"menuSelf": "RU Menu",
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"screens": {
|
"screens": {
|
||||||
"home": "Accueil",
|
"home": "Accueil",
|
||||||
"planning": "Planning",
|
"planning": "Planning",
|
||||||
|
"planningDisplayScreen": "Détails",
|
||||||
"proxiwash": "Proxiwash",
|
"proxiwash": "Proxiwash",
|
||||||
"proximo": "Proximo",
|
"proximo": "Proximo",
|
||||||
"menuSelf": "Menu du RU",
|
"menuSelf": "Menu du RU",
|
||||||
|
|
42
utils/PlanningEventManager.js
Normal file
42
utils/PlanningEventManager.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
export default class PlanningEventManager {
|
||||||
|
static isEventBefore(event1: Object, event2: Object) {
|
||||||
|
let date1 = new Date();
|
||||||
|
let date2 = new Date();
|
||||||
|
let timeArray = this.getEventStartTime(event1).split(":");
|
||||||
|
date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||||
|
timeArray = this.getEventStartTime(event2).split(":");
|
||||||
|
date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||||
|
return date1 < date2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getEventStartDate(event: Object) {
|
||||||
|
return event.date_begin.split(" ")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getEventStartTime(event: Object) {
|
||||||
|
if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null)
|
||||||
|
return this.formatTime(event.date_begin.split(" ")[1]);
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static getEventEndTime(event: Object) {
|
||||||
|
if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null)
|
||||||
|
return this.formatTime(event.date_end.split(" ")[1]);
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static getFormattedTime(event: Object) {
|
||||||
|
if (this.getEventEndTime(event) !== "")
|
||||||
|
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event);
|
||||||
|
else
|
||||||
|
return this.getEventStartTime(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static formatTime(time: string) {
|
||||||
|
let array = time.split(':');
|
||||||
|
return array[0] + ':' + array[1];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue