forked from vergnet/application-amicale
Abstracted async storage and fixed key warning in proxiwash tab view
This commit is contained in:
parent
8fa2bd792f
commit
0cbf60e6cc
10 changed files with 178 additions and 125 deletions
9
App.js
9
App.js
|
@ -10,6 +10,7 @@ import * as Font from 'expo-font';
|
||||||
// https://github.com/GeekyAnts/theme/pull/5/files/91f67c55ca6e65fe3af779586b506950c9f331be#diff-4cfc2dd4d5dae7954012899f2268a422
|
// https://github.com/GeekyAnts/theme/pull/5/files/91f67c55ca6e65fe3af779586b506950c9f331be#diff-4cfc2dd4d5dae7954012899f2268a422
|
||||||
// to allow for dynamic theme switching
|
// to allow for dynamic theme switching
|
||||||
import {clearThemeCache} from 'native-base-shoutem-theme';
|
import {clearThemeCache} from 'native-base-shoutem-theme';
|
||||||
|
import AsyncStorageManager from "./utils/AsyncStorageManager";
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
|
@ -39,11 +40,11 @@ export default class App extends React.Component<Props, State> {
|
||||||
'Roboto': require('native-base/Fonts/Roboto.ttf'),
|
'Roboto': require('native-base/Fonts/Roboto.ttf'),
|
||||||
'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
|
'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
|
||||||
});
|
});
|
||||||
|
await AsyncStorageManager.getInstance().loadPreferences();
|
||||||
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
||||||
await ThemeManager.getInstance().getDataFromPreferences();
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
currentTheme: ThemeManager.getInstance().getCurrentTheme()
|
currentTheme: ThemeManager.getCurrentTheme()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +54,9 @@ export default class App extends React.Component<Props, State> {
|
||||||
updateTheme() {
|
updateTheme() {
|
||||||
// console.log('update theme called');
|
// console.log('update theme called');
|
||||||
this.setState({
|
this.setState({
|
||||||
currentTheme: ThemeManager.getInstance().getCurrentTheme()
|
currentTheme: ThemeManager.getCurrentTheme()
|
||||||
});
|
});
|
||||||
clearThemeCache();
|
// clearThemeCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,8 +41,8 @@ export default class CustomMaterialIcon extends React.Component<Props> {
|
||||||
this.props.color !== undefined ?
|
this.props.color !== undefined ?
|
||||||
this.props.color :
|
this.props.color :
|
||||||
this.props.active ?
|
this.props.active ?
|
||||||
ThemeManager.getInstance().getCurrentThemeVariables().brandPrimary :
|
ThemeManager.getCurrentThemeVariables().brandPrimary :
|
||||||
ThemeManager.getInstance().getCurrentThemeVariables().customMaterialIconColor,
|
ThemeManager.getCurrentThemeVariables().customMaterialIconColor,
|
||||||
fontSize: this.props.fontSize,
|
fontSize: this.props.fontSize,
|
||||||
width: this.props.width
|
width: this.props.width
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -83,15 +83,6 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* What item field should be used as a key in the list
|
|
||||||
* @param item {Object}
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
getKeyExtractor(item: Object) {
|
|
||||||
return item.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasTabs() {
|
hasTabs() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +91,6 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
return (
|
return (
|
||||||
<SectionList
|
<SectionList
|
||||||
sections={dataset}
|
sections={dataset}
|
||||||
keyExtractor={(item) => this.getKeyExtractor(item)}
|
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl
|
<RefreshControl
|
||||||
refreshing={this.state.refreshing}
|
refreshing={this.state.refreshing}
|
||||||
|
@ -121,7 +111,7 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
getTabbedView(dataset: Array<Object>) {
|
getTabbedView(dataset: Array<Object>) {
|
||||||
let tabbedView = [];
|
let tabbedView = [];
|
||||||
for (let i = 0; i < dataset.length; i++) {
|
for (let i = 0; i < dataset.length; i++) {
|
||||||
tabbedView.push(
|
tabbedView.push(
|
||||||
<Tab heading={
|
<Tab heading={
|
||||||
<TabHeading>
|
<TabHeading>
|
||||||
<CustomMaterialIcon icon={dataset[i].icon}
|
<CustomMaterialIcon icon={dataset[i].icon}
|
||||||
|
@ -129,7 +119,8 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
fontSize={20}
|
fontSize={20}
|
||||||
/>
|
/>
|
||||||
<Text>{dataset[i].title}</Text>
|
<Text>{dataset[i].title}</Text>
|
||||||
</TabHeading>}>
|
</TabHeading>}
|
||||||
|
key={dataset[i].title}>
|
||||||
<Content padder>
|
<Content padder>
|
||||||
{this.getSectionList(
|
{this.getSectionList(
|
||||||
[
|
[
|
||||||
|
@ -137,6 +128,7 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
title: dataset[i].title,
|
title: dataset[i].title,
|
||||||
data: dataset[i].data,
|
data: dataset[i].data,
|
||||||
extraData: dataset[i].extraData,
|
extraData: dataset[i].extraData,
|
||||||
|
keyExtractor: dataset[i].keyExtractor
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -50,7 +50,8 @@ export default class HomeScreen extends FetchedDataSectionList {
|
||||||
{
|
{
|
||||||
title: '',
|
title: '',
|
||||||
data: data,
|
data: data,
|
||||||
extraData: super.state
|
extraData: super.state,
|
||||||
|
keyExtractor: this.getKeyExtractor
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ export default class ProximoMainScreen extends FetchedDataSectionList {
|
||||||
title: i18n.t('proximoScreen.listTitle'),
|
title: i18n.t('proximoScreen.listTitle'),
|
||||||
data: ProximoMainScreen.generateData(fetchedData),
|
data: ProximoMainScreen.generateData(fetchedData),
|
||||||
extraData: super.state,
|
extraData: super.state,
|
||||||
|
keyExtractor: this.getKeyExtractor
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Alert, AsyncStorage, View} from 'react-native';
|
import {Alert, View} from 'react-native';
|
||||||
import {Body, Card, CardItem, 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";
|
||||||
|
@ -9,10 +9,9 @@ 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";
|
import PlatformTouchable from "react-native-platform-touchable";
|
||||||
|
import AsyncStorageManager from "../utils/AsyncStorageManager";
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
let reminderNotifTime = 5;
|
let reminderNotifTime = 5;
|
||||||
|
|
||||||
|
@ -36,19 +35,12 @@ let stateColors = {};
|
||||||
*/
|
*/
|
||||||
export default class ProxiwashScreen extends FetchedDataSectionList {
|
export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
|
|
||||||
state = {
|
|
||||||
refreshing: false,
|
|
||||||
firstLoading: true,
|
|
||||||
fetchedData: {},
|
|
||||||
machinesWatched: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates machine state parameters using current theme and translations
|
* Creates machine state parameters using current theme and translations
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
super(DATA_URL);
|
super(DATA_URL);
|
||||||
let colors = ThemeManager.getInstance().getCurrentThemeVariables();
|
let colors = ThemeManager.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;
|
||||||
stateColors[MACHINE_STATES.FONCTIONNE] = colors.proxiwashRunningColor;
|
stateColors[MACHINE_STATES.FONCTIONNE] = colors.proxiwashRunningColor;
|
||||||
|
@ -72,6 +64,14 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
stateIcons[MACHINE_STATES.FONCTIONNE] = 'progress-check';
|
stateIcons[MACHINE_STATES.FONCTIONNE] = 'progress-check';
|
||||||
stateIcons[MACHINE_STATES.HS] = 'alert-octagram-outline';
|
stateIcons[MACHINE_STATES.HS] = 'alert-octagram-outline';
|
||||||
stateIcons[MACHINE_STATES.ERREUR] = 'alert';
|
stateIcons[MACHINE_STATES.ERREUR] = 'alert';
|
||||||
|
|
||||||
|
let dataString = AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.current;
|
||||||
|
this.state = {
|
||||||
|
refreshing: false,
|
||||||
|
firstLoading: true,
|
||||||
|
fetchedData: {},
|
||||||
|
machinesWatched: JSON.parse(dataString),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeaderTranslation() {
|
getHeaderTranslation() {
|
||||||
|
@ -86,18 +86,14 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
return item !== undefined ? item.number : undefined;
|
return item !== undefined ? item.number : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
getDryersKeyExtractor(item: Object) {
|
||||||
* Get which machines have notifications enabled before loading the screen
|
console.log(item !== undefined ? "dryer" + item.number : undefined);
|
||||||
*
|
return item !== undefined ? "dryer" + item.number : undefined;
|
||||||
* @returns {Promise<void>}
|
}
|
||||||
*/
|
|
||||||
async componentWillMount() {
|
getWashersKeyExtractor(item: Object) {
|
||||||
let dataString = await AsyncStorage.getItem(WATCHED_MACHINES_PREFKEY);
|
console.log(item !== undefined ? "washer" + item.number : undefined);
|
||||||
if (dataString === null)
|
return item !== undefined ? "washer" + item.number : undefined;
|
||||||
dataString = '[]';
|
|
||||||
this.setState({
|
|
||||||
machinesWatched: JSON.parse(dataString)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,10 +107,8 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
static getRemainingTime(startString: string, endString: string, percentDone: string): number {
|
static getRemainingTime(startString: string, endString: string, percentDone: string): number {
|
||||||
let startArray = startString.split(':');
|
let startArray = startString.split(':');
|
||||||
let endArray = endString.split(':');
|
let endArray = endString.split(':');
|
||||||
let startDate = new Date();
|
let startDate = new Date().setHours(parseInt(startArray[0]), parseInt(startArray[1]), 0, 0);
|
||||||
startDate.setHours(parseInt(startArray[0]), parseInt(startArray[1]), 0, 0);
|
let endDate = new Date().setHours(parseInt(endArray[0]), parseInt(endArray[1]), 0, 0);
|
||||||
let endDate = new Date();
|
|
||||||
endDate.setHours(parseInt(endArray[0]), parseInt(endArray[1]), 0, 0);
|
|
||||||
// Convert milliseconds into minutes
|
// Convert milliseconds into minutes
|
||||||
let time: string = (((100 - parseFloat(percentDone)) / 100) * (endDate - startDate) / (60 * 1000)).toFixed(0);
|
let time: string = (((100 - parseFloat(percentDone)) / 100) * (endDate - startDate) / (60 * 1000)).toFixed(0);
|
||||||
return parseInt(time);
|
return parseInt(time);
|
||||||
|
@ -131,35 +125,41 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
*/
|
*/
|
||||||
async setupNotifications(machineId: string, remainingTime: number) {
|
async setupNotifications(machineId: string, remainingTime: number) {
|
||||||
if (!this.isMachineWatched(machineId)) {
|
if (!this.isMachineWatched(machineId)) {
|
||||||
let endNotifID = await NotificationsManager.scheduleNotification(
|
let endNotificationID = await NotificationsManager.scheduleNotification(
|
||||||
i18n.t('proxiwashScreen.notifications.machineFinishedTitle'),
|
i18n.t('proxiwashScreen.notifications.machineFinishedTitle'),
|
||||||
i18n.t('proxiwashScreen.notifications.machineFinishedBody', {number: machineId}),
|
i18n.t('proxiwashScreen.notifications.machineFinishedBody', {number: machineId}),
|
||||||
new Date().getTime() + remainingTime * (60 * 1000) // Convert back to milliseconds
|
new Date().getTime() + remainingTime * (60 * 1000) // Convert back to milliseconds
|
||||||
);
|
);
|
||||||
let reminderNotifID = undefined;
|
let reminderNotificationID = await ProxiwashScreen.setupReminderNotification(machineId, remainingTime);
|
||||||
let val = await AsyncStorage.getItem('proxiwashNotifKey');
|
this.saveNotificationToPrefs(machineId, endNotificationID, reminderNotificationID);
|
||||||
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: machineId}),
|
|
||||||
new Date().getTime() + (remainingTime - reminderNotifTime) * (60 * 1000) // Convert back to milliseconds
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let data = this.state.machinesWatched;
|
|
||||||
data.push({machineNumber: machineId, endNotifID: endNotifID, reminderNotifID: reminderNotifID});
|
|
||||||
this.setState({machinesWatched: data});
|
|
||||||
AsyncStorage.setItem(WATCHED_MACHINES_PREFKEY, JSON.stringify(data));
|
|
||||||
} else
|
} else
|
||||||
this.disableNotification(machineId);
|
this.disableNotification(machineId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async setupReminderNotification(machineId: string, remainingTime: number): Promise<string | null> {
|
||||||
|
let reminderNotificationID: string | null = null;
|
||||||
|
let reminderNotificationTime = ProxiwashScreen.getReminderNotificationTime();
|
||||||
|
if (remainingTime > reminderNotificationTime && reminderNotificationTime > 0) {
|
||||||
|
reminderNotificationID = await NotificationsManager.scheduleNotification(
|
||||||
|
i18n.t('proxiwashScreen.notifications.machineRunningTitle', {time: reminderNotificationTime}),
|
||||||
|
i18n.t('proxiwashScreen.notifications.machineRunningBody', {number: machineId}),
|
||||||
|
new Date().getTime() + (remainingTime - reminderNotificationTime) * (60 * 1000) // Convert back to milliseconds
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return reminderNotificationID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getReminderNotificationTime(): number {
|
||||||
|
let val = AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current;
|
||||||
|
if (val !== "never")
|
||||||
|
reminderNotifTime = parseInt(val);
|
||||||
|
else
|
||||||
|
reminderNotifTime = -1;
|
||||||
|
console.log(reminderNotifTime);
|
||||||
|
return reminderNotifTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop scheduled notifications for the machine of the given ID.
|
* Stop scheduled notifications for the machine of the given ID.
|
||||||
* This will also remove the notification if it was already shown.
|
* This will also remove the notification if it was already shown.
|
||||||
|
@ -173,15 +173,37 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
return elem.machineNumber === machineId
|
return elem.machineNumber === machineId
|
||||||
});
|
});
|
||||||
let arrayIndex = data.indexOf(elem);
|
let arrayIndex = data.indexOf(elem);
|
||||||
NotificationsManager.cancelScheduledNotification(data[arrayIndex].endNotifID);
|
if (arrayIndex !== -1) {
|
||||||
if (data[arrayIndex].reminderNotifID !== undefined)
|
NotificationsManager.cancelScheduledNotification(data[arrayIndex].endNotificationID);
|
||||||
NotificationsManager.cancelScheduledNotification(data[arrayIndex].reminderNotifID);
|
if (data[arrayIndex].reminderNotificationID !== null)
|
||||||
data.splice(arrayIndex, 1);
|
NotificationsManager.cancelScheduledNotification(data[arrayIndex].reminderNotificationID);
|
||||||
this.setState({machinesWatched: data});
|
this.removeNotificationFromPrefs(arrayIndex);
|
||||||
AsyncStorage.setItem(WATCHED_MACHINES_PREFKEY, JSON.stringify(data));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveNotificationToPrefs(machineId: string, endNotificationID: string, reminderNotificationID: string | null) {
|
||||||
|
let data = this.state.machinesWatched;
|
||||||
|
data.push({
|
||||||
|
machineNumber: machineId,
|
||||||
|
endNotificationID: endNotificationID,
|
||||||
|
reminderNotificationID: reminderNotificationID
|
||||||
|
});
|
||||||
|
this.updateNotificationPrefs(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeNotificationFromPrefs(index: number) {
|
||||||
|
let data = this.state.machinesWatched;
|
||||||
|
data.splice(index, 1);
|
||||||
|
this.updateNotificationPrefs(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNotificationPrefs(data: Object) {
|
||||||
|
this.setState({machinesWatched: data});
|
||||||
|
let prefKey = AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.key;
|
||||||
|
AsyncStorageManager.getInstance().savePref(prefKey, JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the machine of the given ID has scheduled notifications
|
* Checks whether the machine of the given ID has scheduled notifications
|
||||||
*
|
*
|
||||||
|
@ -200,13 +222,15 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
title: i18n.t('proxiwashScreen.dryers'),
|
title: i18n.t('proxiwashScreen.dryers'),
|
||||||
icon: 'tumble-dryer',
|
icon: 'tumble-dryer',
|
||||||
data: fetchedData.dryers === undefined ? [] : fetchedData.dryers,
|
data: fetchedData.dryers === undefined ? [] : fetchedData.dryers,
|
||||||
extraData: super.state
|
extraData: super.state,
|
||||||
|
keyExtractor: this.getDryersKeyExtractor
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18n.t('proxiwashScreen.washers'),
|
title: i18n.t('proxiwashScreen.washers'),
|
||||||
icon: 'washing-machine',
|
icon: 'washing-machine',
|
||||||
data: fetchedData.washers === undefined ? [] : fetchedData.washers,
|
data: fetchedData.washers === undefined ? [] : fetchedData.washers,
|
||||||
extraData: super.state
|
extraData: super.state,
|
||||||
|
keyExtractor: this.getWashersKeyExtractor
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -215,7 +239,7 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
showAlert(title : string, item : Object, remainingTime: number) {
|
showAlert(title: string, item: Object, remainingTime: number) {
|
||||||
let buttons = [{text: i18n.t("proxiwashScreen.modal.ok")}];
|
let buttons = [{text: i18n.t("proxiwashScreen.modal.ok")}];
|
||||||
let message = modalStateStrings[MACHINE_STATES[item.state]];
|
let message = modalStateStrings[MACHINE_STATES[item.state]];
|
||||||
if (MACHINE_STATES[item.state] === MACHINE_STATES.FONCTIONNE) {
|
if (MACHINE_STATES[item.state] === MACHINE_STATES.FONCTIONNE) {
|
||||||
|
@ -278,7 +302,7 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: 0,
|
right: 0,
|
||||||
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.getCurrentThemeVariables().containerBgColor
|
||||||
}}/>
|
}}/>
|
||||||
<PlatformTouchable
|
<PlatformTouchable
|
||||||
onPress={() => this.showAlert(machineName, item, remainingTime)}
|
onPress={() => this.showAlert(machineName, item, remainingTime)}
|
||||||
|
@ -302,7 +326,7 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
{this.isMachineWatched(item.number) ?
|
{this.isMachineWatched(item.number) ?
|
||||||
<CustomMaterialIcon
|
<CustomMaterialIcon
|
||||||
icon='bell-ring'
|
icon='bell-ring'
|
||||||
color={ThemeManager.getInstance().getCurrentThemeVariables().brandPrimary}
|
color={ThemeManager.getCurrentThemeVariables().brandPrimary}
|
||||||
fontSize={20}
|
fontSize={20}
|
||||||
/> : ''}
|
/> : ''}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -20,9 +20,7 @@ import ThemeManager from '../utils/ThemeManager';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {NavigationActions, StackActions} from "react-navigation";
|
import {NavigationActions, StackActions} from "react-navigation";
|
||||||
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
||||||
import {AsyncStorage} from 'react-native'
|
import AsyncStorageManager from "../utils/AsyncStorageManager";
|
||||||
|
|
||||||
const proxiwashNotifKey = "proxiwashNotifKey";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
|
@ -38,31 +36,18 @@ type State = {
|
||||||
*/
|
*/
|
||||||
export default class SettingsScreen extends React.Component<Props, State> {
|
export default class SettingsScreen extends React.Component<Props, State> {
|
||||||
state = {
|
state = {
|
||||||
nightMode: ThemeManager.getInstance().getNightMode(),
|
nightMode: ThemeManager.getNightMode(),
|
||||||
proxiwashNotifPickerSelected: "5"
|
proxiwashNotifPickerSelected: AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets FetchedData from preferences before rendering components
|
|
||||||
*
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async componentWillMount() {
|
|
||||||
let val = await AsyncStorage.getItem(proxiwashNotifKey);
|
|
||||||
if (val === null)
|
|
||||||
val = "5";
|
|
||||||
this.setState({
|
|
||||||
proxiwashNotifPickerSelected: val,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the value for the proxiwash reminder notification time
|
* Save the value for the proxiwash reminder notification time
|
||||||
*
|
*
|
||||||
* @param value The value to store
|
* @param value The value to store
|
||||||
*/
|
*/
|
||||||
onProxiwashNotifPickerValueChange(value: string) {
|
onProxiwashNotifPickerValueChange(value: string) {
|
||||||
AsyncStorage.setItem(proxiwashNotifKey, value);
|
let key = AsyncStorageManager.getInstance().preferences.proxiwashNotifications.key;
|
||||||
|
AsyncStorageManager.getInstance().savePref(key, value);
|
||||||
this.setState({
|
this.setState({
|
||||||
proxiwashNotifPickerSelected: value
|
proxiwashNotifPickerSelected: value
|
||||||
});
|
});
|
||||||
|
|
66
utils/AsyncStorageManager.js
Normal file
66
utils/AsyncStorageManager.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import {AsyncStorage} from "react-native";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static class used to manage preferences
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default class AsyncStorageManager {
|
||||||
|
|
||||||
|
static instance: AsyncStorageManager | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this class instance or create one if none is found
|
||||||
|
* @returns {ThemeManager}
|
||||||
|
*/
|
||||||
|
static getInstance(): AsyncStorageManager {
|
||||||
|
return AsyncStorageManager.instance === null ?
|
||||||
|
AsyncStorageManager.instance = new AsyncStorageManager() :
|
||||||
|
AsyncStorageManager.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
preferences = {
|
||||||
|
proxiwashNotifications: {
|
||||||
|
key: 'proxiwashNotifications',
|
||||||
|
default: '5',
|
||||||
|
current : '',
|
||||||
|
},
|
||||||
|
proxiwashWatchedMachines : {
|
||||||
|
key: 'proxiwashWatchedMachines',
|
||||||
|
default: '[]',
|
||||||
|
current : '',
|
||||||
|
},
|
||||||
|
nightMode: {
|
||||||
|
key: 'nightMode',
|
||||||
|
default : '0',
|
||||||
|
current : '',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async loadPreferences() {
|
||||||
|
let prefKeys = [];
|
||||||
|
// Get all available keys
|
||||||
|
for (let [key, value] of Object.entries(this.preferences)) {
|
||||||
|
prefKeys.push(value.key);
|
||||||
|
}
|
||||||
|
// Get corresponding values
|
||||||
|
let resultArray : Array<Array<string>> = await AsyncStorage.multiGet(prefKeys);
|
||||||
|
// Save those values for later use
|
||||||
|
for (let i = 0; i < resultArray.length; i++) {
|
||||||
|
let key : string = resultArray[i][0];
|
||||||
|
let val : string | null = resultArray[i][1];
|
||||||
|
if (val === null)
|
||||||
|
val = this.preferences[key].default;
|
||||||
|
this.preferences[key].current = val;
|
||||||
|
}
|
||||||
|
console.log(this.preferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
savePref(key : string, val : string) {
|
||||||
|
this.preferences[key].current = val;
|
||||||
|
AsyncStorage.setItem(key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -46,7 +46,7 @@ export default class NotificationsManager {
|
||||||
* @param time Time at which we should send the notification
|
* @param time Time at which we should send the notification
|
||||||
* @returns {Promise<import("react").ReactText>} Notification Id
|
* @returns {Promise<import("react").ReactText>} Notification Id
|
||||||
*/
|
*/
|
||||||
static async scheduleNotification(title: string, body: string, time: number): Promise<void> {
|
static async scheduleNotification(title: string, body: string, time: number): Promise<string> {
|
||||||
await NotificationsManager.askPermissions();
|
await NotificationsManager.askPermissions();
|
||||||
return Notifications.scheduleLocalNotificationAsync(
|
return Notifications.scheduleLocalNotificationAsync(
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,23 +1,18 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import {AsyncStorage} from 'react-native'
|
|
||||||
import platform from '../native-base-theme/variables/platform';
|
import platform from '../native-base-theme/variables/platform';
|
||||||
import platformDark from '../native-base-theme/variables/platformDark';
|
import platformDark from '../native-base-theme/variables/platformDark';
|
||||||
import getTheme from '../native-base-theme/components';
|
import getTheme from '../native-base-theme/components';
|
||||||
|
import AsyncStorageManager from "./AsyncStorageManager";
|
||||||
const nightModeKey = 'nightMode';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton class used to manage themes
|
* Singleton class used to manage themes
|
||||||
*/
|
*/
|
||||||
export default class ThemeManager {
|
export default class ThemeManager {
|
||||||
|
|
||||||
static instance: ThemeManager | null = null;
|
static instance: ThemeManager | null = null;
|
||||||
nightMode: boolean;
|
|
||||||
updateThemeCallback: Function;
|
updateThemeCallback: Function;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.nightMode = false;
|
|
||||||
this.updateThemeCallback = null;
|
this.updateThemeCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,26 +34,14 @@ export default class ThemeManager {
|
||||||
this.updateThemeCallback = callback;
|
this.updateThemeCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Read async storage to get preferences
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async getDataFromPreferences(): Promise<void> {
|
|
||||||
let result: string = await AsyncStorage.getItem(nightModeKey);
|
|
||||||
|
|
||||||
if (result === '1')
|
|
||||||
this.nightMode = true;
|
|
||||||
// console.log('nightmode: ' + this.nightMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set night mode and save it to preferences
|
* Set night mode and save it to preferences
|
||||||
*
|
*
|
||||||
* @param isNightMode Whether to enable night mode
|
* @param isNightMode Whether to enable night mode
|
||||||
*/
|
*/
|
||||||
setNightMode(isNightMode: boolean) {
|
setNightMode(isNightMode: boolean) {
|
||||||
this.nightMode = isNightMode;
|
let nightModeKey = AsyncStorageManager.getInstance().preferences.nightMode.key;
|
||||||
AsyncStorage.setItem(nightModeKey, isNightMode ? '1' : '0');
|
AsyncStorageManager.getInstance().savePref(nightModeKey, isNightMode ? '1' : '0');
|
||||||
if (this.updateThemeCallback !== null)
|
if (this.updateThemeCallback !== null)
|
||||||
this.updateThemeCallback();
|
this.updateThemeCallback();
|
||||||
}
|
}
|
||||||
|
@ -66,16 +49,16 @@ export default class ThemeManager {
|
||||||
/**
|
/**
|
||||||
* @returns {boolean} Night mode state
|
* @returns {boolean} Night mode state
|
||||||
*/
|
*/
|
||||||
getNightMode(): boolean {
|
static getNightMode(): boolean {
|
||||||
return this.nightMode;
|
return AsyncStorageManager.getInstance().preferences.nightMode.current === '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current theme based on night mode
|
* Get the current theme based on night mode
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
getCurrentTheme(): Object {
|
static getCurrentTheme(): Object {
|
||||||
if (this.nightMode)
|
if (ThemeManager.getNightMode())
|
||||||
return getTheme(platformDark);
|
return getTheme(platformDark);
|
||||||
else
|
else
|
||||||
return getTheme(platform);
|
return getTheme(platform);
|
||||||
|
@ -85,8 +68,8 @@ export default class ThemeManager {
|
||||||
* Get the variables contained in the current theme
|
* Get the variables contained in the current theme
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
getCurrentThemeVariables(): Object {
|
static getCurrentThemeVariables(): Object {
|
||||||
return this.getCurrentTheme().variables;
|
return ThemeManager.getCurrentTheme().variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue