Use React navigation header

This commit is contained in:
keplyx 2020-03-06 09:12:56 +01:00
parent 14960794bc
commit 79eaefab88
21 changed files with 659 additions and 732 deletions

View file

@ -1,83 +0,0 @@
// @flow
import * as React from 'react';
import {Container} from "native-base";
import CustomHeader from "./CustomHeader";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import {Platform, View} from "react-native";
import ThemeManager from "../utils/ThemeManager";
import Touchable from "react-native-platform-touchable";
type Props = {
navigation: Object,
headerTitle: string,
headerSubtitle: string,
headerRightButton: React.Node,
children: React.Node,
hasTabs: boolean,
hasBackButton: boolean,
hasSideMenu: boolean,
enableRotation: boolean,
hideHeaderOnLandscape: boolean,
}
type State = {
isHeaderVisible: boolean
}
export default class BaseContainer extends React.Component<Props, State> {
static defaultProps = {
headerRightButton: <View/>,
hasTabs: false,
hasBackButton: false,
hasSideMenu: true,
enableRotation: false,
hideHeaderOnLandscape: false,
headerSubtitle: '',
};
state = {
isHeaderVisible: true,
};
onDrawerPress: Function;
constructor() {
super();
this.onDrawerPress = this.onDrawerPress.bind(this);
}
onDrawerPress() {
this.props.navigation.toggleDrawer();
}
render() {
// console.log("rendering BaseContainer");
return (
<Container>
{this.state.isHeaderVisible ?
<CustomHeader
navigation={this.props.navigation}
title={this.props.headerTitle}
subtitle={this.props.headerSubtitle}
leftButton={
<Touchable
style={{padding: 6}}
onPress={this.onDrawerPress}>
<MaterialCommunityIcons
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
size={26}
name="menu"/>
</Touchable>
}
rightButton={this.props.headerRightButton}
hasTabs={this.props.hasTabs}
hasBackButton={this.props.hasBackButton}/>
: <View/>}
{this.props.children}
</Container>
);
}
}

View file

