Activate proxiwash notifications and see machine info on alert popup

This commit is contained in:
keplyx 2019-07-30 20:40:17 +02:00
parent b42ae421f5
commit 8fa2bd792f
8 changed files with 125 additions and 54 deletions

View file

@ -4,7 +4,7 @@ import * as React from 'react';
import WebDataManager from "../utils/WebDataManager"; import WebDataManager from "../utils/WebDataManager";
import {Container, Content, Tab, TabHeading, Tabs, Text} from "native-base"; import {Container, Content, Tab, TabHeading, Tabs, Text} from "native-base";
import CustomHeader from "./CustomHeader"; import CustomHeader from "./CustomHeader";
import {RefreshControl, SectionList, View} from "react-native"; import {RefreshControl, SectionList, View, TouchableHighlight} from "react-native";
import CustomMaterialIcon from "./CustomMaterialIcon"; import CustomMaterialIcon from "./CustomMaterialIcon";
type Props = { type Props = {
@ -15,16 +15,16 @@ type State = {
refreshing: boolean, refreshing: boolean,
firstLoading: boolean, firstLoading: boolean,
fetchedData: Object, fetchedData: Object,
machinesWatched: Array<Object> machinesWatched: Array<Object>,
}; };
export default class FetchedDataSectionList extends React.Component<Props, State> { export default class FetchedDataSectionList extends React.Component<Props, State> {
webDataManager: WebDataManager; webDataManager: WebDataManager;
constructor() { constructor(fetchUrl: string) {
super(); super();
this.webDataManager = new WebDataManager(this.getFetchUrl()); this.webDataManager = new WebDataManager(fetchUrl);
} }
state = { state = {
@ -34,10 +34,6 @@ export default class FetchedDataSectionList extends React.Component<Props, State
machinesWatched: [], machinesWatched: [],
}; };
getFetchUrl() {
return "";
}
getHeaderTranslation() { getHeaderTranslation() {
return "Header"; return "Header";
} }

17
package-lock.json generated
View file

@ -5935,6 +5935,14 @@
} }
} }
}, },
"react-native-animatable": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.2.tgz",
"integrity": "sha512-rmah3KQ63ft8DxkzFUwJSuZeq+oSYwldoGF4DTOR5WM2WR5wiWLgBAtrAHlI3Di3by323uOR21s+MlqPcHz2Kw==",
"requires": {
"prop-types": "^15.5.10"
}
},
"react-native-autolink": { "react-native-autolink": {
"version": "1.8.1", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/react-native-autolink/-/react-native-autolink-1.8.1.tgz", "resolved": "https://registry.npmjs.org/react-native-autolink/-/react-native-autolink-1.8.1.tgz",
@ -6034,6 +6042,15 @@
"prop-types": "^15.6.0" "prop-types": "^15.6.0"
} }
}, },
"react-native-modal": {
"version": "11.3.0",
"resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-11.3.0.tgz",
"integrity": "sha512-574hg0dF/gKY0jICg+D4j10F4fKQR8/u88DcVx82LU9QkuYokHr5Rn4E+BoaOUNf3BdNi1z9vzItMQEZa3M8rQ==",
"requires": {
"prop-types": "^15.6.2",
"react-native-animatable": "^1.3.1"
}
},
"react-native-platform-touchable": { "react-native-platform-touchable": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/react-native-platform-touchable/-/react-native-platform-touchable-1.1.1.tgz", "resolved": "https://registry.npmjs.org/react-native-platform-touchable/-/react-native-platform-touchable-1.1.1.tgz",

View file

@ -26,6 +26,7 @@
"react-native-hyperlink": "0.0.14", "react-native-hyperlink": "0.0.14",
"react-native-image-zoom-viewer": "^2.2.26", "react-native-image-zoom-viewer": "^2.2.26",
"react-native-lightbox": "^0.8.0", "react-native-lightbox": "^0.8.0",
"react-native-modal": "^11.3.0",
"react-native-platform-touchable": "^1.1.1", "react-native-platform-touchable": "^1.1.1",
"react-native-scalable-image": "^0.5.1", "react-native-scalable-image": "^0.5.1",
"react-native-status-bar-height": "^2.3.1", "react-native-status-bar-height": "^2.3.1",

View file

@ -26,6 +26,10 @@ function openWebLink(link) {
*/ */
export default class HomeScreen extends FetchedDataSectionList { export default class HomeScreen extends FetchedDataSectionList {
constructor() {
super(DATA_URL);
}
getHeaderTranslation() { getHeaderTranslation() {
return i18n.t("screens.home"); return i18n.t("screens.home");
} }
@ -51,10 +55,6 @@ export default class HomeScreen extends FetchedDataSectionList {
]; ];
} }
getFetchUrl() {
return DATA_URL;
}
/** /**
* Converts a dateString using Unix Timestamp to a formatted date * Converts a dateString using Unix Timestamp to a formatted date
* @param dateString {string} The Unix Timestamp representation of a date * @param dateString {string} The Unix Timestamp representation of a date

View file

@ -23,8 +23,8 @@ const typesIcons = {
*/ */
export default class ProximoMainScreen extends FetchedDataSectionList { export default class ProximoMainScreen extends FetchedDataSectionList {
getFetchUrl() { constructor() {
return DATA_URL; super(DATA_URL);
} }
getHeaderTranslation() { getHeaderTranslation() {

View file

@ -1,13 +1,15 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import {AsyncStorage, View} from 'react-native'; import {Alert, AsyncStorage, View} from 'react-native';
import {Body, Card, CardItem, H2, Left, Right, Text} from 'native-base'; import {Body, Card, CardItem, Left, Right, Text} from 'native-base';
import ThemeManager from '../utils/ThemeManager'; import ThemeManager from '../utils/ThemeManager';
import i18n from "i18n-js"; import i18n from "i18n-js";
import CustomMaterialIcon from "../components/CustomMaterialIcon"; import CustomMaterialIcon from "../components/CustomMaterialIcon";
import FetchedDataSectionList from "../components/FetchedDataSectionList"; import FetchedDataSectionList from "../components/FetchedDataSectionList";
import NotificationsManager from "../utils/NotificationsManager"; import NotificationsManager from "../utils/NotificationsManager";
import PlatformTouchable from "react-native-platform-touchable";
const DATA_URL = "https://etud.insa-toulouse.fr/~vergnet/appli-amicale/dataProxiwash.json"; const DATA_URL = "https://etud.insa-toulouse.fr/~vergnet/appli-amicale/dataProxiwash.json";
const WATCHED_MACHINES_PREFKEY = "proxiwash.watchedMachines"; const WATCHED_MACHINES_PREFKEY = "proxiwash.watchedMachines";
@ -23,6 +25,7 @@ const MACHINE_STATES = {
}; };
let stateStrings = {}; let stateStrings = {};
let modalStateStrings = {};
let stateIcons = {}; let stateIcons = {};
let stateColors = {}; let stateColors = {};
@ -44,7 +47,7 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
* Creates machine state parameters using current theme and translations * Creates machine state parameters using current theme and translations
*/ */
constructor() { constructor() {
super(); super(DATA_URL);
let colors = ThemeManager.getInstance().getCurrentThemeVariables(); let colors = ThemeManager.getInstance().getCurrentThemeVariables();
stateColors[MACHINE_STATES.TERMINE] = colors.proxiwashFinishedColor; stateColors[MACHINE_STATES.TERMINE] = colors.proxiwashFinishedColor;
stateColors[MACHINE_STATES.DISPONIBLE] = colors.proxiwashReadyColor; stateColors[MACHINE_STATES.DISPONIBLE] = colors.proxiwashReadyColor;
@ -58,6 +61,12 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
stateStrings[MACHINE_STATES.HS] = i18n.t('proxiwashScreen.states.broken'); stateStrings[MACHINE_STATES.HS] = i18n.t('proxiwashScreen.states.broken');
stateStrings[MACHINE_STATES.ERREUR] = i18n.t('proxiwashScreen.states.error'); stateStrings[MACHINE_STATES.ERREUR] = i18n.t('proxiwashScreen.states.error');
modalStateStrings[MACHINE_STATES.TERMINE] = i18n.t('proxiwashScreen.modal.finished');
modalStateStrings[MACHINE_STATES.DISPONIBLE] = i18n.t('proxiwashScreen.modal.ready');
modalStateStrings[MACHINE_STATES.FONCTIONNE] = i18n.t('proxiwashScreen.modal.running');
modalStateStrings[MACHINE_STATES.HS] = i18n.t('proxiwashScreen.modal.broken');
modalStateStrings[MACHINE_STATES.ERREUR] = i18n.t('proxiwashScreen.modal.error');
stateIcons[MACHINE_STATES.TERMINE] = 'check-circle'; stateIcons[MACHINE_STATES.TERMINE] = 'check-circle';
stateIcons[MACHINE_STATES.DISPONIBLE] = 'radiobox-blank'; stateIcons[MACHINE_STATES.DISPONIBLE] = 'radiobox-blank';
stateIcons[MACHINE_STATES.FONCTIONNE] = 'progress-check'; stateIcons[MACHINE_STATES.FONCTIONNE] = 'progress-check';
@ -65,10 +74,6 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
stateIcons[MACHINE_STATES.ERREUR] = 'alert'; stateIcons[MACHINE_STATES.ERREUR] = 'alert';
} }
getFetchUrl() {
return DATA_URL;
}
getHeaderTranslation() { getHeaderTranslation() {
return i18n.t("screens.proxiwash"); return i18n.t("screens.proxiwash");
} }
@ -210,6 +215,35 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
return true; return true;
} }
showAlert(title : string, item : Object, remainingTime: number) {
let buttons = [{text: i18n.t("proxiwashScreen.modal.ok")}];
let message = modalStateStrings[MACHINE_STATES[item.state]];
if (MACHINE_STATES[item.state] === MACHINE_STATES.FONCTIONNE) {
buttons = [
{
text: this.isMachineWatched(item.number) ?
i18n.t("proxiwashScreen.modal.disableNotifications") :
i18n.t("proxiwashScreen.modal.enableNotifications"),
onPress: () => this.setupNotifications(item.number, remainingTime)
},
{
text: i18n.t("proxiwashScreen.modal.cancel")
}
];
message = i18n.t('proxiwashScreen.modal.running',
{
start: item.startTime,
end: item.endTime,
remaining: remainingTime
});
}
Alert.alert(
title,
message,
buttons
);
}
/** /**
* Get list item to be rendered * Get list item to be rendered
* *
@ -219,6 +253,12 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
* @returns {React.Node} * @returns {React.Node}
*/ */
getRenderItem(item: Object, section: Object, data: Object) { getRenderItem(item: Object, section: Object, data: Object) {
let isMachineRunning = MACHINE_STATES[item.state] === MACHINE_STATES.FONCTIONNE;
let machineName = (section.title === i18n.t('proxiwashScreen.dryers') ? i18n.t('proxiwashScreen.dryer') : i18n.t('proxiwashScreen.washer')) + ' n°' + item.number;
let remainingTime = 0;
if (isMachineRunning)
remainingTime = ProxiwashScreen.getRemainingTime(item.startTime, item.endTime, item.donePercent);
return ( return (
<Card style={{ <Card style={{
flex: 0, flex: 0,
@ -228,7 +268,9 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
<CardItem <CardItem
style={{ style={{
backgroundColor: stateColors[MACHINE_STATES[item.state]], backgroundColor: stateColors[MACHINE_STATES[item.state]],
height: '100%' paddingRight: 0,
paddingLeft: 0,
height: '100%',
}} }}
> >
<View style={{ <View style={{
@ -238,20 +280,38 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
width: item.donePercent !== '' ? (100 - parseInt(item.donePercent)).toString() + '%' : 0, width: item.donePercent !== '' ? (100 - parseInt(item.donePercent)).toString() + '%' : 0,
backgroundColor: ThemeManager.getInstance().getCurrentThemeVariables().containerBgColor backgroundColor: ThemeManager.getInstance().getCurrentThemeVariables().containerBgColor
}}/> }}/>
<Left> <PlatformTouchable
<CustomMaterialIcon icon={section.title === i18n.t('proxiwashScreen.dryers') ? 'tumble-dryer' : 'washing-machine'} onPress={() => this.showAlert(machineName, item, remainingTime)}
style={{
height: 64,
position: 'absolute',
right: 0,
width: '100%'
}}
>
<View/>
</PlatformTouchable>
<Left style={{marginLeft: 10}}>
<CustomMaterialIcon
icon={section.title === i18n.t('proxiwashScreen.dryers') ? 'tumble-dryer' : 'washing-machine'}
fontSize={30} fontSize={30}
/> />
<Body> <Body>
<Text> <Text>
{section.title === i18n.t('proxiwashScreen.dryers') ? i18n.t('proxiwashScreen.dryer') : i18n.t('proxiwashScreen.washer')} n°{item.number} {machineName + ' '}
{this.isMachineWatched(item.number) ?
<CustomMaterialIcon
icon='bell-ring'
color={ThemeManager.getInstance().getCurrentThemeVariables().brandPrimary}
fontSize={20}
/> : ''}
</Text> </Text>
<Text note> <Text note>
{item.startTime !== '' ? item.startTime + '/' + item.endTime : ''} {isMachineRunning ? item.startTime + '/' + item.endTime : ''}
</Text> </Text>
</Body> </Body>
</Left> </Left>
<Right style={{}}> <Right style={{marginRight: 10}}>
<Text style={MACHINE_STATES[item.state] === MACHINE_STATES.TERMINE ? <Text style={MACHINE_STATES[item.state] === MACHINE_STATES.TERMINE ?
{fontWeight: 'bold'} : {}} {fontWeight: 'bold'} : {}}
> >
@ -260,33 +320,8 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
<CustomMaterialIcon icon={stateIcons[MACHINE_STATES[item.state]]} <CustomMaterialIcon icon={stateIcons[MACHINE_STATES[item.state]]}
fontSize={25} fontSize={25}
/> />
{/*{item.startTime !== '' ?*/}
{/* <Button*/}
{/* style={this.isMachineWatched(item.number) ?*/}
{/* {backgroundColor: '#ba7c1f'} : {}}*/}
{/* onPress={() => {*/}
{/* this.setupNotifications(item.number, ProxiwashScreen.getRemainingTime(item.startTime, item.endTime, item.donePercent))*/}
{/* }}*/}
{/* >*/}
{/* <Text>*/}
{/* {ProxiwashScreen.getRemainingTime(item.startTime, item.endTime, item.donePercent) + ' ' + i18n.t('proxiwashScreen.min')}*/}
{/* </Text>*/}
{/* <Icon*/}
{/* name={this.isMachineWatched(item.number) ? 'bell-ring' : 'bell'}*/}
{/* type={'MaterialCommunityIcons'}*/}
{/* style={{fontSize: 30, width: 30}}*/}
{/* />*/}
{/* </Button>*/}
{/* : (*/}
{/* )*/}
{/*}*/}
</Right> </Right>
</CardItem> </CardItem>
</Card>); </Card>);
} }
// getRenderSectionHeader(title: String) {
// return <H2 style={{textAlign: 'center', paddingVertical: 10}}>{title}</H2>;
// }
} }

View file

@ -61,6 +61,17 @@
"listUpdateFail": "Error while updating machines state", "listUpdateFail": "Error while updating machines state",
"error": "Could not update machines state. Pull down to retry.", "error": "Could not update machines state. Pull down to retry.",
"loading": "Loading...", "loading": "Loading...",
"modal": {
"enableNotifications": "Notify me",
"disableNotifications": "Stop notifications",
"ok": "OK",
"cancel": "Cancel",
"finished": "This machine is finished. If you started it, you can get back your laundry.",
"ready": "This machine is empty and ready to use. {Put price here}",
"running": "This machine has been started at %{start} and will end at %{end}.\nRemaining time: %{remaining} min",
"broken": "This machine is broken and cannot be used. Thank you for your comprehension.",
"error": "There has been an error and we are unable to get information from this machine. Sorry for the inconvenience."
},
"states": { "states": {
"finished": "FINISHED", "finished": "FINISHED",
"ready": "READY", "ready": "READY",

View file

@ -61,6 +61,17 @@
"listUpdateFail": "Erreur lors de la mise à jour del'état des machines", "listUpdateFail": "Erreur lors de la mise à jour del'état des machines",
"error": "Impossible de mettre a jour l'état des machines. Tirez vers le bas pour reessayer.", "error": "Impossible de mettre a jour l'état des machines. Tirez vers le bas pour reessayer.",
"loading": "Chargement...", "loading": "Chargement...",
"modal": {
"enableNotifications": "Me Notifier",
"disableNotifications": "Désactiver les notifications",
"ok": "OK",
"cancel": "Annuler",
"finished": "Cette machine est terminée. Si vous l'avez l'avez démarée, vous pouvez récupérer votre linge.",
"ready": "Cette machine est vide et prête à être utilisée. {Afficher prix ici}",
"running": "Cette machine a démarré à %{start} et terminera à %{end}.\nTemps restant : %{remaining} min",
"broken": "Cette machine est hors service. Merci pour votre compréhension.",
"error": "Il y a eu une erreur et il est impossible de récupérer les informations de cette machine. Veuillez nous excuser pour le gène occasionnée."
},
"states": { "states": {
"finished": "TERMINE", "finished": "TERMINE",
"ready": "DISPONIBLE", "ready": "DISPONIBLE",