forked from vergnet/application-amicale
Added setting to set proxiwash reminder notification
This commit is contained in:
parent
7cd543ac74
commit
f2cd3bec0d
11 changed files with 224 additions and 50 deletions
7
App.js
7
App.js
|
@ -35,8 +35,7 @@ export default class App extends React.Component {
|
|||
}
|
||||
|
||||
updateTheme() {
|
||||
console.log('update theme called');
|
||||
// Change not propagating, need to restart the app
|
||||
// console.log('update theme called');
|
||||
this.setState({
|
||||
currentTheme: ThemeManager.getInstance().getCurrentTheme()
|
||||
});
|
||||
|
@ -47,8 +46,8 @@ export default class App extends React.Component {
|
|||
if (this.state.isLoading) {
|
||||
return <View/>;
|
||||
}
|
||||
console.log('rendering');
|
||||
console.log(this.state.currentTheme.variables.containerBgColor);
|
||||
// console.log('rendering');
|
||||
// console.log(this.state.currentTheme.variables.containerBgColor);
|
||||
return (
|
||||
<Root>
|
||||
<StyleProvider style={this.state.currentTheme}>
|
||||
|
|
4
app.json
4
app.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"expo": {
|
||||
"name": "Application Amicale",
|
||||
"name": "Amicale INSAT",
|
||||
"slug": "application-amicale",
|
||||
"privacy": "public",
|
||||
"sdkVersion": "33.0.0",
|
||||
|
@ -15,7 +15,7 @@
|
|||
"primaryColor": "#e42612",
|
||||
"splash": {
|
||||
"image": "./assets/splash.png",
|
||||
"resizeMode": "contain",
|
||||
"resizeMode": "cover",
|
||||
"backgroundColor": "#fff"
|
||||
},
|
||||
"updates": {
|
||||
|
|
|
@ -118,7 +118,7 @@ export default {
|
|||
containerBgColor: "#333333",
|
||||
|
||||
//Date Picker
|
||||
datePickerTextColor: "#000",
|
||||
datePickerTextColor: "#fff",
|
||||
datePickerBg: "transparent",
|
||||
|
||||
// Font
|
||||
|
|
19
package-lock.json
generated
19
package-lock.json
generated
|
@ -1782,6 +1782,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"base-64": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
|
||||
"integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
|
||||
|
@ -6253,6 +6258,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-native-fs": {
|
||||
"version": "2.13.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.13.3.tgz",
|
||||
"integrity": "sha512-B62LSSAEYQGItg7KVTzTVVCxezOYFBYp4DMVFbdoZUd1mZVFdqR2sy1HY1mye1VI/Lf3IbxSyZEQ0GmrrdwLjg==",
|
||||
"requires": {
|
||||
"base-64": "^0.1.0",
|
||||
"utf8": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"react-native-gesture-handler": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.2.1.tgz",
|
||||
|
@ -8374,6 +8388,11 @@
|
|||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
},
|
||||
"utf8": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz",
|
||||
"integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"react-dom": "^16.8.6",
|
||||
"react-i18next": "latest",
|
||||
"react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz",
|
||||
"react-native-fs": "^2.13.3",
|
||||
"react-native-paper": "latest",
|
||||
"react-native-platform-touchable": "latest",
|
||||
"react-native-settings-page": "latest",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import {StyleSheet, RefreshControl, FlatList} from 'react-native';
|
||||
import {Container, Text, Content, ListItem, Left, Right, Body, Badge, Icon, Toast} from 'native-base';
|
||||
import {RefreshControl, SectionList} from 'react-native';
|
||||
import {Container, Text, Content, ListItem, Left, Right, Body, Badge, Icon, Toast, H2} from 'native-base';
|
||||
import CustomHeader from "../../components/CustomHeader";
|
||||
import i18n from "i18n-js";
|
||||
import CustomMaterialIcon from "../../components/CustomMaterialIcon";
|
||||
|
@ -82,12 +82,24 @@ export default class ProximoMainScreen extends React.Component {
|
|||
|
||||
render() {
|
||||
const nav = this.props.navigation;
|
||||
const data = [
|
||||
{
|
||||
title: i18n.t('proximoScreen.listTitle'),
|
||||
data: this.state.data,
|
||||
extraData: this.state,
|
||||
}
|
||||
];
|
||||
const loadingData = [
|
||||
{
|
||||
title: i18n.t('proximoScreen.loading'),
|
||||
data: []
|
||||
}
|
||||
];
|
||||
return (
|
||||
<Container>
|
||||
<CustomHeader navigation={nav} title={'Proximo'}/>
|
||||
<FlatList
|
||||
data={this.state.data}
|
||||
extraData={this.state}
|
||||
<SectionList
|
||||
sections={this.state.firstLoading ? loadingData : data}
|
||||
keyExtractor={(item, index) => item.type}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
|
@ -96,6 +108,9 @@ export default class ProximoMainScreen extends React.Component {
|
|||
/>
|
||||
}
|
||||
style={{minHeight: 300, width: '100%'}}
|
||||
renderSectionHeader={({section: {title}}) => (
|
||||
<H2 style={{textAlign: 'center', paddingVertical: 10}}>{title}</H2>
|
||||
)}
|
||||
renderItem={({item}) =>
|
||||
<ListItem
|
||||
button
|
||||
|
|
|
@ -11,7 +11,7 @@ import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
|||
const DATA_URL = "https://etud.insa-toulouse.fr/~vergnet/appli-amicale/dataProxiwash.json";
|
||||
const WATCHED_MACHINES_PREFKEY = "proxiwash.watchedMachines";
|
||||
|
||||
const remainderNotifTime = 5;
|
||||
let reminderNotifTime = 5;
|
||||
|
||||
const MACHINE_STATES = {
|
||||
TERMINE: "0",
|
||||
|
@ -72,9 +72,12 @@ export default class ProxiwashScreen extends React.Component {
|
|||
let dataString = await AsyncStorage.getItem(WATCHED_MACHINES_PREFKEY);
|
||||
if (dataString === null)
|
||||
dataString = '[]';
|
||||
this.setState({machinesWatched: JSON.parse(dataString)});
|
||||
this.setState({
|
||||
machinesWatched: JSON.parse(dataString)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
this._onRefresh();
|
||||
}
|
||||
|
@ -112,16 +115,24 @@ export default class ProxiwashScreen extends React.Component {
|
|||
i18n.t('proxiwashScreen.notifications.machineFinishedBody', {number: number}),
|
||||
new Date().getTime() + remainingTime * (60 * 1000) // Convert back to milliseconds
|
||||
);
|
||||
let remainderNotifID = undefined;
|
||||
if (remainingTime > remainderNotifTime) {
|
||||
remainderNotifID = await NotificationsManager.scheduleNotification(
|
||||
i18n.t('proxiwashScreen.notifications.machineRunningTitle', {time: remainderNotifTime}),
|
||||
let reminderNotifID = undefined;
|
||||
let val = await AsyncStorage.getItem('proxiwashNotifKey');
|
||||
if (val === null)
|
||||
val = "5";
|
||||
if (val !== "never")
|
||||
reminderNotifTime = parseInt(val);
|
||||
else
|
||||
reminderNotifTime = -1;
|
||||
console.log(reminderNotifTime);
|
||||
if (remainingTime > reminderNotifTime && reminderNotifTime > 0) {
|
||||
reminderNotifID = await NotificationsManager.scheduleNotification(
|
||||
i18n.t('proxiwashScreen.notifications.machineRunningTitle', {time: reminderNotifTime}),
|
||||
i18n.t('proxiwashScreen.notifications.machineRunningBody', {number: number}),
|
||||
new Date().getTime() + (remainingTime - remainderNotifTime) * (60 * 1000) // Convert back to milliseconds
|
||||
new Date().getTime() + (remainingTime - reminderNotifTime) * (60 * 1000) // Convert back to milliseconds
|
||||
);
|
||||
}
|
||||
let data = this.state.machinesWatched;
|
||||
data.push({machineNumber: number, endNotifID: endNotifID, remainderNotifID: remainderNotifID});
|
||||
data.push({machineNumber: number, endNotifID: endNotifID, reminderNotifID: reminderNotifID});
|
||||
this.setState({machinesWatched: data});
|
||||
AsyncStorage.setItem(WATCHED_MACHINES_PREFKEY, JSON.stringify(data));
|
||||
} else
|
||||
|
@ -136,8 +147,8 @@ export default class ProxiwashScreen extends React.Component {
|
|||
});
|
||||
let arrayIndex = data.indexOf(elem);
|
||||
NotificationsManager.cancelScheduledNoification(data[arrayIndex].endNotifID);
|
||||
if (data[arrayIndex].remainderNotifID !== undefined)
|
||||
NotificationsManager.cancelScheduledNoification(data[arrayIndex].remainderNotifID);
|
||||
if (data[arrayIndex].reminderNotifID !== undefined)
|
||||
NotificationsManager.cancelScheduledNoification(data[arrayIndex].reminderNotifID);
|
||||
data.splice(arrayIndex, 1);
|
||||
this.setState({machinesWatched: data});
|
||||
AsyncStorage.setItem(WATCHED_MACHINES_PREFKEY, JSON.stringify(data));
|
||||
|
|
|
@ -1,22 +1,74 @@
|
|||
import React from 'react';
|
||||
import {Container, Content, Left, ListItem, Right, Text, List, CheckBox, Button} from "native-base";
|
||||
import {
|
||||
Container,
|
||||
Content,
|
||||
Left,
|
||||
ListItem,
|
||||
Right,
|
||||
Text,
|
||||
List,
|
||||
CheckBox,
|
||||
Body,
|
||||
CardItem,
|
||||
Card,
|
||||
Picker,
|
||||
} from "native-base";
|
||||
import CustomHeader from "../components/CustomHeader";
|
||||
import ThemeManager from '../utils/ThemeManager';
|
||||
import i18n from "i18n-js";
|
||||
import {NavigationActions, StackActions} from "react-navigation";
|
||||
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
||||
import {AsyncStorage} from 'react-native'
|
||||
|
||||
|
||||
const nightModeKey = 'nightMode';
|
||||
const proxiwashNotifKey = "proxiwashNotifKey";
|
||||
|
||||
export default class SettingsScreen extends React.Component {
|
||||
state = {
|
||||
nightMode: ThemeManager.getInstance().getNightMode(),
|
||||
proxiwashNotifPickerSelected: "5"
|
||||
};
|
||||
|
||||
async componentWillMount() {
|
||||
let val = await AsyncStorage.getItem(proxiwashNotifKey);
|
||||
if (val === null)
|
||||
val = "5";
|
||||
this.setState({
|
||||
proxiwashNotifPickerSelected: val,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
onProxiwashNotidPickerValueChange(value) {
|
||||
AsyncStorage.setItem(proxiwashNotifKey, value);
|
||||
this.setState({
|
||||
proxiwashNotifPickerSelected: value
|
||||
});
|
||||
}
|
||||
|
||||
getproxiwashNotifPicker() {
|
||||
return (
|
||||
<Picker
|
||||
note
|
||||
mode="dropdown"
|
||||
style={{width: 120}}
|
||||
selectedValue={this.state.proxiwashNotifPickerSelected}
|
||||
onValueChange={(value) => this.onProxiwashNotidPickerValueChange(value)}
|
||||
>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.never')} value="never"/>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.1')} value="1"/>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.2')} value="2"/>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.3')} value="3"/>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.5')} value="5"/>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.10')} value="10"/>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.20')} value="20"/>
|
||||
<Picker.Item label={i18n.t('settingsScreen.proxiwashNotifReminderPicker.30')} value="30"/>
|
||||
</Picker>
|
||||
);
|
||||
}
|
||||
|
||||
toggleNightMode() {
|
||||
this.setState({nightMode: !this.state.nightMode});
|
||||
ThemeManager.getInstance().setNightmode(!this.state.nightMode);
|
||||
this.setState({nightMode: !this.state.nightMode});
|
||||
// Alert.alert(i18n.t('settingsScreen.nightMode'), i18n.t('settingsScreen.restart'));
|
||||
this.resetStack();
|
||||
}
|
||||
|
@ -25,35 +77,84 @@ export default class SettingsScreen extends React.Component {
|
|||
const resetAction = StackActions.reset({
|
||||
index: 0,
|
||||
key: null,
|
||||
actions: [NavigationActions.navigate({ routeName: 'Main' })],
|
||||
actions: [NavigationActions.navigate({routeName: 'Main'})],
|
||||
});
|
||||
this.props.navigation.dispatch(resetAction);
|
||||
this.props.navigation.navigate('Settings');
|
||||
}
|
||||
|
||||
getToggleItem(onPressCallback, icon, text, subtitle) {
|
||||
return (
|
||||
<ListItem
|
||||
button
|
||||
thumbnail
|
||||
onPress={onPressCallback}
|
||||
>
|
||||
<Left>
|
||||
<CustomMaterialIcon icon={icon}/>
|
||||
</Left>
|
||||
<Body>
|
||||
<Text>
|
||||
{text}
|
||||
</Text>
|
||||
<Text note>
|
||||
{subtitle}
|
||||
</Text>
|
||||
</Body>
|
||||
<Right style={{flex: 1}}>
|
||||
<CheckBox checked={this.state.nightMode}
|
||||
onPress={() => this.toggleNightMode()}/>
|
||||
</Right>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
getGeneralItem(control, icon, text, subtitle) {
|
||||
return (
|
||||
<ListItem
|
||||
thumbnail
|
||||
>
|
||||
<Left>
|
||||
<CustomMaterialIcon icon={icon}/>
|
||||
</Left>
|
||||
<Body>
|
||||
<Text>
|
||||
{text}
|
||||
</Text>
|
||||
<Text note>
|
||||
{subtitle}
|
||||
</Text>
|
||||
</Body>
|
||||
|
||||
<Right style={{flex: 1}}>
|
||||
{control}
|
||||
</Right>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const nav = this.props.navigation;
|
||||
return (
|
||||
<Container>
|
||||
<CustomHeader navigation={nav} title={i18n.t('screens.settings')}/>
|
||||
<Content>
|
||||
<List>
|
||||
<ListItem
|
||||
button
|
||||
onPress={() => this.toggleNightMode()}
|
||||
>
|
||||
<Left>
|
||||
<CustomMaterialIcon icon={'theme-light-dark'} />
|
||||
<Text>
|
||||
{i18n.t('settingsScreen.nightMode')}
|
||||
</Text>
|
||||
</Left>
|
||||
<Right style={{flex: 1}}>
|
||||
<CheckBox checked={this.state.nightMode}
|
||||
onPress={() => this.toggleNightMode()}/>
|
||||
</Right>
|
||||
</ListItem>
|
||||
</List>
|
||||
<Card>
|
||||
<CardItem header>
|
||||
<Text>{i18n.t('settingsScreen.appearanceCard')}</Text>
|
||||
</CardItem>
|
||||
<List>
|
||||
{this.getToggleItem(() => this.toggleNightMode(), 'theme-light-dark', i18n.t('settingsScreen.nightMode'), i18n.t('settingsScreen.nightModeSub'))}
|
||||
</List>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardItem header>
|
||||
<Text>Proxiwash</Text>
|
||||
</CardItem>
|
||||
<List>
|
||||
{this.getGeneralItem(this.getproxiwashNotifPicker(), 'washing-machine', i18n.t('settingsScreen.proxiwashNotifReminder'), i18n.t('settingsScreen.proxiwashNotifReminderSub'))}
|
||||
</List>
|
||||
</Card>
|
||||
</Content>
|
||||
</Container>
|
||||
|
||||
|
|
|
@ -6,8 +6,21 @@
|
|||
"about": "About"
|
||||
},
|
||||
"settingsScreen": {
|
||||
"appearanceCard": "Appearance",
|
||||
"nightMode": "Night Mode",
|
||||
"restart": "Restart the app to apply changes"
|
||||
"nightModeSub": "Switch the app to a dark or light theme",
|
||||
"proxiwashNotifReminder": "Machine running reminder",
|
||||
"proxiwashNotifReminderSub": "Choose when to send a notification to remind you a machine is running with your laundry",
|
||||
"proxiwashNotifReminderPicker": {
|
||||
"never": "Never",
|
||||
"1": "1 min",
|
||||
"2": "2 min",
|
||||
"3": "3 min",
|
||||
"5": "5 min",
|
||||
"10": "10 min",
|
||||
"20": "20 min",
|
||||
"30": "30 min"
|
||||
}
|
||||
},
|
||||
"aboutScreen": {
|
||||
"appstore": "See on the Appstore",
|
||||
|
@ -27,7 +40,9 @@
|
|||
"articles": "Articles",
|
||||
"sortName": "Sort by name",
|
||||
"sortPrice": "Sort by price",
|
||||
"listUpdated": "Article list updated!"
|
||||
"listUpdated": "Article list updated!",
|
||||
"loading": "Loading...",
|
||||
"listTitle": "Choose a category"
|
||||
},
|
||||
"proxiwashScreen": {
|
||||
"dryer": "Dryer",
|
||||
|
|
|
@ -6,8 +6,21 @@
|
|||
"about": "À Propos"
|
||||
},
|
||||
"settingsScreen": {
|
||||
"appearanceCard": "Apparence",
|
||||
"nightMode": "Mode Nuit",
|
||||
"restart": "Redémarrez l'application pour appliquer les changements"
|
||||
"nightModeSub": "Passer l'application dans un thème sombre ou clair",
|
||||
"proxiwashNotifReminder": "Rappel de machine en cours",
|
||||
"proxiwashNotifReminderSub": "Choississez quand envoyer une notification pour vous rappeler qu'une machine avec votre linge est en cours",
|
||||
"proxiwashNotifReminderPicker": {
|
||||
"never": "Jamais",
|
||||
"1": "1 min",
|
||||
"2": "2 min",
|
||||
"3": "3 min",
|
||||
"5": "5 min",
|
||||
"10": "10 min",
|
||||
"20": "20 min",
|
||||
"30": "30 min"
|
||||
}
|
||||
},
|
||||
"aboutScreen": {
|
||||
"appstore": "Voir sur l'Appstore",
|
||||
|
@ -27,7 +40,9 @@
|
|||
"articles": "Articles",
|
||||
"sortName": "Trier par nom",
|
||||
"sortPrice": "Trier par prix",
|
||||
"listUpdated": "Liste des articles mise à jour !"
|
||||
"listUpdated": "Liste des articles mise à jour !",
|
||||
"loading": "Chargement...",
|
||||
"listTitle": "Choisissez une catégorie"
|
||||
},
|
||||
"proxiwashScreen": {
|
||||
"dryer": "Sèche Linge",
|
||||
|
|
|
@ -23,8 +23,6 @@ export default class ThemeManager {
|
|||
|
||||
setUpdateThemeCallback(callback) {
|
||||
this.updateThemeCallback = callback;
|
||||
console.log(this.updateThemeCallback);
|
||||
|
||||
}
|
||||
|
||||
async getDataFromPreferences() {
|
||||
|
|
Loading…
Reference in a new issue