forked from vergnet/application-amicale
Added tabbed webview for available rooms
This commit is contained in:
parent
8b132ccc91
commit
1da41c1fd1
8 changed files with 163 additions and 46 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
import * as React from 'react';
|
||||
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 Touchable from "react-native-platform-touchable";
|
||||
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
||||
|
@ -11,8 +11,12 @@ import BaseContainer from "../components/BaseContainer";
|
|||
|
||||
type Props = {
|
||||
navigation: Object,
|
||||
url: string,
|
||||
customInjectedJS: string,
|
||||
data: Array<{
|
||||
url: string,
|
||||
icon: string,
|
||||
name: string,
|
||||
customJS: string
|
||||
}>,
|
||||
headerTitle: string,
|
||||
hasHeaderBackButton: boolean,
|
||||
hasSideMenu: boolean,
|
||||
|
@ -25,16 +29,15 @@ type Props = {
|
|||
export default class WebViewScreen extends React.Component<Props> {
|
||||
|
||||
static defaultProps = {
|
||||
customInjectedJS: '',
|
||||
hasBackButton: false,
|
||||
hasSideMenu: true,
|
||||
hasFooter: true,
|
||||
};
|
||||
|
||||
webview: WebView;
|
||||
webviewArray: Array<WebView> = [];
|
||||
|
||||
openWebLink() {
|
||||
Linking.openURL(this.props.url).catch((err) => console.error('Error opening link', err));
|
||||
openWebLink(url: string) {
|
||||
Linking.openURL(url).catch((err) => console.error('Error opening link', err));
|
||||
}
|
||||
|
||||
getHeaderButton(clickAction: Function, icon: string) {
|
||||
|
@ -58,15 +61,73 @@ export default class WebViewScreen extends React.Component<Props> {
|
|||
};
|
||||
|
||||
refreshWebview() {
|
||||
this.webview.reload();
|
||||
for (let view of this.webviewArray) {
|
||||
view.reload();
|
||||
}
|
||||
}
|
||||
|
||||
goBackWebview() {
|
||||
this.webview.goBack();
|
||||
for (let view of this.webviewArray) {
|
||||
view.goBack();
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -78,38 +139,22 @@ export default class WebViewScreen extends React.Component<Props> {
|
|||
headerRightButton={this.getRefreshButton()}
|
||||
hasBackButton={this.props.hasHeaderBackButton}
|
||||
hasSideMenu={this.props.hasSideMenu}>
|
||||
<WebView
|
||||
ref={ref => (this.webview = ref)}
|
||||
source={{uri: this.props.url}}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
startInLoadingState={true}
|
||||
injectedJavaScript={this.props.customInjectedJS}
|
||||
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>
|
||||
}
|
||||
/>
|
||||
{this.props.hasFooter ?
|
||||
{this.props.data.length === 1 ?
|
||||
this.getWebview(this.props.data[0]) :
|
||||
<Tabs
|
||||
tabContainerStyle={{
|
||||
elevation: 0, // Fix for android shadow
|
||||
}}
|
||||
locked={true}
|
||||
>
|
||||
{this.getTabbedWebview()}
|
||||
</Tabs>}
|
||||
{this.props.hasFooter && this.props.data.length === 1 ?
|
||||
<Footer>
|
||||
<Left style={{
|
||||
paddingLeft: 6,
|
||||
}}>
|
||||
{this.getHeaderButton(() => this.openWebLink(), 'open-in-new')}
|
||||
{this.getHeaderButton(() => this.openWebLink(this.props.data[0]['url']), 'open-in-new')}
|
||||
</Left>
|
||||
<Body/>
|
||||
<Right style={{
|
||||
|
|
|
@ -22,7 +22,14 @@ export default class AmicaleScreen extends React.Component<Props> {
|
|||
return (
|
||||
<WebViewScreen
|
||||
navigation={nav}
|
||||
url={URL}
|
||||
data={[
|
||||
{
|
||||
url: URL,
|
||||
icon: '',
|
||||
name: '',
|
||||
customJS: ''
|
||||
},
|
||||
]}
|
||||
headerTitle={'Amicale'}
|
||||
hasHeaderBackButton={true}
|
||||
hasSideMenu={false}/>
|
||||
|
|
|
@ -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.
|
||||
|
@ -18,10 +22,20 @@ const URL = 'http://planex.insa-toulouse.fr/salles.php';
|
|||
export default class AvailableRoomScreen extends React.Component<Props> {
|
||||
|
||||
customInjectedJS: string;
|
||||
customBibInjectedJS: string;
|
||||
|
||||
constructor() {
|
||||
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() {
|
||||
|
@ -29,11 +43,31 @@ export default class AvailableRoomScreen extends React.Component<Props> {
|
|||
return (
|
||||
<WebViewScreen
|
||||
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}
|
||||
headerTitle={i18n.t('screens.availableRooms')}
|
||||
hasHeaderBackButton={true}
|
||||
hasSideMenu={false}/>
|
||||
hasSideMenu={false}
|
||||
hasFooter={false}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,14 @@ export default class PlanexScreen extends React.Component<Props> {
|
|||
return (
|
||||
<WebViewScreen
|
||||
navigation={nav}
|
||||
url={PLANEX_URL}
|
||||
data={[
|
||||
{
|
||||
url: PLANEX_URL,
|
||||
icon: '',
|
||||
name: '',
|
||||
customJS: this.customInjectedJS
|
||||
},
|
||||
]}
|
||||
customInjectedJS={this.customInjectedJS}
|
||||
headerTitle={'Planex'}
|
||||
hasHeaderBackButton={false}
|
||||
|
|
|
@ -22,7 +22,14 @@ export default class TutorInsaScreen extends React.Component<Props> {
|
|||
return (
|
||||
<WebViewScreen
|
||||
navigation={nav}
|
||||
url={URL}
|
||||
data={[
|
||||
{
|
||||
url: URL,
|
||||
icon: '',
|
||||
name: '',
|
||||
customJS: ''
|
||||
},
|
||||
]}
|
||||
headerTitle={'Tutor\'INSA'}
|
||||
hasHeaderBackButton={true}
|
||||
hasSideMenu={false}/>
|
||||
|
|
|
@ -22,7 +22,14 @@ export default class WiketudScreen extends React.Component<Props> {
|
|||
return (
|
||||
<WebViewScreen
|
||||
navigation={nav}
|
||||
url={URL}
|
||||
data={[
|
||||
{
|
||||
url: URL,
|
||||
icon: '',
|
||||
name: '',
|
||||
customJS: ''
|
||||
},
|
||||
]}
|
||||
headerTitle={'Wiketud'}
|
||||
hasHeaderBackButton={true}
|
||||
hasSideMenu={false}/>
|
||||
|
|
|
@ -182,6 +182,11 @@
|
|||
"machineRunningBody": "The machine n°{{number}} is still running"
|
||||
}
|
||||
},
|
||||
"availableRoomScreen": {
|
||||
"normalRoom": "Work",
|
||||
"computerRoom": "Computer",
|
||||
"bibRoom": "Bib'Box"
|
||||
},
|
||||
"general": {
|
||||
"loading": "Loading...",
|
||||
"networkError": "Unable to contact servers. Make sure you are connected to Internet."
|
||||
|
|
|
@ -184,6 +184,11 @@
|
|||
"machineRunningBody": "La machine n°{{number}} n'est pas encore terminée"
|
||||
}
|
||||
},
|
||||
"availableRoomScreen": {
|
||||
"normalRoom": "Travail",
|
||||
"computerRoom": "Ordi",
|
||||
"bibRoom": "Bib'Box"
|
||||
},
|
||||
"general": {
|
||||
"loading": "Chargement...",
|
||||
"networkError": "Impossible de contacter les serveurs. Assurez vous d'être connecté à internet."
|
||||
|
|
Loading…
Reference in a new issue