Added tabbed webview for available rooms

This commit is contained in:
keplyx 2019-11-08 02:37:38 +01:00
parent 8b132ccc91
commit 1da41c1fd1
8 changed files with 163 additions and 46 deletions

View file

@ -2,7 +2,7 @@
import * as React from 'react'; import * as React from 'react';
import {Linking, Platform, View} from 'react-native'; import {Linking, Platform, View} from 'react-native';
import {Spinner, Footer, Right, Left, Body} from 'native-base'; import {Spinner, Footer, Right, Left, Body, Tab, TabHeading, Text, Tabs} from 'native-base';
import WebView from "react-native-webview"; import WebView from "react-native-webview";
import Touchable from "react-native-platform-touchable"; import Touchable from "react-native-platform-touchable";
import CustomMaterialIcon from "../components/CustomMaterialIcon"; import CustomMaterialIcon from "../components/CustomMaterialIcon";
@ -11,8 +11,12 @@ import BaseContainer from "../components/BaseContainer";
type Props = { type Props = {
navigation: Object, navigation: Object,
url: string, data: Array<{
customInjectedJS: string, url: string,
icon: string,
name: string,
customJS: string
}>,
headerTitle: string, headerTitle: string,
hasHeaderBackButton: boolean, hasHeaderBackButton: boolean,
hasSideMenu: boolean, hasSideMenu: boolean,
@ -25,16 +29,15 @@ type Props = {
export default class WebViewScreen extends React.Component<Props> { export default class WebViewScreen extends React.Component<Props> {
static defaultProps = { static defaultProps = {
customInjectedJS: '',
hasBackButton: false, hasBackButton: false,
hasSideMenu: true, hasSideMenu: true,
hasFooter: true, hasFooter: true,
}; };
webview: WebView; webviewArray: Array<WebView> = [];
openWebLink() { openWebLink(url: string) {
Linking.openURL(this.props.url).catch((err) => console.error('Error opening link', err)); Linking.openURL(url).catch((err) => console.error('Error opening link', err));
} }
getHeaderButton(clickAction: Function, icon: string) { getHeaderButton(clickAction: Function, icon: string) {
@ -58,15 +61,73 @@ export default class WebViewScreen extends React.Component<Props> {
}; };
refreshWebview() { refreshWebview() {
this.webview.reload(); for (let view of this.webviewArray) {
view.reload();
}
} }
goBackWebview() { goBackWebview() {
this.webview.goBack(); for (let view of this.webviewArray) {
view.goBack();
}
} }
goForwardWebview() { goForwardWebview() {
this.webview.goForward(); for (let view of this.webviewArray) {
view.goForward();
}
}
getWebview(obj: Object) {
return (
<WebView
ref={ref => (this.webviewArray.push(ref))}
source={{uri: obj['url']}}
style={{
width: '100%',
height: '100%',
}}
startInLoadingState={true}
injectedJavaScript={obj['customJS']}
javaScriptEnabled={true}
renderLoading={() =>
<View style={{
backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor,
position: 'absolute',
top: 0,
right: 0,
width: '100%',
height: '100%',
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Spinner/>
</View>
}
/>
);
}
getTabbedWebview() {
let tabbedView = [];
for (let i = 0; i < this.props.data.length; i++) {
tabbedView.push(
<Tab heading={
<TabHeading>
<CustomMaterialIcon
icon={this.props.data[i]['icon']}
color={ThemeManager.getCurrentThemeVariables().tabIconColor}
fontSize={20}
/>
<Text>{this.props.data[i]['name']}</Text>
</TabHeading>}
key={this.props.data[i]['url']}
style={{backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor}}>
{this.getWebview(this.props.data[i])}
</Tab>);
}
return tabbedView;
} }
render() { render() {
@ -78,38 +139,22 @@ export default class WebViewScreen extends React.Component<Props> {
headerRightButton={this.getRefreshButton()} headerRightButton={this.getRefreshButton()}
hasBackButton={this.props.hasHeaderBackButton} hasBackButton={this.props.hasHeaderBackButton}
hasSideMenu={this.props.hasSideMenu}> hasSideMenu={this.props.hasSideMenu}>
<WebView {this.props.data.length === 1 ?
ref={ref => (this.webview = ref)} this.getWebview(this.props.data[0]) :
source={{uri: this.props.url}} <Tabs
style={{ tabContainerStyle={{
width: '100%', elevation: 0, // Fix for android shadow
height: '100%', }}
}} locked={true}
startInLoadingState={true} >
injectedJavaScript={this.props.customInjectedJS} {this.getTabbedWebview()}
javaScriptEnabled={true} </Tabs>}
renderLoading={() => {this.props.hasFooter && this.props.data.length === 1 ?
<View style={{
backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor,
position: 'absolute',
top: 0,
right: 0,
width: '100%',
height: '100%',
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}>
<Spinner/>
</View>
}
/>
{this.props.hasFooter ?
<Footer> <Footer>
<Left style={{ <Left style={{
paddingLeft: 6, paddingLeft: 6,
}}> }}>
{this.getHeaderButton(() => this.openWebLink(), 'open-in-new')} {this.getHeaderButton(() => this.openWebLink(this.props.data[0]['url']), 'open-in-new')}
</Left> </Left>
<Body/> <Body/>
<Right style={{ <Right style={{

View file

@ -22,7 +22,14 @@ export default class AmicaleScreen extends React.Component<Props> {
return ( return (
<WebViewScreen <WebViewScreen
navigation={nav} navigation={nav}
url={URL} data={[
{
url: URL,
icon: '',
name: '',
customJS: ''
},
]}
headerTitle={'Amicale'} headerTitle={'Amicale'}
hasHeaderBackButton={true} hasHeaderBackButton={true}
hasSideMenu={false}/> hasSideMenu={false}/>

View file

@ -9,7 +9,11 @@ type Props = {
} }
const URL = 'http://planex.insa-toulouse.fr/salles.php'; 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://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customMobile.css';
const CUSTOM_CSS_Bib = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customBibMobile.css';
/** /**
* Class defining the app's planex screen. * Class defining the app's planex screen.
@ -18,10 +22,20 @@ const URL = 'http://planex.insa-toulouse.fr/salles.php';
export default class AvailableRoomScreen extends React.Component<Props> { export default class AvailableRoomScreen extends React.Component<Props> {
customInjectedJS: string; customInjectedJS: string;
customBibInjectedJS: string;
constructor() { constructor() {
super(); super();
this.customInjectedJS = ''; 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>");' +
'$("thead").append(header);';
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"/>\';';
} }
render() { render() {
@ -29,11 +43,31 @@ export default class AvailableRoomScreen extends React.Component<Props> {
return ( return (
<WebViewScreen <WebViewScreen
navigation={nav} navigation={nav}
url={URL} data={[
{
url: ROOM_URL,
icon: 'file-document-outline',
name: i18n.t('availableRoomScreen.normalRoom'),
customJS: this.customInjectedJS
},
{
url: PC_URL,
icon: 'monitor',
name: i18n.t('availableRoomScreen.computerRoom'),
customJS: this.customInjectedJS
},
{
url: BIB_URL,
icon: 'book',
name: i18n.t('availableRoomScreen.bibRoom'),
customJS: this.customBibInjectedJS
},
]}
customInjectedJS={this.customInjectedJS} customInjectedJS={this.customInjectedJS}
headerTitle={i18n.t('screens.availableRooms')} headerTitle={i18n.t('screens.availableRooms')}
hasHeaderBackButton={true} hasHeaderBackButton={true}
hasSideMenu={false}/> hasSideMenu={false}
hasFooter={false}/>
); );
} }
} }

View file

@ -36,7 +36,14 @@ export default class PlanexScreen extends React.Component<Props> {
return ( return (
<WebViewScreen <WebViewScreen
navigation={nav} navigation={nav}
url={PLANEX_URL} data={[
{
url: PLANEX_URL,
icon: '',
name: '',
customJS: this.customInjectedJS
},
]}
customInjectedJS={this.customInjectedJS} customInjectedJS={this.customInjectedJS}
headerTitle={'Planex'} headerTitle={'Planex'}
hasHeaderBackButton={false} hasHeaderBackButton={false}

View file

@ -22,7 +22,14 @@ export default class TutorInsaScreen extends React.Component<Props> {
return ( return (
<WebViewScreen <WebViewScreen
navigation={nav} navigation={nav}
url={URL} data={[
{
url: URL,
icon: '',
name: '',
customJS: ''
},
]}
headerTitle={'Tutor\'INSA'} headerTitle={'Tutor\'INSA'}
hasHeaderBackButton={true} hasHeaderBackButton={true}
hasSideMenu={false}/> hasSideMenu={false}/>

View file

@ -22,7 +22,14 @@ export default class WiketudScreen extends React.Component<Props> {
return ( return (
<WebViewScreen <WebViewScreen
navigation={nav} navigation={nav}
url={URL} data={[
{
url: URL,
icon: '',
name: '',
customJS: ''
},
]}
headerTitle={'Wiketud'} headerTitle={'Wiketud'}
hasHeaderBackButton={true} hasHeaderBackButton={true}
hasSideMenu={false}/> hasSideMenu={false}/>

View file

@ -182,6 +182,11 @@
"machineRunningBody": "The machine n°{{number}} is still running" "machineRunningBody": "The machine n°{{number}} is still running"
} }
}, },
"availableRoomScreen": {
"normalRoom": "Work",
"computerRoom": "Computer",
"bibRoom": "Bib'Box"
},
"general": { "general": {
"loading": "Loading...", "loading": "Loading...",
"networkError": "Unable to contact servers. Make sure you are connected to Internet." "networkError": "Unable to contact servers. Make sure you are connected to Internet."

View file

@ -184,6 +184,11 @@
"machineRunningBody": "La machine n°{{number}} n'est pas encore terminée" "machineRunningBody": "La machine n°{{number}} n'est pas encore terminée"
} }
}, },
"availableRoomScreen": {
"normalRoom": "Travail",
"computerRoom": "Ordi",
"bibRoom": "Bib'Box"
},
"general": { "general": {
"loading": "Chargement...", "loading": "Chargement...",
"networkError": "Impossible de contacter les serveurs. Assurez vous d'être connecté à internet." "networkError": "Impossible de contacter les serveurs. Assurez vous d'être connecté à internet."