forked from vergnet/application-amicale
Improved proxiwash screen + show help banner on proxiwash and planex
This commit is contained in:
parent
24ad1076a0
commit
7f7ae68664
8 changed files with 197 additions and 64 deletions
|
@ -1,5 +1,5 @@
|
|||
import * as React from 'react';
|
||||
import {Divider, List, Text, withTheme} from 'react-native-paper';
|
||||
import {Card, Avatar, List, Text, withTheme} from 'react-native-paper';
|
||||
import {View} from "react-native";
|
||||
import ProxiwashConstants from "../constants/ProxiwashConstants";
|
||||
|
||||
|
@ -13,27 +13,48 @@ function ProxiwashListItem(props) {
|
|||
stateColors[ProxiwashConstants.machineStates.ERREUR] = colors.proxiwashErrorColor;
|
||||
const icon = (
|
||||
props.isWatched ?
|
||||
<List.Icon icon={'bell-ring'} color={colors.primary}/> :
|
||||
<List.Icon icon={props.isDryer ? 'tumble-dryer' : 'washing-machine'}/>
|
||||
<Avatar.Icon
|
||||
icon={'bell-ring'}
|
||||
size={45}
|
||||
color={colors.primary}
|
||||
style={{backgroundColor: 'transparent'}}
|
||||
/> :
|
||||
<Avatar.Icon
|
||||
icon={props.isDryer ? 'tumble-dryer' : 'washing-machine'}
|
||||
color={colors.text}
|
||||
size={40}
|
||||
style={{backgroundColor: 'transparent'}}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<View style={{
|
||||
backgroundColor:
|
||||
ProxiwashConstants.machineStates[props.state] === ProxiwashConstants.machineStates["EN COURS"] ?
|
||||
colors.proxiwashRunningBgColor :
|
||||
colors.background
|
||||
}}>
|
||||
<View style={{
|
||||
<Card
|
||||
style={{
|
||||
margin: 5,
|
||||
}}
|
||||
onPress={props.onPress}
|
||||
>
|
||||
{ProxiwashConstants.machineStates[props.state] === ProxiwashConstants.machineStates["EN COURS"] ?
|
||||
<Card style={{
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
width: '100%',
|
||||
backgroundColor: colors.proxiwashRunningBgColor,
|
||||
elevation: 0
|
||||
}}/> : null
|
||||
}
|
||||
|
||||
<Card style={{
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
width: props.progress,
|
||||
backgroundColor: stateColors[ProxiwashConstants.machineStates[props.state]]
|
||||
backgroundColor: stateColors[ProxiwashConstants.machineStates[props.state]],
|
||||
elevation: 0
|
||||
}}/>
|
||||
<List.Item
|
||||
<Card.Title
|
||||
title={props.title}
|
||||
description={props.description}
|
||||
onPress={props.onPress}
|
||||
subtitle={props.description}
|
||||
style={{
|
||||
backgroundColor: 'transparent',
|
||||
height: 64
|
||||
|
@ -52,14 +73,15 @@ function ProxiwashListItem(props) {
|
|||
</Text>
|
||||
</View>
|
||||
|
||||
<List.Icon
|
||||
color={colors.text}
|
||||
<Avatar.Icon
|
||||
icon={props.statusIcon}
|
||||
color={colors.text}
|
||||
size={30}
|
||||
style={{backgroundColor: 'transparent'}}
|
||||
/>
|
||||
</View>)}
|
||||
/>
|
||||
<Divider/>
|
||||
</View>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ export default class WebSectionList extends React.Component<Props, State> {
|
|||
render() {
|
||||
let dataset = this.props.createDataset(this.state.fetchedData);
|
||||
const isEmpty = dataset[0].data.length === 0;
|
||||
const shouldRenderHeader = !isEmpty || (this.props.renderSectionHeader !== null);
|
||||
const shouldRenderHeader = !isEmpty && (this.props.renderSectionHeader !== null);
|
||||
if (isEmpty)
|
||||
dataset = this.createEmptyDataset();
|
||||
return (
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
|
||||
import * as React from 'react';
|
||||
import {Alert, Platform, View} from 'react-native';
|
||||
import ThemeManager from '../../utils/ThemeManager';
|
||||
import i18n from "i18n-js";
|
||||
import WebSectionList from "../../components/WebSectionList";
|
||||
import NotificationsManager from "../../utils/NotificationsManager";
|
||||
import AsyncStorageManager from "../../utils/AsyncStorageManager";
|
||||
import * as Expo from "expo";
|
||||
import {Divider, IconButton, List, Text, Title} from 'react-native-paper';
|
||||
import {Card, Banner, Avatar} from 'react-native-paper';
|
||||
import HeaderButton from "../../components/HeaderButton";
|
||||
import ProxiwashListItem from "../../components/ProxiwashListItem";
|
||||
import ProxiwashConstants from "../../constants/ProxiwashConstants";
|
||||
|
@ -30,6 +29,7 @@ type State = {
|
|||
firstLoading: boolean,
|
||||
fetchedData: Object,
|
||||
machinesWatched: Array<string>,
|
||||
bannerVisible: boolean,
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,6 +43,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
|
|||
getRenderItem: Function;
|
||||
getRenderSectionHeader: Function;
|
||||
createDataset: Function;
|
||||
onHideBanner: Function;
|
||||
|
||||
state = {
|
||||
refreshing: false,
|
||||
|
@ -50,6 +51,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
|
|||
fetchedData: {},
|
||||
// machinesWatched: JSON.parse(dataString),
|
||||
machinesWatched: [],
|
||||
bannerVisible: AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.current === '1',
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -80,6 +82,15 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
|
|||
this.getRenderItem = this.getRenderItem.bind(this);
|
||||
this.getRenderSectionHeader = this.getRenderSectionHeader.bind(this);
|
||||
this.createDataset = this.createDataset.bind(this);
|
||||
this.onHideBanner = this.onHideBanner.bind(this);
|
||||
}
|
||||
|
||||
onHideBanner() {
|
||||
this.setState({bannerVisible: false});
|
||||
AsyncStorageManager.getInstance().savePref(
|
||||
AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.key,
|
||||
'0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -280,6 +291,22 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
|
|||
render() {
|
||||
const nav = this.props.navigation;
|
||||
return (
|
||||
<View>
|
||||
<Banner
|
||||
visible={this.state.bannerVisible}
|
||||
actions={[
|
||||
{
|
||||
label: 'OK',
|
||||
onPress: this.onHideBanner,
|
||||
},
|
||||
]}
|
||||
icon={() => <Avatar.Icon
|
||||
icon={'information'}
|
||||
size={40}
|
||||
/>}
|
||||
>
|
||||
{i18n.t('proxiwashScreen.enableNotificationsTip')}
|
||||
</Banner>
|
||||
<WebSectionList
|
||||
createDataset={this.createDataset}
|
||||
navigation={nav}
|
||||
|
@ -287,17 +314,34 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
|
|||
fetchUrl={DATA_URL}
|
||||
renderItem={this.getRenderItem}
|
||||
renderSectionHeader={this.getRenderSectionHeader}/>
|
||||
</View>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
getRenderSectionHeader({section}: Object) {
|
||||
return (
|
||||
<Title style={{
|
||||
marginTop: 10,
|
||||
textAlign: 'center'
|
||||
<Card style={{
|
||||
width: '80%',
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
marginBottom: 10,
|
||||
marginTop: 20,
|
||||
}}>
|
||||
{section.title}
|
||||
</Title>
|
||||
<Card.Title
|
||||
title={section.title}
|
||||
// subtitle={''} // TODO display num available
|
||||
titleStyle={{
|
||||
textAlign: 'center'
|
||||
}}
|
||||
subtitleStyle={{
|
||||
textAlign: 'center'
|
||||
}}
|
||||
style={{
|
||||
paddingLeft: 0,
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,19 @@
|
|||
import * as React from 'react';
|
||||
import ThemeManager from "../../utils/ThemeManager";
|
||||
import WebViewScreen from "../../components/WebViewScreen";
|
||||
import {Avatar, Banner} from "react-native-paper";
|
||||
import i18n from "i18n-js";
|
||||
import {View} from "react-native";
|
||||
import AsyncStorageManager from "../../utils/AsyncStorageManager";
|
||||
|
||||
type Props = {
|
||||
navigation: Object,
|
||||
}
|
||||
|
||||
type State = {
|
||||
bannerVisible: boolean,
|
||||
}
|
||||
|
||||
|
||||
const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
|
||||
|
||||
|
@ -75,9 +83,11 @@ const OBSERVE_MUTATIONS_INJECTED =
|
|||
* Class defining the app's planex screen.
|
||||
* This screen uses a webview to render the planex page
|
||||
*/
|
||||
export default class PlanexScreen extends React.Component<Props> {
|
||||
export default class PlanexScreen extends React.Component<Props, State> {
|
||||
|
||||
customInjectedJS: string;
|
||||
onHideBanner: Function;
|
||||
onGoToSettings: Function;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -93,12 +103,55 @@ export default class PlanexScreen extends React.Component<Props> {
|
|||
this.customInjectedJS +=
|
||||
'removeAlpha();' +
|
||||
'});true;'; // Prevent crash on ios
|
||||
this.onHideBanner = this.onHideBanner.bind(this);
|
||||
this.onGoToSettings = this.onGoToSettings.bind(this);
|
||||
}
|
||||
|
||||
state = {
|
||||
bannerVisible:
|
||||
AsyncStorageManager.getInstance().preferences.planexShowBanner.current === '1' &&
|
||||
AsyncStorageManager.getInstance().preferences.defaultStartScreen.current !== 'Planex',
|
||||
};
|
||||
|
||||
onHideBanner() {
|
||||
this.setState({bannerVisible: false});
|
||||
AsyncStorageManager.getInstance().savePref(
|
||||
AsyncStorageManager.getInstance().preferences.planexShowBanner.key,
|
||||
'0'
|
||||
);
|
||||
}
|
||||
|
||||
onGoToSettings() {
|
||||
this.onHideBanner();
|
||||
this.props.navigation.navigate('SettingsScreen');
|
||||
}
|
||||
|
||||
render() {
|
||||
const nav = this.props.navigation;
|
||||
return (
|
||||
<View style={{
|
||||
height: '100%'
|
||||
}}>
|
||||
<Banner
|
||||
visible={this.state.bannerVisible}
|
||||
actions={[
|
||||
{
|
||||
label: i18n.t('planexScreen.enableStartOK'),
|
||||
onPress: this.onGoToSettings,
|
||||
},
|
||||
{
|
||||
label: i18n.t('planexScreen.enableStartCancel'),
|
||||
onPress: this.onHideBanner,
|
||||
},
|
||||
|
||||
]}
|
||||
icon={() => <Avatar.Icon
|
||||
icon={'information'}
|
||||
size={40}
|
||||
/>}
|
||||
>
|
||||
{i18n.t('planexScreen.enableStartScreen')}
|
||||
</Banner>
|
||||
<WebViewScreen
|
||||
navigation={nav}
|
||||
data={[
|
||||
|
@ -113,6 +166,7 @@ export default class PlanexScreen extends React.Component<Props> {
|
|||
headerTitle={'Planex'}
|
||||
hasHeaderBackButton={false}
|
||||
hasFooter={false}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,6 +160,7 @@
|
|||
"dryerTips": "The advised dryer length is 35 minutes for 14 kg of laundry. You can choose a shorter length if the dryer is not fully charged.",
|
||||
"procedure": "Procedure",
|
||||
"tips": "Tips",
|
||||
"enableNotificationsTip": "Click on a running machine to enable notifications",
|
||||
"modal": {
|
||||
"enableNotifications": "Notify me",
|
||||
"disableNotifications": "Stop notifications",
|
||||
|
@ -188,8 +189,9 @@
|
|||
}
|
||||
},
|
||||
"planexScreen": {
|
||||
"rotateToLandscape": "Turn your screen to see the whole week",
|
||||
"rotateToPortrait": "Turn your screen to see only 2 days"
|
||||
"enableStartScreen": "Come here often? Set it as default screen!",
|
||||
"enableStartOK": "Yes please!",
|
||||
"enableStartCancel": "Later"
|
||||
},
|
||||
"availableRoomScreen": {
|
||||
"normalRoom": "Work",
|
||||
|
|
|
@ -160,7 +160,7 @@
|
|||
"dryerTips": "La durée conseillée est de 35 minutes pour 14kg de linge. Vous pouvez choisir une durée plus courte si le sèche-linge n'est pas chargé.",
|
||||
"procedure": "Procédure",
|
||||
"tips": "Conseils",
|
||||
|
||||
"enableNotificationsTip": "Cliquez sur une machine en cours pour activer les notifications",
|
||||
"modal": {
|
||||
"enableNotifications": "Me Notifier",
|
||||
"disableNotifications": "Désactiver les notifications",
|
||||
|
@ -190,8 +190,9 @@
|
|||
}
|
||||
},
|
||||
"planexScreen": {
|
||||
"rotateToLandscape": "Tournez votre téléphone pour voir la semaine entière",
|
||||
"rotateToPortrait": "Tournez votre téléphone pour voir seulement 2 jours"
|
||||
"enableStartScreen": "Vous venez souvent ici ? Démarrez l'appli sur cette page!",
|
||||
"enableStartOK": "Oui svp!",
|
||||
"enableStartCancel": "Plus tard"
|
||||
},
|
||||
"availableRoomScreen": {
|
||||
"normalRoom": "Travail",
|
||||
|
|
|
@ -63,7 +63,17 @@ export default class AsyncStorageManager {
|
|||
key: 'defaultStartScreen',
|
||||
default: 'Home',
|
||||
current: '',
|
||||
}
|
||||
},
|
||||
proxiwashShowBanner: {
|
||||
key: 'proxiwashShowBanner',
|
||||
default: '1',
|
||||
current: '',
|
||||
},
|
||||
planexShowBanner: {
|
||||
key: 'planexShowBanner',
|
||||
default: '1',
|
||||
current: '',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,12 +35,12 @@ export default class ThemeManager {
|
|||
agendaDayTextColor: '#636363',
|
||||
|
||||
// PROXIWASH
|
||||
proxiwashFinishedColor: "rgba(54,165,22,0.31)",
|
||||
proxiwashFinishedColor: "#a5dc9d",
|
||||
proxiwashReadyColor: "transparent",
|
||||
proxiwashRunningColor: "rgba(94,104,241,0.3)",
|
||||
proxiwashRunningBgColor: "rgba(99,109,255,0.14)",
|
||||
proxiwashBrokenColor: "rgba(162,162,162,0.31)",
|
||||
proxiwashErrorColor: "rgba(204,7,0,0.31)",
|
||||
proxiwashRunningColor: "#a0ceff",
|
||||
proxiwashRunningBgColor: "#c7e3ff",
|
||||
proxiwashBrokenColor: "#8e8e8e",
|
||||
proxiwashErrorColor: "rgba(204,7,0,0.31)#e35f57",
|
||||
|
||||
// Screens
|
||||
planningColor: '#d9b10a',
|
||||
|
@ -72,12 +72,12 @@ export default class ThemeManager {
|
|||
agendaDayTextColor: '#6d6d6d',
|
||||
|
||||
// PROXIWASH
|
||||
proxiwashFinishedColor: "rgba(17,149,32,0.53)",
|
||||
proxiwashFinishedColor: "#31682c",
|
||||
proxiwashReadyColor: "transparent",
|
||||
proxiwashRunningColor: "rgba(29,59,175,0.65)",
|
||||
proxiwashRunningBgColor: "rgba(99,109,255,0.14)",
|
||||
proxiwashBrokenColor: "#000000",
|
||||
proxiwashErrorColor: "rgba(213,8,0,0.57)",
|
||||
proxiwashRunningColor: "#213c79",
|
||||
proxiwashRunningBgColor: "#1a2033",
|
||||
proxiwashBrokenColor: "#656565",
|
||||
proxiwashErrorColor: "#7e2e2f",
|
||||
|
||||
// Screens
|
||||
planningColor: '#d99e09',
|
||||
|
|
Loading…
Reference in a new issue