Improved proxiwash screen + show help banner on proxiwash and planex

This commit is contained in:
keplyx 2020-03-08 00:05:41 +01:00
parent 24ad1076a0
commit 7f7ae68664
8 changed files with 197 additions and 64 deletions

View file

@ -1,5 +1,5 @@
import * as React from 'react'; 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 {View} from "react-native";
import ProxiwashConstants from "../constants/ProxiwashConstants"; import ProxiwashConstants from "../constants/ProxiwashConstants";
@ -13,27 +13,48 @@ function ProxiwashListItem(props) {
stateColors[ProxiwashConstants.machineStates.ERREUR] = colors.proxiwashErrorColor; stateColors[ProxiwashConstants.machineStates.ERREUR] = colors.proxiwashErrorColor;
const icon = ( const icon = (
props.isWatched ? props.isWatched ?
<List.Icon icon={'bell-ring'} color={colors.primary}/> : <Avatar.Icon
<List.Icon icon={props.isDryer ? 'tumble-dryer' : 'washing-machine'}/> 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 ( return (
<View style={{ <Card
backgroundColor: style={{
ProxiwashConstants.machineStates[props.state] === ProxiwashConstants.machineStates["EN COURS"] ? margin: 5,
colors.proxiwashRunningBgColor : }}
colors.background onPress={props.onPress}
}}> >
<View style={{ {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%', height: '100%',
position: 'absolute', position: 'absolute',
left: 0, left: 0,
width: props.progress, width: props.progress,
backgroundColor: stateColors[ProxiwashConstants.machineStates[props.state]] backgroundColor: stateColors[ProxiwashConstants.machineStates[props.state]],
elevation: 0
}}/> }}/>
<List.Item <Card.Title
title={props.title} title={props.title}
description={props.description} subtitle={props.description}
onPress={props.onPress}
style={{ style={{
backgroundColor: 'transparent', backgroundColor: 'transparent',
height: 64 height: 64
@ -52,14 +73,15 @@ function ProxiwashListItem(props) {
</Text> </Text>
</View> </View>
<List.Icon <Avatar.Icon
color={colors.text}
icon={props.statusIcon} icon={props.statusIcon}
color={colors.text}
size={30}
style={{backgroundColor: 'transparent'}}
/> />
</View>)} </View>)}
/> />
<Divider/> </Card>
</View>
); );
} }

View file

@ -187,7 +187,7 @@ export default class WebSectionList extends React.Component<Props, State> {
render() { render() {
let dataset = this.props.createDataset(this.state.fetchedData); let dataset = this.props.createDataset(this.state.fetchedData);
const isEmpty = dataset[0].data.length === 0; const isEmpty = dataset[0].data.length === 0;
const shouldRenderHeader = !isEmpty || (this.props.renderSectionHeader !== null); const shouldRenderHeader = !isEmpty && (this.props.renderSectionHeader !== null);
if (isEmpty) if (isEmpty)
dataset = this.createEmptyDataset(); dataset = this.createEmptyDataset();
return ( return (

View file

@ -2,13 +2,12 @@
import * as React from 'react'; import * as React from 'react';
import {Alert, Platform, View} from 'react-native'; import {Alert, Platform, View} from 'react-native';
import ThemeManager from '../../utils/ThemeManager';
import i18n from "i18n-js"; import i18n from "i18n-js";
import WebSectionList from "../../components/WebSectionList"; import WebSectionList from "../../components/WebSectionList";
import NotificationsManager from "../../utils/NotificationsManager"; import NotificationsManager from "../../utils/NotificationsManager";
import AsyncStorageManager from "../../utils/AsyncStorageManager"; import AsyncStorageManager from "../../utils/AsyncStorageManager";
import * as Expo from "expo"; 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 HeaderButton from "../../components/HeaderButton";
import ProxiwashListItem from "../../components/ProxiwashListItem"; import ProxiwashListItem from "../../components/ProxiwashListItem";
import ProxiwashConstants from "../../constants/ProxiwashConstants"; import ProxiwashConstants from "../../constants/ProxiwashConstants";
@ -30,6 +29,7 @@ type State = {
firstLoading: boolean, firstLoading: boolean,
fetchedData: Object, fetchedData: Object,
machinesWatched: Array<string>, machinesWatched: Array<string>,
bannerVisible: boolean,
}; };
@ -43,6 +43,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
getRenderItem: Function; getRenderItem: Function;
getRenderSectionHeader: Function; getRenderSectionHeader: Function;
createDataset: Function; createDataset: Function;
onHideBanner: Function;
state = { state = {
refreshing: false, refreshing: false,
@ -50,6 +51,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
fetchedData: {}, fetchedData: {},
// machinesWatched: JSON.parse(dataString), // machinesWatched: JSON.parse(dataString),
machinesWatched: [], 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.getRenderItem = this.getRenderItem.bind(this);
this.getRenderSectionHeader = this.getRenderSectionHeader.bind(this); this.getRenderSectionHeader = this.getRenderSectionHeader.bind(this);
this.createDataset = this.createDataset.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,24 +291,57 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
render() { render() {
const nav = this.props.navigation; const nav = this.props.navigation;
return ( return (
<WebSectionList <View>
createDataset={this.createDataset} <Banner
navigation={nav} visible={this.state.bannerVisible}
refreshTime={REFRESH_TIME} actions={[
fetchUrl={DATA_URL} {
renderItem={this.getRenderItem} label: 'OK',
renderSectionHeader={this.getRenderSectionHeader}/> onPress: this.onHideBanner,
},
]}
icon={() => <Avatar.Icon
icon={'information'}
size={40}
/>}
>
{i18n.t('proxiwashScreen.enableNotificationsTip')}
</Banner>
<WebSectionList
createDataset={this.createDataset}
navigation={nav}
refreshTime={REFRESH_TIME}
fetchUrl={DATA_URL}
renderItem={this.getRenderItem}
renderSectionHeader={this.getRenderSectionHeader}/>
</View>
); );
} }
getRenderSectionHeader({section}: Object) { getRenderSectionHeader({section}: Object) {
return ( return (
<Title style={{ <Card style={{
marginTop: 10, width: '80%',
textAlign: 'center' marginLeft: 'auto',
marginRight: 'auto',
marginBottom: 10,
marginTop: 20,
}}> }}>
{section.title} <Card.Title
</Title> title={section.title}
// subtitle={''} // TODO display num available
titleStyle={{
textAlign: 'center'
}}
subtitleStyle={{
textAlign: 'center'
}}
style={{
paddingLeft: 0,
}}
/>
</Card>
); );
} }

View file

@ -3,11 +3,19 @@
import * as React from 'react'; import * as React from 'react';
import ThemeManager from "../../utils/ThemeManager"; import ThemeManager from "../../utils/ThemeManager";
import WebViewScreen from "../../components/WebViewScreen"; 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 = { type Props = {
navigation: Object, navigation: Object,
} }
type State = {
bannerVisible: boolean,
}
const PLANEX_URL = 'http://planex.insa-toulouse.fr/'; const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
@ -75,9 +83,11 @@ const OBSERVE_MUTATIONS_INJECTED =
* Class defining the app's planex screen. * Class defining the app's planex screen.
* This screen uses a webview to render the planex page * 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; customInjectedJS: string;
onHideBanner: Function;
onGoToSettings: Function;
constructor() { constructor() {
super(); super();
@ -93,26 +103,70 @@ export default class PlanexScreen extends React.Component<Props> {
this.customInjectedJS += this.customInjectedJS +=
'removeAlpha();' + 'removeAlpha();' +
'});true;'; // Prevent crash on ios '});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() { render() {
const nav = this.props.navigation; const nav = this.props.navigation;
return ( return (
<WebViewScreen <View style={{
navigation={nav} height: '100%'
data={[ }}>
{ <Banner
url: PLANEX_URL, visible={this.state.bannerVisible}
icon: '', actions={[
name: '', {
customJS: this.customInjectedJS label: i18n.t('planexScreen.enableStartOK'),
}, onPress: this.onGoToSettings,
]} },
customInjectedJS={this.customInjectedJS} {
headerTitle={'Planex'} label: i18n.t('planexScreen.enableStartCancel'),
hasHeaderBackButton={false} onPress: this.onHideBanner,
hasFooter={false}/> },
]}
icon={() => <Avatar.Icon
icon={'information'}
size={40}
/>}
>
{i18n.t('planexScreen.enableStartScreen')}
</Banner>
<WebViewScreen
navigation={nav}
data={[
{
url: PLANEX_URL,
icon: '',
name: '',
customJS: this.customInjectedJS
},
]}
customInjectedJS={this.customInjectedJS}
headerTitle={'Planex'}
hasHeaderBackButton={false}
hasFooter={false}/>
</View>
); );
} }
} }

View file

@ -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.", "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", "procedure": "Procedure",
"tips": "Tips", "tips": "Tips",
"enableNotificationsTip": "Click on a running machine to enable notifications",
"modal": { "modal": {
"enableNotifications": "Notify me", "enableNotifications": "Notify me",
"disableNotifications": "Stop notifications", "disableNotifications": "Stop notifications",
@ -188,8 +189,9 @@
} }
}, },
"planexScreen": { "planexScreen": {
"rotateToLandscape": "Turn your screen to see the whole week", "enableStartScreen": "Come here often? Set it as default screen!",
"rotateToPortrait": "Turn your screen to see only 2 days" "enableStartOK": "Yes please!",
"enableStartCancel": "Later"
}, },
"availableRoomScreen": { "availableRoomScreen": {
"normalRoom": "Work", "normalRoom": "Work",

View file

@ -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é.", "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", "procedure": "Procédure",
"tips": "Conseils", "tips": "Conseils",
"enableNotificationsTip": "Cliquez sur une machine en cours pour activer les notifications",
"modal": { "modal": {
"enableNotifications": "Me Notifier", "enableNotifications": "Me Notifier",
"disableNotifications": "Désactiver les notifications", "disableNotifications": "Désactiver les notifications",
@ -190,8 +190,9 @@
} }
}, },
"planexScreen": { "planexScreen": {
"rotateToLandscape": "Tournez votre téléphone pour voir la semaine entière", "enableStartScreen": "Vous venez souvent ici ? Démarrez l'appli sur cette page!",
"rotateToPortrait": "Tournez votre téléphone pour voir seulement 2 jours" "enableStartOK": "Oui svp!",
"enableStartCancel": "Plus tard"
}, },
"availableRoomScreen": { "availableRoomScreen": {
"normalRoom": "Travail", "normalRoom": "Travail",

View file

@ -63,7 +63,17 @@ export default class AsyncStorageManager {
key: 'defaultStartScreen', key: 'defaultStartScreen',
default: 'Home', default: 'Home',
current: '', current: '',
} },
proxiwashShowBanner: {
key: 'proxiwashShowBanner',
default: '1',
current: '',
},
planexShowBanner: {
key: 'planexShowBanner',
default: '1',
current: '',
},
}; };
/** /**

View file

@ -35,12 +35,12 @@ export default class ThemeManager {
agendaDayTextColor: '#636363', agendaDayTextColor: '#636363',
// PROXIWASH // PROXIWASH
proxiwashFinishedColor: "rgba(54,165,22,0.31)", proxiwashFinishedColor: "#a5dc9d",
proxiwashReadyColor: "transparent", proxiwashReadyColor: "transparent",
proxiwashRunningColor: "rgba(94,104,241,0.3)", proxiwashRunningColor: "#a0ceff",
proxiwashRunningBgColor: "rgba(99,109,255,0.14)", proxiwashRunningBgColor: "#c7e3ff",
proxiwashBrokenColor: "rgba(162,162,162,0.31)", proxiwashBrokenColor: "#8e8e8e",
proxiwashErrorColor: "rgba(204,7,0,0.31)", proxiwashErrorColor: "rgba(204,7,0,0.31)#e35f57",
// Screens // Screens
planningColor: '#d9b10a', planningColor: '#d9b10a',
@ -72,12 +72,12 @@ export default class ThemeManager {
agendaDayTextColor: '#6d6d6d', agendaDayTextColor: '#6d6d6d',
// PROXIWASH // PROXIWASH
proxiwashFinishedColor: "rgba(17,149,32,0.53)", proxiwashFinishedColor: "#31682c",
proxiwashReadyColor: "transparent", proxiwashReadyColor: "transparent",
proxiwashRunningColor: "rgba(29,59,175,0.65)", proxiwashRunningColor: "#213c79",
proxiwashRunningBgColor: "rgba(99,109,255,0.14)", proxiwashRunningBgColor: "#1a2033",
proxiwashBrokenColor: "#000000", proxiwashBrokenColor: "#656565",
proxiwashErrorColor: "rgba(213,8,0,0.57)", proxiwashErrorColor: "#7e2e2f",
// Screens // Screens
planningColor: '#d99e09', planningColor: '#d99e09',