@ -1,150 +0,0 @@
// @flow
import * as React from "react";
import {Body, Header, Input, Item, Left, Right, Subtitle, 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';
import ThemeManager from "../utils/ThemeManager";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import i18n from "i18n-js";
type Props = {
hasBackButton: boolean,
hasSearchField: boolean,
searchCallback: Function,
shouldFocusSearchBar: boolean,
leftButton: React.Node,
rightButton: React.Node,
title: string,
subtitle: string,
navigation: Object,
hasTabs: boolean,
};
/**
* Custom component defining a header using native base
*
* @prop hasBackButton {boolean} Whether to show a back button or a burger menu. Use burger if unspecified
* @prop rightMenu {React.Node} Element to place at the right of the header. Use nothing if unspecified
* @prop title {string} This header title
* @prop navigation {Object} The navigation object from react navigation
*/
export default class CustomHeader extends React.Component<Props> {
static defaultProps = {
hasBackButton: false,
hasSearchField: false,
searchCallback: null,
shouldFocusSearchBar: false,
title: '',
subtitle: '',
leftButton: <View/>,
rightButton: <View/>,
hasTabs: false,
};
onPressBack: Function;
constructor() {
super();
this.onPressBack = this.onPressBack.bind(this);
}
shouldComponentUpdate(nextProps: Props): boolean {
return nextProps.title !== this.props.title ||
nextProps.subtitle !== this.props.subtitle ||
nextProps.hasBackButton !== this.props.hasBackButton ||
nextProps.hasSearchField !== this.props.hasSearchField ||
nextProps.shouldFocusSearchBar !== this.props.shouldFocusSearchBar ||
nextProps.hasTabs !== this.props.hasTabs ||
nextProps.rightButton !== this.props.rightButton ||
nextProps.leftButton !== this.props.leftButton;
}
componentDidMount() {
if (this.refs.searchInput !== undefined && this.refs.searchInput._root !== undefined && this.props.shouldFocusSearchBar) {
// does not work if called too early for some reason...
setTimeout(this.refs.searchInput._root.focus, 500);
}
}
getSearchBar() {
return (
<Body>
<Item
style={{
width: '100%',
marginBottom: 7
}}>
<MaterialCommunityIcons
name={'magnify'}
size={26}
color={ThemeManager.getCurrentThemeVariables().toolbarBtnColor}/>
<Input
ref="searchInput"
placeholder={i18n.t('proximoScreen.search')}
placeholderTextColor={ThemeManager.getCurrentThemeVariables().toolbarPlaceholderColor}
onChangeText={this.props.searchCallback}/>
</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>
);
}
onPressBack() {
this.props.navigation.goBack();
}
render() {
// console.log("rendering CustomHeader");
let button;
// Does the app have a back button or a burger menu ?
if (this.props.hasBackButton)
button =
<Touchable
style={{padding: 6}}
onPress={this.onPressBack}>
<MaterialCommunityIcons
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
name={Platform.OS === 'ios' ? 'chevron-left' : "arrow-left"}
size={26}/>
</Touchable>;
else
button = this.props.leftButton;
return (
<Header style={styles.header}
hasTabs={this.props.hasTabs}>
<Left style={{flex: 0}}>
{button}
</Left>
{this.props.hasSearchField ?
this.getSearchBar() :
this.getHeaderTitle()}
<Right style={{flex: this.props.hasSearchField ? 0 : 1}}>
{this.props.rightButton}
</Right>
</Header>);
}
};
// Fix header in status bar on Android
const styles = StyleSheet.create({
header: {
paddingTop: getStatusBarHeight(),
height: 54 + getStatusBarHeight(),
},
});

View file

@ -40,6 +40,42 @@ export default class SideBar extends React.Component<Props, State> {
super(props);
// Dataset used to render the drawer
this.dataSet = [
{
name: "Home",
route: "Main",
icon: "home",
},
{
name: i18n.t('sidenav.divider2'),
route: "Divider2"
},
{
name: i18n.t('screens.menuSelf'),
route: "SelfMenuScreen",
icon: "silverware-fork-knife",
},
{
name: i18n.t('screens.availableRooms'),
route: "AvailableRoomScreen",
icon: "calendar-check",
},
{
name: 'Bib',
route: "BibScreen",
icon: "book",
},
{
name: i18n.t('screens.bluemind'),
route: "BlueMindScreen",
link: "https://etud-mel.insa-toulouse.fr/webmail/",
icon: "email",
},
{
name: i18n.t('screens.ent'),
route: "EntScreen",
link: "https://ent.insa-toulouse.fr/",
icon: "notebook",
},
{
name: i18n.t('sidenav.divider1'),
route: "Divider1"
@ -68,32 +104,6 @@ export default class SideBar extends React.Component<Props, State> {
link: "https://www.etud.insa-toulouse.fr/~tutorinsa/",
icon: "school",
},
{
name: i18n.t('sidenav.divider2'),
route: "Divider2"
},
{
name: i18n.t('screens.bluemind'),
route: "BlueMindScreen",
link: "https://etud-mel.insa-toulouse.fr/webmail/",
icon: "email",
},
{
name: i18n.t('screens.ent'),
route: "EntScreen",
link: "https://ent.insa-toulouse.fr/",
icon: "notebook",
},
{
name: i18n.t('screens.availableRooms'),
route: "AvailableRoomScreen",
icon: "calendar-check",
},
{
name: i18n.t('screens.menuSelf'),
route: "SelfMenuScreen",
icon: "silverware-fork-knife",
},
{
name: i18n.t('sidenav.divider3'),
route: "Divider3"

View file

@ -1,13 +1,12 @@
// @flow
import * as React from 'react';
import {Linking, Platform, View} from 'react-native';
import {Body, Footer, Left, Right, Spinner, Tab, TabHeading, Tabs, Text} from 'native-base';
import {Platform, View} from 'react-native';
import {Container, Spinner, Tab, TabHeading, Tabs, Text} from 'native-base';
import WebView from "react-native-webview";
import Touchable from "react-native-platform-touchable";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import ThemeManager from "../utils/ThemeManager";
import BaseContainer from "../components/BaseContainer";
type Props = {
navigation: Object,
@ -50,8 +49,11 @@ export default class WebViewScreen extends React.Component<Props> {
this.onOpenWebLink = this.onOpenWebLink.bind(this);
}
openWebLink(url: string) {
Linking.openURL(url).catch((err) => console.error('Error opening link', err));
componentDidMount() {
const rightButton = this.getRefreshButton.bind(this);
this.props.navigation.setOptions({
headerRight: rightButton,
});
}
getHeaderButton(clickAction: Function, icon: string) {
@ -69,7 +71,10 @@ export default class WebViewScreen extends React.Component<Props> {
getRefreshButton() {
return (
<View style={{flexDirection: 'row'}}>
<View style={{
flexDirection: 'row',
marginRight: 10
}}>
{this.getHeaderButton(this.onRefreshClicked, 'refresh')}
</View>
);
@ -165,15 +170,7 @@ export default class WebViewScreen extends React.Component<Props> {
const nav = this.props.navigation;
this.webviewArray = [];
return (
<BaseContainer
navigation={nav}
headerTitle={this.props.headerTitle}
headerRightButton={this.getRefreshButton()}
hasBackButton={this.props.hasHeaderBackButton}
hasSideMenu={this.props.hasSideMenu}
enableRotation={true}
hideHeaderOnLandscape={true}
hasTabs={this.props.data.length > 1}>
<Container>
{this.props.data.length === 1 ?
this.getWebview(this.props.data[0]) :
<Tabs
@ -190,30 +187,7 @@ export default class WebViewScreen extends React.Component<Props> {
>
{this.getTabbedWebview()}
</Tabs>}
{this.props.hasFooter && this.props.data.length === 1 ?
<Footer>
<Left style={{
paddingLeft: 6,
}}>
{this.getHeaderButton(this.onOpenWebLink, 'open-in-new')}
</Left>
<Body/>
<Right style={{
flexDirection: 'row',
alignItems: 'flex-end',
paddingRight: 6
}}>
<View style={{
flexDirection: 'row',
marginRight: 0,
marginLeft: 'auto'
}}>
{this.getHeaderButton(this.onGoBackWebview, 'chevron-left')}
{this.getHeaderButton(this.onGoForwardWebview, 'chevron-right')}
</View>
</Right>
</Footer> : <View/>}
</BaseContainer>
</Container>
);
}
}

View file

@ -8,10 +8,52 @@ import AboutScreen from '../screens/About/AboutScreen';
import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen';
import SelfMenuScreen from '../screens/SelfMenuScreen';
import AvailableRoomScreen from "../screens/Websites/AvailableRoomScreen";
import BibScreen from "../screens/Websites/BibScreen";
import DebugScreen from '../screens/DebugScreen';
import Sidebar from "../components/Sidebar";
import {createStackNavigator, TransitionPresets} from "@react-navigation/stack";
import PerfHomeScreen from '../screens/PerfHomeScreen';
import {Platform, StyleSheet, View} from "react-native";
import ThemeManager from "../utils/ThemeManager";
import Touchable from "react-native-platform-touchable";
import {MaterialCommunityIcons} from "@expo/vector-icons";
const styles = StyleSheet.create({
header: {
backgroundColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
},
headerTitle: {
color: "#ffffff",
},
});
const defaultScreenOptions = {
headerTintColor: 'white',
headerStyle: styles.header,
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.SlideFromRightIOS,
};
function getDrawerButton(navigation: Object) {
return (
<View
style={{
flexDirection: 'row',
marginLeft: 10
}}>
<Touchable
style={{padding: 6}}
onPress={navigation.openDrawer}>
<MaterialCommunityIcons
name="menu"
size={26}
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}/>
</Touchable>
</View>
);
}
const AboutStack = createStackNavigator();
@ -19,30 +61,134 @@ function AboutStackComponent() {
return (
<AboutStack.Navigator
initialRouteName="AboutScreen"
mode='card'
headerMode="none"
screenOptions={{
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.SlideFromRightIOS,
}}
headerMode="float"
screenOptions={defaultScreenOptions}
>
<AboutStack.Screen
name="AboutScreen"
component={AboutScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'About',
headerLeft: openDrawer
};
}}
/>
<AboutStack.Screen
name="AboutDependenciesScreen"
component={AboutDependenciesScreen}
options={{
title: 'Dependencies'
}}
/>
<AboutStack.Screen
name="DebugScreen"
component={DebugScreen}
options={{
title: 'Debug'
}}
/>
</AboutStack.Navigator>
);
}
const SettingsStack = createStackNavigator();
function SettingsStackComponent() {
return (
<SettingsStack.Navigator
initialRouteName="SettingsScreen"
headerMode="float"
screenOptions={defaultScreenOptions}
>
<SettingsStack.Screen
name="SettingsScreen"
component={SettingsScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Settings',
headerLeft: openDrawer
};
}}
/>
</SettingsStack.Navigator>
);
}
const SelfMenuStack = createStackNavigator();
function SelfMenuStackComponent() {
return (
<SelfMenuStack.Navigator
initialRouteName="SelfMenuScreen"
headerMode="float"
screenOptions={defaultScreenOptions}
>
<SelfMenuStack.Screen
name="SelfMenuScreen"
component={SelfMenuScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Menu RU',
headerLeft: openDrawer
};
}}
/>
</SelfMenuStack.Navigator>
);
}
const AvailableRoomStack = createStackNavigator();
function AvailableRoomStackComponent() {
return (
<AvailableRoomStack.Navigator
initialRouteName="AvailableRoomScreen"
headerMode="float"
screenOptions={defaultScreenOptions}
>
<AvailableRoomStack.Screen
name="AvailableRoomScreen"
component={AvailableRoomScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Available Rooms',
headerLeft: openDrawer
};
}}
/>
</AvailableRoomStack.Navigator>
);
}
const BibStack = createStackNavigator();
function BibStackComponent() {
return (
<BibStack.Navigator
initialRouteName="BibScreen"
headerMode="float"
screenOptions={defaultScreenOptions}
>
<BibStack.Screen
name="BibScreen"
component={BibScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Bib',
headerLeft: openDrawer
};
}}
/>
</BibStack.Navigator>
);
}
const Drawer = createDrawerNavigator();
function getDrawerContent(nav) {
@ -53,13 +199,11 @@ export default function DrawerNavigator() {
return (
<Drawer.Navigator
initialRouteName={'Main'}
mode='card'
headerMode={'float'}
backBehavior={'initialRoute'}
drawerType={'back'}
drawerContent={props => getDrawerContent(props.navigation)}
screenOptions={{
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.SlideFromRightIOS,
}}
screenOptions={defaultScreenOptions}
>
<Drawer.Screen
name="Main"
@ -68,7 +212,7 @@ export default function DrawerNavigator() {
</Drawer.Screen>
<Drawer.Screen
name="SettingsScreen"
component={SettingsScreen}
component={SettingsStackComponent}
/>
<Drawer.Screen
name="AboutScreen"
@ -76,33 +220,16 @@ export default function DrawerNavigator() {
/>
<Drawer.Screen
name="SelfMenuScreen"
component={SelfMenuScreen}
component={SelfMenuStackComponent}
/>
<Drawer.Screen
name="AvailableRoomScreen"
component={AvailableRoomScreen}
component={AvailableRoomStackComponent}
/>
<Drawer.Screen
name="BibScreen"
component={BibStackComponent}
/>
</Drawer.Navigator>
);
}
const basicStack = createStackNavigator();
function DrawerNavigator1() {
return (
<basicStack.Navigator
initialRouteName={'Main'}
mode='card'
screenOptions={{
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.SlideFromRightIOS,
}}
>
<basicStack.Screen
name="Main"
component={TabNavigator}
/>
</basicStack.Navigator>
);
}

View file

@ -14,7 +14,7 @@ import PlanexScreen from '../screens/Websites/PlanexScreen';
import {MaterialCommunityIcons} from "@expo/vector-icons";
import ThemeManager from "../utils/ThemeManager";
import AsyncStorageManager from "../utils/AsyncStorageManager";
import {StyleSheet, View} from "react-native";
import {Platform, StyleSheet, View} from "react-native";
import Touchable from "react-native-platform-touchable";
const TAB_ICONS = {
@ -25,8 +25,6 @@ const TAB_ICONS = {
Planex: 'timetable',
};
const ProximoStack = createStackNavigator();
const styles = StyleSheet.create({
header: {
backgroundColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
@ -36,24 +34,50 @@ const styles = StyleSheet.create({
},
});
const defaultScreenOptions = {
headerTintColor: 'white',
headerStyle: styles.header,
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.SlideFromRightIOS,
};
function getDrawerButton(navigation: Object) {
return (
<View
style={{
flexDirection: 'row',
marginLeft: 10
}}>
<Touchable
style={{padding: 6}}
onPress={navigation.openDrawer}>
<MaterialCommunityIcons
name="menu"
size={26}
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}/>
</Touchable>
</View>
);
}
const ProximoStack = createStackNavigator();
function ProximoStackComponent() {
return (
<ProximoStack.Navigator
initialRouteName="ProximoMainScreen"
headerMode="float"
screenOptions={{
headerTintColor: 'white',
headerStyle: styles.header,
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.SlideFromRightIOS,
}}
screenOptions={defaultScreenOptions}
>
<ProximoStack.Screen
name="ProximoMainScreen"
options={{
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Proximo',
headerLeft: openDrawer
};
}}
component={ProximoMainScreen}
/>
@ -82,21 +106,27 @@ function ProxiwashStackComponent() {
return (
<ProxiwashStack.Navigator
initialRouteName="ProxiwashScreen"
mode='card'
headerMode="none"
screenOptions={{
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.ModalSlideFromBottomIOS,
}}
headerMode='float'
screenOptions={defaultScreenOptions}
>
<ProxiwashStack.Screen
name="ProxiwashScreen"
component={ProxiwashScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Proxiwash',
headerLeft: openDrawer
};
}}
/>
<ProxiwashStack.Screen
name="ProxiwashAboutScreen"
component={ProxiwashAboutScreen}
options={{
title: 'Proxiwash',
...TransitionPresets.ModalSlideFromBottomIOS,
}}
/>
</ProxiwashStack.Navigator>
);
@ -108,21 +138,27 @@ function PlanningStackComponent() {
return (
<PlanningStack.Navigator
initialRouteName="PlanningScreen"
mode='card'
headerMode="none"
screenOptions={{
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.ModalSlideFromBottomIOS,
}}
headerMode='float'
screenOptions={defaultScreenOptions}
>
<PlanningStack.Screen
name="PlanningScreen"
component={PlanningScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Planning',
headerLeft: openDrawer
};
}}
/>
<PlanningStack.Screen
name="PlanningDisplayScreen"
component={PlanningDisplayScreen}
options={{
title: 'Details',
...TransitionPresets.ModalSlideFromBottomIOS,
}}
/>
</PlanningStack.Navigator>
);
@ -134,26 +170,56 @@ function HomeStackComponent() {
return (
<HomeStack.Navigator
initialRouteName="HomeScreen"
mode='card'
headerMode="float"
screenOptions={{
gestureEnabled: true,
cardOverlayEnabled: true,
...TransitionPresets.ModalSlideFromBottomIOS,
}}
screenOptions={defaultScreenOptions}
>
<HomeStack.Screen
name="HomeScreen"
component={HomeScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Home',
headerLeft: openDrawer
};
}}
/>
<HomeStack.Screen
name="PlanningDisplayScreen"
component={PlanningDisplayScreen}
options={{
title: 'Details',
...TransitionPresets.ModalSlideFromBottomIOS,
}}
/>
</HomeStack.Navigator>
);
}
const PlanexStack = createStackNavigator();
function PlanexStackComponent() {
return (
<PlanexStack.Navigator
initialRouteName="HomeScreen"
headerMode="float"
screenOptions={defaultScreenOptions}
>
<PlanexStack.Screen
name="PlanexScreen"
component={PlanexScreen}
options={({navigation}) => {
const openDrawer = getDrawerButton.bind(this, navigation);
return {
title: 'Planex',
headerLeft: openDrawer
};
}}
/>
</PlanexStack.Navigator>
);
}
const Tab = createMaterialBottomTabNavigator();
export default function TabNavigator() {
@ -188,7 +254,7 @@ export default function TabNavigator() {
/>
<Tab.Screen
name="Planex"
component={PlanexScreen}
component={PlanexStackComponent}
/>
</Tab.Navigator>
);

View file

@ -1,10 +1,9 @@
// @flow
import * as React from 'react';
import {Body, Container, ListItem, Text} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import {Body, ListItem, Text} from 'native-base';
import {FlatList} from "react-native";
import i18n from "i18n-js";
import packageJson from '../../package';
function generateListFromObject(object) {
let list = [];
@ -17,7 +16,8 @@ function generateListFromObject(object) {
}
type Props = {
navigation: Object
navigation: Object,
route: Object
}
/**
@ -26,11 +26,8 @@ type Props = {
export default class AboutDependenciesScreen extends React.Component<Props> {
render() {
const nav = this.props.navigation;
const data = generateListFromObject(nav.getParam('data', {}));
const data = generateListFromObject(packageJson.dependencies);
return (
<Container>
<CustomHeader hasBackButton={true} navigation={nav} title={i18n.t('aboutScreen.libs')}/>
<FlatList
data={data}
keyExtractor={(item) => item.name}
@ -47,7 +44,6 @@ export default class AboutDependenciesScreen extends React.Component<Props> {
</Body>
</ListItem>}
/>
</Container>
);
}
}

View file

@ -2,11 +2,9 @@
import * as React from 'react';
import {FlatList, Linking, Platform, View} from 'react-native';
import {Body, Button, Card, CardItem, Container, H1, Left, Right, Text, Thumbnail} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import {Body, Button, Card, CardItem, Content, H1, Left, Right, Text, Thumbnail} from 'native-base';
import i18n from "i18n-js";
import appJson from '../../app';
import packageJson from '../../package';
import {MaterialCommunityIcons} from "@expo/vector-icons";
import AsyncStorageManager from "../../utils/AsyncStorageManager";
import {Modalize} from "react-native-modalize";
@ -169,7 +167,7 @@ export default class AboutScreen extends React.Component<Props, State> {
showChevron: true
},
{
onPressCallback: () => this.props.navigation.navigate('AboutDependenciesScreen', {data: packageJson.dependencies}),
onPressCallback: () => this.props.navigation.navigate('AboutDependenciesScreen'),
icon: 'developer-board',
text: i18n.t('aboutScreen.libs'),
showChevron: true
@ -391,11 +389,9 @@ export default class AboutScreen extends React.Component<Props, State> {
}
render() {
const nav = this.props.navigation;
return (
<Container>
<Content padder>
{this.getBugReportModal()}
<CustomHeader navigation={nav} title={i18n.t('screens.about')} hasBackButton={true}/>
<FlatList
style={{padding: 5}}
data={this.dataOrder}
@ -403,7 +399,7 @@ export default class AboutScreen extends React.Component<Props, State> {
keyExtractor={(item) => item.id}
renderItem={this.getMainCard}
/>
</Container>
</Content>
);
}
}

View file

@ -20,9 +20,7 @@ import {
Right,
Text
} from "native-base";
import CustomHeader from "../components/CustomHeader";
import ThemeManager from '../utils/ThemeManager';
import i18n from "i18n-js";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import {Alert, Clipboard, View} from "react-native";
import AsyncStorageManager from "../utils/AsyncStorageManager";
@ -150,7 +148,6 @@ export default class DebugScreen extends React.Component<Props, State> {
}
render() {
const nav = this.props.navigation;
return (
<Container>
<Modalize
@ -159,7 +156,6 @@ export default class DebugScreen extends React.Component<Props, State> {
modalStyle={{backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor}}>
{this.getModalContent()}
</Modalize>
<CustomHeader navigation={nav} title={i18n.t('screens.debug')} hasBackButton={true}/>
<Content padder>
<Card>
<CardItem header>

View file

@ -9,7 +9,6 @@ import Autolink from 'react-native-autolink';
import ThemeManager from "../utils/ThemeManager";
import DashboardItem from "../components/DashboardItem";
import * as WebBrowser from 'expo-web-browser';
import BaseContainer from "../components/BaseContainer";
import WebSectionList from "../components/WebSectionList";
// import DATA from "../dashboard_data.json";
@ -571,9 +570,6 @@ export default class HomeScreen extends React.Component<Props> {
render() {
const nav = this.props.navigation;
return (
<BaseContainer
navigation={nav}
headerTitle={i18n.t('screens.home')}>
<WebSectionList
createDataset={this.createDataset}
navigation={nav}
@ -581,7 +577,6 @@ export default class HomeScreen extends React.Component<Props> {
fetchUrl={DATA_URL}
renderItem={this.getRenderItem}
updateErrorText={i18n.t("homeScreen.listUpdateFail")}/>
</BaseContainer>
);
}
}

View file

@ -3,7 +3,6 @@
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";
@ -11,6 +10,7 @@ import PlanningEventManager from '../utils/PlanningEventManager';
type Props = {
navigation: Object,
route: Object
};
function openWebLink(event, link) {
@ -21,37 +21,33 @@ function openWebLink(event, link) {
* 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> {
displayData = this.props.route.params['data'];
render() {
// console.log("rendering planningDisplayScreen");
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}
{this.displayData.title}
</H1>
<H3 style={{
marginTop: 10,
color: ThemeManager.getCurrentThemeVariables().listNoteColor
}}>
{PlanningEventManager.getFormattedTime(displayData)}
{PlanningEventManager.getFormattedTime(this.displayData)}
</H3>
{displayData.logo !== null ?
{this.displayData.logo !== null ?
<View style={{width: '100%', height: 300, marginTop: 20, marginBottom: 20}}>
<Image style={{flex: 1, resizeMode: "contain"}}
source={{uri: displayData.logo}}/>
source={{uri: this.displayData.logo}}/>
</View>
: <View/>}
{displayData.description !== null ?
{this.displayData.description !== null ?
// Surround description with div to allow text styling if the description is not html
<HTML html={"<div>" + displayData.description + "</div>"}
<HTML html={"<div>" + this.displayData.description + "</div>"}
tagsStyles={{
p: {
color: ThemeManager.getCurrentThemeVariables().textColor,

View file

@ -5,7 +5,6 @@ import {BackHandler, Image} from 'react-native';
import {H3, Text, View} from 'native-base';
import i18n from "i18n-js";
import ThemeManager from "../utils/ThemeManager";
import BaseContainer from "../components/BaseContainer";
import {Agenda, LocaleConfig} from 'react-native-calendars';
import Touchable from 'react-native-platform-touchable';
import WebDataManager from "../utils/WebDataManager";
@ -61,6 +60,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
onAgendaRef: Function;
onCalendarToggled: Function;
onBackButtonPressAndroid: Function;
currentDate = this.getCurrentDate();
constructor(props: any) {
super(props);
@ -271,12 +271,9 @@ export default class PlanningScreen extends React.Component<Props, State> {
this.setState({calendarShowing: isCalendarOpened});
}
currentDate = this.getCurrentDate();
render() {
// console.log("rendering PlanningScreen");
return (
<BaseContainer navigation={this.props.navigation} headerTitle={i18n.t('screens.planning')}>
<Agenda
// 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
@ -330,7 +327,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
agendaKnobColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
}}
/>
</BaseContainer>
);
}
}

View file

@ -3,7 +3,6 @@
import * as React from 'react';
import {Image, View} from 'react-native';
import {Card, CardItem, Container, Content, H2, Left, Text} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import i18n from "i18n-js";
import {MaterialCommunityIcons} from "@expo/vector-icons";

View file

@ -1,8 +1,7 @@
// @flow
import * as React from 'react';
import {Body, Container, Content, H1, H3, Input, Item, Left, ListItem, Right, Text, Thumbnail} from 'native-base';
import CustomHeader from "../../components/CustomHeader";
import {Body, Content, H1, H3, Input, Item, Left, ListItem, Right, Text, Thumbnail} from 'native-base';
import {FlatList, Image, Platform, View} from "react-native";
import Touchable from 'react-native-platform-touchable';
import Menu, {MenuItem} from 'react-native-material-menu';
@ -387,7 +386,7 @@ export default class ProximoListScreen extends React.Component<Props, State> {
// console.log("rendering ProximoListScreen");
const nav = this.props.navigation;
return (
<Container>
<View>
<Modalize ref={this.modalRef}
adjustToContentHeight
modalStyle={{backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor}}>
@ -400,7 +399,7 @@ export default class ProximoListScreen extends React.Component<Props, State> {
style={{minHeight: 300, width: '100%'}}
renderItem={this.renderItem}
/>
</Container>
</View>
);
}
}

View file

@ -2,7 +2,7 @@
import * as React from 'react';
import {Platform, View} from 'react-native'
import {Body, Left, ListItem, Right, Text, Container} from 'native-base';
import {Body, Left, ListItem, Right, Text} from 'native-base';
import i18n from "i18n-js";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import ThemeManager from "../../utils/ThemeManager";
@ -40,14 +40,6 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
this.createDataset = this.createDataset.bind(this);
}
componentDidMount() {
const button = this.getRightButton.bind(this);
this.props.navigation.setOptions({
headerRight: button
,
});
}
static sortFinalData(a: Object, b: Object) {
let str1 = a.type.name.toLowerCase();
let str2 = b.type.name.toLowerCase();
@ -66,6 +58,13 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
return 0;
}
componentDidMount() {
const rightButton = this.getRightButton.bind(this);
this.props.navigation.setOptions({
headerRight: rightButton,
});
}
getKeyExtractor(item: Object) {
return item !== undefined ? item.type['id'] : undefined;
}
@ -180,6 +179,7 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
);
}
getRenderItem({item}: Object) {
let dataToSend = {
shouldFocusSearchBar: false,
@ -223,7 +223,6 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
render() {
const nav = this.props.navigation;
return (
<Container>
<WebSectionList
createDataset={this.createDataset}
navigation={nav}
@ -231,7 +230,6 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
fetchUrl={DATA_URL}
renderItem={this.getRenderItem}
updateErrorText={i18n.t("homeScreen.listUpdateFail")}/>
</Container>
);
}
}

View file

@ -2,8 +2,7 @@
import * as React from 'react';
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 {Body, Card, CardItem, Content, H2, H3, Left, Tab, TabHeading, Tabs, Text} from 'native-base';
import i18n from "i18n-js";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import ThemeManager from "../../utils/ThemeManager";
@ -18,17 +17,8 @@ type Props = {
export default class ProxiwashAboutScreen extends React.Component<Props> {
render() {
const nav = this.props.navigation;
return (
<Container>
<CustomHeader
navigation={nav} title={i18n.t('screens.proxiwash')}
hasBackButton={true}
hasTabs={true}/>
<Tabs
tabContainerStyle={{
elevation: 0, // Fix for android shadow
}}>
<Tabs>
<Tab
heading={
<TabHeading>
@ -151,7 +141,6 @@ export default class ProxiwashAboutScreen extends React.Component<Props> {
</Content>
</Tab>
</Tabs>
</Container>
);
}
}

View file

@ -12,7 +12,6 @@ import PlatformTouchable from "react-native-platform-touchable";
import Touchable from "react-native-platform-touchable";
import AsyncStorageManager from "../../utils/AsyncStorageManager";
import * as Expo from "expo";
import BaseContainer from "../../components/BaseContainer";
const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/washinsa/washinsa.json";
@ -102,6 +101,10 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
* Setup notification channel for android and add listeners to detect notifications fired
*/
componentDidMount() {
const rightButton = this.getRightButton.bind(this);
this.props.navigation.setOptions({
headerRight: rightButton,
});
if (AsyncStorageManager.getInstance().preferences.expoToken.current !== '') {
// Get latest watchlist from server
NotificationsManager.getMachineNotificationWatchlist((fetchedList) => {
@ -283,10 +286,13 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
this.props.navigation.navigate('ProxiwashAboutScreen');
}
getRightButton(): * {
getRightButton() {
return (
<Touchable
style={{padding: 6}}
style={{
padding: 6,
marginRight: 10
}}
onPress={this.onAboutPress}>
<MaterialCommunityIcons
color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}
@ -299,10 +305,6 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
render() {
const nav = this.props.navigation;
return (
<BaseContainer
navigation={nav}
headerTitle={i18n.t('screens.proxiwash')}
headerRightButton={this.getRightButton()}>
<WebSectionList
createDataset={this.createDataset}
navigation={nav}
@ -310,7 +312,6 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
fetchUrl={DATA_URL}
renderItem={this.getRenderItem}
updateErrorText={i18n.t("proxiwashScreen.listUpdateFail")}/>
</BaseContainer>
);
}

View file

@ -5,7 +5,6 @@ import {View} from 'react-native';
import {Card, CardItem, H2, H3, Text} from 'native-base';
import ThemeManager from "../utils/ThemeManager";
import i18n from "i18n-js";
import BaseContainer from "../components/BaseContainer";
import WebSectionList from "../components/WebSectionList";
const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json";
@ -95,7 +94,6 @@ export default class SelfMenuScreen extends React.Component<Props> {
}
getRenderSectionHeader({section}: Object) {
let title = "";
return (
<Card style={{
marginLeft: 10,
@ -164,10 +162,6 @@ export default class SelfMenuScreen extends React.Component<Props> {
render() {
const nav = this.props.navigation;
return (
<BaseContainer
navigation={nav}
headerTitle={i18n.t('screens.menuSelf')}
hasBackButton={true}>
<WebSectionList
createDataset={this.createDataset}
navigation={nav}
@ -177,7 +171,6 @@ export default class SelfMenuScreen extends React.Component<Props> {
renderSectionHeader={this.getRenderSectionHeader}
updateErrorText={i18n.t("homeScreen.listUpdateFail")}
stickyHeader={true}/>
</BaseContainer>
);
}
}

View file

@ -1,21 +1,7 @@
// @flow
import * as React from 'react';
import {
Body,
Card,
CardItem,
CheckBox,
Container,
Content,
Left,
List,
ListItem,
Picker,
Right,
Text,
} from "native-base";
import CustomHeader from "../components/CustomHeader";
import {Body, Card, CardItem, CheckBox, Content, Left, List, ListItem, Picker, Right, Text,} from "native-base";
import ThemeManager from '../utils/ThemeManager';
import i18n from "i18n-js";
import {NavigationActions, StackActions} from "@react-navigation/native";
@ -228,10 +214,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
}
render() {
const nav = this.props.navigation;
return (
<Container>
<CustomHeader navigation={nav} title={i18n.t('screens.settings')} hasBackButton={true}/>
<Content padder>
<Card>
<CardItem header>
@ -251,7 +234,6 @@ export default class SettingsScreen extends React.Component<Props, State> {
</List>
</Card>
</Content>
</Container>
);
}

View file

@ -11,9 +11,7 @@ type Props = {
const ROOM_URL = 'http://planex.insa-toulouse.fr/salles.php';
const PC_URL = 'http://planex.insa-toulouse.fr/sallesInfo.php';
const BIB_URL = 'https://bibbox.insa-toulouse.fr/';
const CUSTOM_CSS_GENERAL = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customMobile.css';
const CUSTOM_CSS_Bib = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customBibMobile.css';
/**
* Class defining the app's planex screen.
@ -32,17 +30,6 @@ export default class AvailableRoomScreen extends React.Component<Props> {
'let header = $(".table tbody tr:first");' +
'$("table").prepend("<thead></thead>");true;' + // Fix for crash on ios
'$("thead").append(header);true;';
this.customBibInjectedJS =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_Bib + '" type="text/css"/>\';' +
'if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)' +
'$(".hero-unit-form").append("' +
'<div style=\'width: 100%; display: flex\'>' +
'<a style=\'margin: auto\' href=\'' + BIB_URL + '\'>' +
'<button id=\'customBackButton\' class=\'btn btn-primary\'>Retour</button>' +
'</a>' +
'</div>");true;';
}
render() {
@ -63,12 +50,6 @@ export default class AvailableRoomScreen extends React.Component<Props> {
name: i18n.t('availableRoomScreen.computerRoom'),
customJS: this.customInjectedJS
},
{
url: BIB_URL,
icon: 'book',
name: i18n.t('availableRoomScreen.bibRoom'),
customJS: this.customBibInjectedJS
},
]}
customInjectedJS={this.customInjectedJS}
headerTitle={i18n.t('screens.availableRooms')}

View file

@ -0,0 +1,66 @@
// @flow
import * as React from 'react';
import WebViewScreen from "../../components/WebViewScreen";
import i18n from "i18n-js";
type Props = {
navigation: Object,
}
const BIB_URL = 'https://bibbox.insa-toulouse.fr/';
const CUSTOM_CSS_GENERAL = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customMobile.css';
const CUSTOM_CSS_Bib = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customBibMobile.css';
/**
* Class defining the app's planex screen.
* This screen uses a webview to render the planex page
*/
export default class AvailableRoomScreen extends React.Component<Props> {
customInjectedJS: string;
customBibInjectedJS: string;
constructor() {
super();
this.customInjectedJS =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\';' +
'let header = $(".table tbody tr:first");' +
'$("table").prepend("<thead></thead>");true;' + // Fix for crash on ios
'$("thead").append(header);true;';
this.customBibInjectedJS =
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_Bib + '" type="text/css"/>\';' +
'if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)' +
'$(".hero-unit-form").append("' +
'<div style=\'width: 100%; display: flex\'>' +
'<a style=\'margin: auto\' href=\'' + BIB_URL + '\'>' +
'<button id=\'customBackButton\' class=\'btn btn-primary\'>Retour</button>' +
'</a>' +
'</div>");true;';
}
render() {
const nav = this.props.navigation;
return (
<WebViewScreen
navigation={nav}
data={[
{
url: BIB_URL,
icon: 'book',
name: i18n.t('availableRoomScreen.bibRoom'),
customJS: this.customBibInjectedJS
},
]}
customInjectedJS={this.customInjectedJS}
headerTitle={i18n.t('screens.availableRooms')}
hasHeaderBackButton={true}
hasSideMenu={false}
hasFooter={false}/>
);
}
}