Update proxiwash screen and notifications
This commit is contained in:
parent
e08fdc7c37
commit
27199b85e5
8 changed files with 252 additions and 329 deletions
|
@ -8,7 +8,6 @@
|
||||||
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
|
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
|
||||||
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
|
@ -19,31 +18,33 @@
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
>
|
>
|
||||||
<!-- NOTIFICATIONS -->
|
|
||||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
|
|
||||||
android:value="reminders"/>
|
|
||||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
|
|
||||||
android:value="reminders"/>
|
|
||||||
<!-- Change the resource name to your App's accent color - or any other color you want -->
|
|
||||||
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
|
|
||||||
android:resource="@color/colorPrimary"/> <!-- or @android:color/{name} to use a standard color -->
|
|
||||||
|
|
||||||
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher"/>
|
<!-- START NOTIFICATIONS -->
|
||||||
|
|
||||||
|
<!-- Change the value to true to enable pop-up for in foreground on receiving remote notifications (for prevent duplicating while showing local notifications set this to false) -->
|
||||||
|
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
|
||||||
|
android:value="false"/>
|
||||||
|
Change the resource name to your App's accent color - or any other color you want
|
||||||
|
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
|
||||||
|
android:resource="@color/colorPrimary"/>
|
||||||
|
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
|
||||||
|
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
|
||||||
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
|
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
|
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||||
|
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
|
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
|
||||||
android:exported="false">
|
android:exported="false" >
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
<!-- END NOTIFICATIONS -->
|
||||||
<!-- END NOTIFICATIONS-->
|
|
||||||
|
|
||||||
|
|
||||||
<meta-data android:name="com.facebook.sdk.AutoInitEnabled" android:value="false"/>
|
<meta-data android:name="com.facebook.sdk.AutoInitEnabled" android:value="false"/>
|
||||||
|
|
|
@ -5,22 +5,11 @@ import com.facebook.react.ReactActivity;
|
||||||
import com.facebook.react.ReactActivityDelegate;
|
import com.facebook.react.ReactActivityDelegate;
|
||||||
import com.facebook.react.ReactRootView;
|
import com.facebook.react.ReactRootView;
|
||||||
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
|
|
||||||
import org.devio.rn.splashscreen.SplashScreen;
|
import org.devio.rn.splashscreen.SplashScreen;
|
||||||
|
|
||||||
public class MainActivity extends ReactActivity {
|
public class MainActivity extends ReactActivity {
|
||||||
|
|
||||||
// Added automatically by Expo Config
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged(Configuration newConfig) {
|
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
Intent intent = new Intent("onConfigurationChanged");
|
|
||||||
intent.putExtra("newConfig", newConfig);
|
|
||||||
sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
SplashScreen.show(this, R.style.SplashScreenTheme);
|
SplashScreen.show(this, R.style.SplashScreenTheme);
|
||||||
|
|
15
package-lock.json
generated
15
package-lock.json
generated
|
@ -2530,6 +2530,12 @@
|
||||||
"@types/xdate": "*"
|
"@types/xdate": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-native-push-notification": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-native-push-notification/-/react-native-push-notification-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-4kErWFa0qit8qzPB6Nbp7kG9NiwDyKu5XxrNlrCIc1zoFxu48ABeofVvNCKv2RtlmFvCftibtykeysRZCeuT8A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/react-native-vector-icons": {
|
"@types/react-native-vector-icons": {
|
||||||
"version": "6.4.6",
|
"version": "6.4.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-native-vector-icons/-/react-native-vector-icons-6.4.6.tgz",
|
||||||
|
@ -10684,12 +10690,9 @@
|
||||||
"integrity": "sha512-8xiEnU29qHZcT05XXwhPHiLChTt82Pn5Z/nFdDOYGNFZ+IYSbYeGmIxFpratCRO6dgLptNaDFDPiyw2X7UZTeg=="
|
"integrity": "sha512-8xiEnU29qHZcT05XXwhPHiLChTt82Pn5Z/nFdDOYGNFZ+IYSbYeGmIxFpratCRO6dgLptNaDFDPiyw2X7UZTeg=="
|
||||||
},
|
},
|
||||||
"react-native-push-notification": {
|
"react-native-push-notification": {
|
||||||
"version": "5.1.1",
|
"version": "7.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-7.3.0.tgz",
|
||||||
"integrity": "sha512-CJmKqzM2P/s+a9PImoaiUN4TP1+K4YfmG1B0uUbavgFdGhTtRPTLLwDfFk2h3J6VmTXNak82rUz2iGwyptHm5w==",
|
"integrity": "sha512-Ofy8dYAhIkFJKxQDvAn7BnXxwtun1SMnqLjZUhRTRzhPEqN0tW7TmIjfyYanNf/lnggRYZqFO+b14Ul3nhlMGw=="
|
||||||
"requires": {
|
|
||||||
"@react-native-community/push-notification-ios": "^1.4.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"react-native-reanimated": {
|
"react-native-reanimated": {
|
||||||
"version": "1.13.2",
|
"version": "1.13.2",
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"react-native-modalize": "2.0.8",
|
"react-native-modalize": "2.0.8",
|
||||||
"react-native-paper": "4.8.1",
|
"react-native-paper": "4.8.1",
|
||||||
"react-native-permissions": "3.0.3",
|
"react-native-permissions": "3.0.3",
|
||||||
"react-native-push-notification": "5.1.1",
|
"react-native-push-notification": "7.3.0",
|
||||||
"react-native-reanimated": "1.13.2",
|
"react-native-reanimated": "1.13.2",
|
||||||
"react-native-render-html": "5.1.0",
|
"react-native-render-html": "5.1.0",
|
||||||
"react-native-safe-area-context": "3.2.0",
|
"react-native-safe-area-context": "3.2.0",
|
||||||
|
@ -65,6 +65,7 @@
|
||||||
"@types/react": "17.0.3",
|
"@types/react": "17.0.3",
|
||||||
"@types/react-native": "0.64.4",
|
"@types/react-native": "0.64.4",
|
||||||
"@types/react-native-calendars": "1.20.10",
|
"@types/react-native-calendars": "1.20.10",
|
||||||
|
"@types/react-native-push-notification": "^7.2.0",
|
||||||
"@types/react-native-vector-icons": "6.4.6",
|
"@types/react-native-vector-icons": "6.4.6",
|
||||||
"@types/react-test-renderer": "17.0.1",
|
"@types/react-test-renderer": "17.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "4.22.1",
|
"@typescript-eslint/eslint-plugin": "4.22.1",
|
||||||
|
@ -94,7 +95,9 @@
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-undef": 0,
|
"no-undef": 0,
|
||||||
"no-shadow": "off",
|
"no-shadow": "off",
|
||||||
"@typescript-eslint/no-shadow": ["error"],
|
"@typescript-eslint/no-shadow": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
"prettier/prettier": [
|
"prettier/prettier": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,27 +17,28 @@
|
||||||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from 'react';
|
import React, { Ref } from 'react';
|
||||||
import { useTheme } from 'react-native-paper';
|
import { useTheme } from 'react-native-paper';
|
||||||
import { Modalize } from 'react-native-modalize';
|
import { Modalize } from 'react-native-modalize';
|
||||||
import { View } from 'react-native-animatable';
|
import { View } from 'react-native-animatable';
|
||||||
import { TAB_BAR_HEIGHT } from '../Tabbar/CustomTabBar';
|
import { TAB_BAR_HEIGHT } from '../Tabbar/CustomTabBar';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children?: React.ReactChild | null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstraction layer for Modalize component, using custom configuration
|
* Abstraction layer for Modalize component, using custom configuration
|
||||||
*
|
*
|
||||||
* @param props Props to pass to the element. Must specify an onRef prop to get an Modalize ref.
|
* @param props Props to pass to the element. Must specify an onRef prop to get an Modalize ref.
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
function CustomModal(props: {
|
function CustomModal(props: Props, ref?: Ref<Modalize>) {
|
||||||
onRef: (re: Modalize) => void;
|
|
||||||
children?: React.ReactNode;
|
|
||||||
}) {
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { onRef, children } = props;
|
const { children } = props;
|
||||||
return (
|
return (
|
||||||
<Modalize
|
<Modalize
|
||||||
ref={onRef}
|
ref={ref}
|
||||||
adjustToContentHeight
|
adjustToContentHeight
|
||||||
handlePosition="inside"
|
handlePosition="inside"
|
||||||
modalStyle={{ backgroundColor: theme.colors.card }}
|
modalStyle={{ backgroundColor: theme.colors.card }}
|
||||||
|
@ -54,4 +55,4 @@ function CustomModal(props: {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CustomModal;
|
export default React.forwardRef(CustomModal);
|
||||||
|
|
|
@ -17,20 +17,17 @@
|
||||||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from 'react';
|
import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Alert,
|
|
||||||
SectionListData,
|
SectionListData,
|
||||||
SectionListRenderItemInfo,
|
SectionListRenderItemInfo,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import { Avatar, Button, Card, Text, withTheme } from 'react-native-paper';
|
import { Avatar, Button, Card, Text, useTheme } from 'react-native-paper';
|
||||||
import { StackNavigationProp } from '@react-navigation/stack';
|
|
||||||
import { Modalize } from 'react-native-modalize';
|
import { Modalize } from 'react-native-modalize';
|
||||||
import WebSectionList from '../../components/Screens/WebSectionList';
|
import WebSectionList from '../../components/Screens/WebSectionList';
|
||||||
import * as Notifications from '../../utils/Notifications';
|
|
||||||
import AsyncStorageManager from '../../managers/AsyncStorageManager';
|
import AsyncStorageManager from '../../managers/AsyncStorageManager';
|
||||||
import ProxiwashListItem from '../../components/Lists/Proxiwash/ProxiwashListItem';
|
import ProxiwashListItem from '../../components/Lists/Proxiwash/ProxiwashListItem';
|
||||||
import ProxiwashConstants, {
|
import ProxiwashConstants, {
|
||||||
|
@ -53,6 +50,8 @@ import type { SectionListDataType } from '../../components/Screens/WebSectionLis
|
||||||
import type { LaundromatType } from './ProxiwashAboutScreen';
|
import type { LaundromatType } from './ProxiwashAboutScreen';
|
||||||
import GENERAL_STYLES from '../../constants/Styles';
|
import GENERAL_STYLES from '../../constants/Styles';
|
||||||
import { readData } from '../../utils/WebData';
|
import { readData } from '../../utils/WebData';
|
||||||
|
import { useFocusEffect, useNavigation } from '@react-navigation/core';
|
||||||
|
import { setupMachineNotification } from '../../utils/Notifications';
|
||||||
|
|
||||||
const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
|
const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
|
||||||
const LIST_ITEM_HEIGHT = 64;
|
const LIST_ITEM_HEIGHT = 64;
|
||||||
|
@ -68,17 +67,6 @@ export type ProxiwashMachineType = {
|
||||||
program: string;
|
program: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PropsType = {
|
|
||||||
navigation: StackNavigationProp<any>;
|
|
||||||
theme: ReactNativePaper.Theme;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StateType = {
|
|
||||||
modalCurrentDisplayItem: React.ReactNode;
|
|
||||||
machinesWatched: Array<ProxiwashMachineType>;
|
|
||||||
selectedWash: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type FetchedDataType = {
|
type FetchedDataType = {
|
||||||
dryers: Array<ProxiwashMachineType>;
|
dryers: Array<ProxiwashMachineType>;
|
||||||
washers: Array<ProxiwashMachineType>;
|
washers: Array<ProxiwashMachineType>;
|
||||||
|
@ -99,22 +87,28 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
function ProxiwashScreen() {
|
||||||
* Class defining the app's proxiwash screen. This screen shows information about washing machines and
|
const navigation = useNavigation();
|
||||||
* dryers, taken from a scrapper reading proxiwash website
|
const theme = useTheme();
|
||||||
*/
|
const [
|
||||||
class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
modalCurrentDisplayItem,
|
||||||
/**
|
setModalCurrentDisplayItem,
|
||||||
* Shows a warning telling the user notifications are disabled for the app
|
] = useState<React.ReactElement | null>(null);
|
||||||
*/
|
const [machinesWatched, setMachinesWatched] = useState<
|
||||||
static showNotificationsDisabledWarning() {
|
Array<ProxiwashMachineType>
|
||||||
Alert.alert(
|
>(
|
||||||
i18n.t('screens.proxiwash.modal.notificationErrorTitle'),
|
AsyncStorageManager.getObject(
|
||||||
i18n.t('screens.proxiwash.modal.notificationErrorDescription')
|
AsyncStorageManager.PREFERENCES.proxiwashWatchedMachines.key
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
modalStateStrings: { [key in MachineStates]: string } = {
|
const [selectedWash, setSelectedWash] = useState(
|
||||||
|
AsyncStorageManager.getString(
|
||||||
|
AsyncStorageManager.PREFERENCES.selectedWash.key
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const modalStateStrings: { [key in MachineStates]: string } = {
|
||||||
[MachineStates.AVAILABLE]: i18n.t('screens.proxiwash.modal.ready'),
|
[MachineStates.AVAILABLE]: i18n.t('screens.proxiwash.modal.ready'),
|
||||||
[MachineStates.RUNNING]: i18n.t('screens.proxiwash.modal.running'),
|
[MachineStates.RUNNING]: i18n.t('screens.proxiwash.modal.running'),
|
||||||
[MachineStates.RUNNING_NOT_STARTED]: i18n.t(
|
[MachineStates.RUNNING_NOT_STARTED]: i18n.t(
|
||||||
|
@ -126,95 +120,48 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
[MachineStates.UNKNOWN]: i18n.t('screens.proxiwash.modal.unknown'),
|
[MachineStates.UNKNOWN]: i18n.t('screens.proxiwash.modal.unknown'),
|
||||||
};
|
};
|
||||||
|
|
||||||
modalRef: null | Modalize;
|
const modalRef = useRef<Modalize>(null);
|
||||||
|
|
||||||
fetchedData: {
|
useLayoutEffect(() => {
|
||||||
dryers: Array<ProxiwashMachineType>;
|
|
||||||
washers: Array<ProxiwashMachineType>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates machine state parameters using current theme and translations
|
|
||||||
*/
|
|
||||||
constructor(props: PropsType) {
|
|
||||||
super(props);
|
|
||||||
this.modalRef = null;
|
|
||||||
this.fetchedData = { dryers: [], washers: [] };
|
|
||||||
this.state = {
|
|
||||||
modalCurrentDisplayItem: null,
|
|
||||||
machinesWatched: AsyncStorageManager.getObject(
|
|
||||||
AsyncStorageManager.PREFERENCES.proxiwashWatchedMachines.key
|
|
||||||
),
|
|
||||||
selectedWash: AsyncStorageManager.getString(
|
|
||||||
AsyncStorageManager.PREFERENCES.selectedWash.key
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup notification channel for android and add listeners to detect notifications fired
|
|
||||||
*/
|
|
||||||
componentDidMount() {
|
|
||||||
const { navigation } = this.props;
|
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
<MaterialHeaderButtons>
|
<MaterialHeaderButtons>
|
||||||
<Item
|
<Item
|
||||||
title="switch"
|
title={'switch'}
|
||||||
iconName="swap-horizontal"
|
iconName={'swap-horizontal'}
|
||||||
onPress={(): void => navigation.navigate('settings')}
|
onPress={() => navigation.navigate('settings')}
|
||||||
/>
|
/>
|
||||||
<Item
|
<Item
|
||||||
title="information"
|
title={'information'}
|
||||||
iconName="information"
|
iconName={'information'}
|
||||||
onPress={this.onAboutPress}
|
onPress={() => navigation.navigate('proxiwash-about')}
|
||||||
/>
|
/>
|
||||||
</MaterialHeaderButtons>
|
</MaterialHeaderButtons>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
navigation.addListener('focus', this.onScreenFocus);
|
}, [navigation]);
|
||||||
}
|
|
||||||
|
|
||||||
onScreenFocus = () => {
|
useFocusEffect(
|
||||||
const { state } = this;
|
useCallback(() => {
|
||||||
const selected = AsyncStorageManager.getString(
|
const selected = AsyncStorageManager.getString(
|
||||||
AsyncStorageManager.PREFERENCES.selectedWash.key
|
AsyncStorageManager.PREFERENCES.selectedWash.key
|
||||||
);
|
);
|
||||||
if (selected !== state.selectedWash) {
|
if (selected !== selectedWash) {
|
||||||
this.setState({
|
setSelectedWash(selected);
|
||||||
selectedWash: selected,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
}, [selectedWash])
|
||||||
|
);
|
||||||
/**
|
|
||||||
* Callback used when pressing the about button.
|
|
||||||
* This will open the ProxiwashAboutScreen.
|
|
||||||
*/
|
|
||||||
onAboutPress = () => {
|
|
||||||
const { navigation } = this.props;
|
|
||||||
navigation.navigate('proxiwash-about');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback used when the user clicks on enable notifications for a machine
|
* Callback used when the user clicks on enable notifications for a machine
|
||||||
*
|
*
|
||||||
* @param machine The machine to set notifications for
|
* @param machine The machine to set notifications for
|
||||||
*/
|
*/
|
||||||
onSetupNotificationsPress(machine: ProxiwashMachineType) {
|
const onSetupNotificationsPress = (machine: ProxiwashMachineType) => {
|
||||||
if (this.modalRef) {
|
if (modalRef.current) {
|
||||||
this.modalRef.close();
|
modalRef.current.close();
|
||||||
}
|
}
|
||||||
this.setupNotifications(machine);
|
setupNotifications(machine);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback used when receiving modal ref
|
|
||||||
*
|
|
||||||
* @param ref
|
|
||||||
*/
|
|
||||||
onModalRef = (ref: Modalize) => {
|
|
||||||
this.modalRef = ref;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,11 +173,14 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param isDryer True if the given item is a dryer
|
* @param isDryer True if the given item is a dryer
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
getModalContent(title: string, item: ProxiwashMachineType, isDryer: boolean) {
|
const getModalContent = (
|
||||||
const { props, state } = this;
|
title: string,
|
||||||
|
item: ProxiwashMachineType,
|
||||||
|
isDryer: boolean
|
||||||
|
) => {
|
||||||
let button: { text: string; icon: string; onPress: () => void } | undefined;
|
let button: { text: string; icon: string; onPress: () => void } | undefined;
|
||||||
let message = this.modalStateStrings[item.state];
|
let message = modalStateStrings[item.state];
|
||||||
const onPress = () => this.onSetupNotificationsPress(item);
|
const onPress = () => onSetupNotificationsPress(item);
|
||||||
if (item.state === MachineStates.RUNNING) {
|
if (item.state === MachineStates.RUNNING) {
|
||||||
let remainingTime = parseInt(item.remainingTime, 10);
|
let remainingTime = parseInt(item.remainingTime, 10);
|
||||||
if (remainingTime < 0) {
|
if (remainingTime < 0) {
|
||||||
|
@ -238,7 +188,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
button = {
|
button = {
|
||||||
text: isMachineWatched(item, state.machinesWatched)
|
text: isMachineWatched(item, machinesWatched)
|
||||||
? i18n.t('screens.proxiwash.modal.disableNotifications')
|
? i18n.t('screens.proxiwash.modal.disableNotifications')
|
||||||
: i18n.t('screens.proxiwash.modal.enableNotifications'),
|
: i18n.t('screens.proxiwash.modal.enableNotifications'),
|
||||||
icon: '',
|
icon: '',
|
||||||
|
@ -258,7 +208,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
left={() => (
|
left={() => (
|
||||||
<Avatar.Icon
|
<Avatar.Icon
|
||||||
icon={isDryer ? 'tumble-dryer' : 'washing-machine'}
|
icon={isDryer ? 'tumble-dryer' : 'washing-machine'}
|
||||||
color={props.theme.colors.text}
|
color={theme.colors.text}
|
||||||
style={styles.icon}
|
style={styles.icon}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -281,7 +231,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the section render item
|
* Gets the section render item
|
||||||
|
@ -289,13 +239,13 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param section The section to render
|
* @param section The section to render
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
getRenderSectionHeader = ({
|
const getRenderSectionHeader = ({
|
||||||
section,
|
section,
|
||||||
}: {
|
}: {
|
||||||
section: SectionListData<ProxiwashMachineType>;
|
section: SectionListData<ProxiwashMachineType>;
|
||||||
}) => {
|
}) => {
|
||||||
const isDryer = section.title === i18n.t('screens.proxiwash.dryers');
|
const isDryer = section.title === i18n.t('screens.proxiwash.dryers');
|
||||||
const nbAvailable = this.getMachineAvailableNumber(isDryer);
|
const nbAvailable = getMachineAvailableNumber(section.data);
|
||||||
return (
|
return (
|
||||||
<ProxiwashSectionHeader
|
<ProxiwashSectionHeader
|
||||||
title={section.title}
|
title={section.title}
|
||||||
|
@ -312,13 +262,14 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param section The object describing the current SectionList section
|
* @param section The object describing the current SectionList section
|
||||||
* @returns {React.Node}
|
* @returns {React.Node}
|
||||||
*/
|
*/
|
||||||
getRenderItem = (data: SectionListRenderItemInfo<ProxiwashMachineType>) => {
|
const getRenderItem = (
|
||||||
const { machinesWatched } = this.state;
|
data: SectionListRenderItemInfo<ProxiwashMachineType>
|
||||||
|
) => {
|
||||||
const isDryer = data.section.title === i18n.t('screens.proxiwash.dryers');
|
const isDryer = data.section.title === i18n.t('screens.proxiwash.dryers');
|
||||||
return (
|
return (
|
||||||
<ProxiwashListItem
|
<ProxiwashListItem
|
||||||
item={data.item}
|
item={data.item}
|
||||||
onPress={this.showModal}
|
onPress={showModal}
|
||||||
isWatched={isMachineWatched(data.item, machinesWatched)}
|
isWatched={isMachineWatched(data.item, machinesWatched)}
|
||||||
isDryer={isDryer}
|
isDryer={isDryer}
|
||||||
height={LIST_ITEM_HEIGHT}
|
height={LIST_ITEM_HEIGHT}
|
||||||
|
@ -332,7 +283,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param item The item to extract the key from
|
* @param item The item to extract the key from
|
||||||
* @return {*} The extracted key
|
* @return {*} The extracted key
|
||||||
*/
|
*/
|
||||||
getKeyExtractor = (item: ProxiwashMachineType): string => item.number;
|
const getKeyExtractor = (item: ProxiwashMachineType): string => item.number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setups notifications for the machine with the given ID.
|
* Setups notifications for the machine with the given ID.
|
||||||
|
@ -341,28 +292,19 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
*
|
*
|
||||||
* @param machine The machine to watch
|
* @param machine The machine to watch
|
||||||
*/
|
*/
|
||||||
setupNotifications(machine: ProxiwashMachineType) {
|
const setupNotifications = (machine: ProxiwashMachineType) => {
|
||||||
const { machinesWatched } = this.state;
|
|
||||||
if (!isMachineWatched(machine, machinesWatched)) {
|
if (!isMachineWatched(machine, machinesWatched)) {
|
||||||
Notifications.setupMachineNotification(
|
setupMachineNotification(
|
||||||
machine.number,
|
machine.number,
|
||||||
true,
|
true,
|
||||||
getMachineEndDate(machine)
|
getMachineEndDate(machine)
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
this.saveNotificationToState(machine);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
ProxiwashScreen.showNotificationsDisabledWarning();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Notifications.setupMachineNotification(machine.number, false, null).then(
|
|
||||||
() => {
|
|
||||||
this.removeNotificationFromState(machine);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
saveNotificationToState(machine);
|
||||||
|
} else {
|
||||||
|
setupMachineNotification(machine.number, false);
|
||||||
|
removeNotificationFromState(machine);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of machines available
|
* Gets the number of machines available
|
||||||
|
@ -370,13 +312,9 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param isDryer True if we are only checking for dryer, false for washers
|
* @param isDryer True if we are only checking for dryer, false for washers
|
||||||
* @return {number} The number of machines available
|
* @return {number} The number of machines available
|
||||||
*/
|
*/
|
||||||
getMachineAvailableNumber(isDryer: boolean): number {
|
const getMachineAvailableNumber = (
|
||||||
let data;
|
data: ReadonlyArray<ProxiwashMachineType>
|
||||||
if (isDryer) {
|
): number => {
|
||||||
data = this.fetchedData.dryers;
|
|
||||||
} else {
|
|
||||||
data = this.fetchedData.washers;
|
|
||||||
}
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
data.forEach((machine: ProxiwashMachineType) => {
|
data.forEach((machine: ProxiwashMachineType) => {
|
||||||
if (machine.state === MachineStates.AVAILABLE) {
|
if (machine.state === MachineStates.AVAILABLE) {
|
||||||
|
@ -384,7 +322,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return count;
|
return count;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the dataset to be used by the FlatList
|
* Creates the dataset to be used by the FlatList
|
||||||
|
@ -392,10 +330,9 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param fetchedData
|
* @param fetchedData
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
createDataset = (
|
const createDataset = (
|
||||||
fetchedData: FetchedDataType | undefined
|
fetchedData: FetchedDataType | undefined
|
||||||
): SectionListDataType<ProxiwashMachineType> => {
|
): SectionListDataType<ProxiwashMachineType> => {
|
||||||
const { state } = this;
|
|
||||||
if (fetchedData) {
|
if (fetchedData) {
|
||||||
let data = fetchedData;
|
let data = fetchedData;
|
||||||
if (AprilFoolsManager.getInstance().isAprilFoolsEnabled()) {
|
if (AprilFoolsManager.getInstance().isAprilFoolsEnabled()) {
|
||||||
|
@ -403,24 +340,26 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
AprilFoolsManager.getNewProxiwashDryerOrderedList(data.dryers);
|
AprilFoolsManager.getNewProxiwashDryerOrderedList(data.dryers);
|
||||||
AprilFoolsManager.getNewProxiwashWasherOrderedList(data.washers);
|
AprilFoolsManager.getNewProxiwashWasherOrderedList(data.washers);
|
||||||
}
|
}
|
||||||
this.fetchedData = data;
|
fetchedData = data;
|
||||||
// TODO dirty, should be refactored
|
const cleanedList = getCleanedMachineWatched(machinesWatched, [
|
||||||
this.state.machinesWatched = getCleanedMachineWatched(
|
...data.dryers,
|
||||||
state.machinesWatched,
|
...data.washers,
|
||||||
[...data.dryers, ...data.washers]
|
]);
|
||||||
);
|
if (cleanedList !== machinesWatched) {
|
||||||
|
setMachinesWatched(machinesWatched);
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: i18n.t('screens.proxiwash.dryers'),
|
title: i18n.t('screens.proxiwash.dryers'),
|
||||||
icon: 'tumble-dryer',
|
icon: 'tumble-dryer',
|
||||||
data: data.dryers === undefined ? [] : data.dryers,
|
data: data.dryers === undefined ? [] : data.dryers,
|
||||||
keyExtractor: this.getKeyExtractor,
|
keyExtractor: getKeyExtractor,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18n.t('screens.proxiwash.washers'),
|
title: i18n.t('screens.proxiwash.washers'),
|
||||||
icon: 'washing-machine',
|
icon: 'washing-machine',
|
||||||
data: data.washers === undefined ? [] : data.washers,
|
data: data.washers === undefined ? [] : data.washers,
|
||||||
keyExtractor: this.getKeyExtractor,
|
keyExtractor: getKeyExtractor,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
|
@ -428,15 +367,6 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback used when the user clicks on the navigate to settings button.
|
|
||||||
* This will hide the banner and open the SettingsScreen
|
|
||||||
*/
|
|
||||||
onGoToSettings = () => {
|
|
||||||
const { navigation } = this.props;
|
|
||||||
navigation.navigate('settings');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a modal for the given item
|
* Shows a modal for the given item
|
||||||
*
|
*
|
||||||
|
@ -444,12 +374,14 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
* @param item The item to display information for in the modal
|
* @param item The item to display information for in the modal
|
||||||
* @param isDryer True if the given item is a dryer
|
* @param isDryer True if the given item is a dryer
|
||||||
*/
|
*/
|
||||||
showModal = (title: string, item: ProxiwashMachineType, isDryer: boolean) => {
|
const showModal = (
|
||||||
this.setState({
|
title: string,
|
||||||
modalCurrentDisplayItem: this.getModalContent(title, item, isDryer),
|
item: ProxiwashMachineType,
|
||||||
});
|
isDryer: boolean
|
||||||
if (this.modalRef) {
|
) => {
|
||||||
this.modalRef.open();
|
setModalCurrentDisplayItem(getModalContent(title, item, isDryer));
|
||||||
|
if (modalRef.current) {
|
||||||
|
modalRef.current.open();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -458,44 +390,36 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
*
|
*
|
||||||
* @param machine
|
* @param machine
|
||||||
*/
|
*/
|
||||||
saveNotificationToState(machine: ProxiwashMachineType) {
|
const saveNotificationToState = (machine: ProxiwashMachineType) => {
|
||||||
const { machinesWatched } = this.state;
|
let data = [...machinesWatched];
|
||||||
const data = machinesWatched;
|
|
||||||
data.push(machine);
|
data.push(machine);
|
||||||
this.saveNewWatchedList(data);
|
saveNewWatchedList(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given index from the watchlist array and saves it to preferences
|
* Removes the given index from the watchlist array and saves it to preferences
|
||||||
*
|
*
|
||||||
* @param selectedMachine
|
* @param selectedMachine
|
||||||
*/
|
*/
|
||||||
removeNotificationFromState(selectedMachine: ProxiwashMachineType) {
|
const removeNotificationFromState = (
|
||||||
const { machinesWatched } = this.state;
|
selectedMachine: ProxiwashMachineType
|
||||||
const newList = [...machinesWatched];
|
) => {
|
||||||
machinesWatched.forEach((machine: ProxiwashMachineType, index: number) => {
|
const newList = machinesWatched.filter(
|
||||||
if (
|
(m) => m.number !== selectedMachine.number
|
||||||
machine.number === selectedMachine.number &&
|
);
|
||||||
machine.endTime === selectedMachine.endTime
|
saveNewWatchedList(newList);
|
||||||
) {
|
};
|
||||||
newList.splice(index, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.saveNewWatchedList(newList);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveNewWatchedList(list: Array<ProxiwashMachineType>) {
|
const saveNewWatchedList = (list: Array<ProxiwashMachineType>) => {
|
||||||
this.setState({ machinesWatched: list });
|
setMachinesWatched(list);
|
||||||
AsyncStorageManager.set(
|
AsyncStorageManager.set(
|
||||||
AsyncStorageManager.PREFERENCES.proxiwashWatchedMachines.key,
|
AsyncStorageManager.PREFERENCES.proxiwashWatchedMachines.key,
|
||||||
list
|
list
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
|
||||||
const { state } = this;
|
|
||||||
let data: LaundromatType;
|
let data: LaundromatType;
|
||||||
switch (state.selectedWash) {
|
switch (selectedWash) {
|
||||||
case 'tripodeB':
|
case 'tripodeB':
|
||||||
data = ProxiwashConstants.tripodeB;
|
data = ProxiwashConstants.tripodeB;
|
||||||
break;
|
break;
|
||||||
|
@ -507,12 +431,12 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<WebSectionList
|
<WebSectionList
|
||||||
request={() => readData<FetchedDataType>(data.url)}
|
request={() => readData<FetchedDataType>(data.url)}
|
||||||
createDataset={this.createDataset}
|
createDataset={createDataset}
|
||||||
renderItem={this.getRenderItem}
|
renderItem={getRenderItem}
|
||||||
renderSectionHeader={this.getRenderSectionHeader}
|
renderSectionHeader={getRenderSectionHeader}
|
||||||
autoRefreshTime={REFRESH_TIME}
|
autoRefreshTime={REFRESH_TIME}
|
||||||
refreshOnFocus={true}
|
refreshOnFocus={true}
|
||||||
extraData={state.machinesWatched.length}
|
extraData={machinesWatched.length}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<MascotPopup
|
<MascotPopup
|
||||||
|
@ -524,7 +448,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
action: {
|
action: {
|
||||||
message: i18n.t('screens.proxiwash.mascotDialog.ok'),
|
message: i18n.t('screens.proxiwash.mascotDialog.ok'),
|
||||||
icon: 'cog',
|
icon: 'cog',
|
||||||
onPress: this.onGoToSettings,
|
onPress: () => navigation.navigate('settings'),
|
||||||
},
|
},
|
||||||
cancel: {
|
cancel: {
|
||||||
message: i18n.t('screens.proxiwash.mascotDialog.cancel'),
|
message: i18n.t('screens.proxiwash.mascotDialog.cancel'),
|
||||||
|
@ -533,12 +457,9 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
|
||||||
}}
|
}}
|
||||||
emotion={MASCOT_STYLE.NORMAL}
|
emotion={MASCOT_STYLE.NORMAL}
|
||||||
/>
|
/>
|
||||||
<CustomModal onRef={this.onModalRef}>
|
<CustomModal ref={modalRef}>{modalCurrentDisplayItem}</CustomModal>
|
||||||
{state.modalCurrentDisplayItem}
|
|
||||||
</CustomModal>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(ProxiwashScreen);
|
export default ProxiwashScreen;
|
||||||
|
|
|
@ -17,44 +17,59 @@
|
||||||
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
|
||||||
checkNotifications,
|
|
||||||
requestNotifications,
|
|
||||||
RESULTS,
|
|
||||||
} from 'react-native-permissions';
|
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import AsyncStorageManager from '../managers/AsyncStorageManager';
|
import AsyncStorageManager from '../managers/AsyncStorageManager';
|
||||||
|
import PushNotificationIOS from '@react-native-community/push-notification-ios';
|
||||||
const PushNotification = require('react-native-push-notification');
|
import PushNotification from 'react-native-push-notification';
|
||||||
|
import { Platform } from 'react-native';
|
||||||
|
|
||||||
// Used to multiply the normal notification id to create the reminder one. It allows to find it back easily
|
// Used to multiply the normal notification id to create the reminder one. It allows to find it back easily
|
||||||
const reminderIdFactor = 100;
|
const reminderIdFactor = 100;
|
||||||
|
|
||||||
/**
|
PushNotification.createChannel(
|
||||||
* Async function asking permission to send notifications to the user.
|
{
|
||||||
* Used on ios.
|
channelId: 'reminders', // (required)
|
||||||
*
|
channelName: 'Reminders', // (required)
|
||||||
* @returns {Promise<void>}
|
channelDescription: 'Get laundry reminders', // (optional) default: undefined.
|
||||||
|
playSound: true, // (optional) default: true
|
||||||
|
soundName: 'default', // (optional) See `soundName` parameter of `localNotification` function
|
||||||
|
importance: 4, // (optional) default: 4. Int value of the Android notification importance
|
||||||
|
vibrate: true, // (optional) default: true. Creates the default vibration patten if true.
|
||||||
|
},
|
||||||
|
(created) => console.log(`createChannel returned '${created}'`) // (optional) callback returns whether the channel was created, false means it already existed.
|
||||||
|
);
|
||||||
|
|
||||||
|
PushNotification.configure({
|
||||||
|
// (required) Called when a remote is received or opened, or local notification is opened
|
||||||
|
onNotification: function (notification) {
|
||||||
|
console.log('NOTIFICATION:', notification);
|
||||||
|
|
||||||
|
// process the notification
|
||||||
|
|
||||||
|
// (required) Called when a remote is received or opened, or local notification is opened
|
||||||
|
notification.finish(PushNotificationIOS.FetchResult.NoData);
|
||||||
|
},
|
||||||
|
|
||||||
|
// IOS ONLY (optional): default: all - Permissions to register.
|
||||||
|
permissions: {
|
||||||
|
alert: true,
|
||||||
|
badge: true,
|
||||||
|
sound: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Should the initial notification be popped automatically
|
||||||
|
// default: true
|
||||||
|
popInitialNotification: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (optional) default: true
|
||||||
|
* - Specified if permissions (ios) and token (android and ios) will requested or not,
|
||||||
|
* - if not, you must call PushNotificationsHandler.requestPermissions() later
|
||||||
|
* - if you are not using remote notification or do not have Firebase installed, use this:
|
||||||
|
* requestPermissions: Platform.OS === 'ios'
|
||||||
*/
|
*/
|
||||||
export async function askPermissions(): Promise<void> {
|
requestPermissions: Platform.OS === 'ios',
|
||||||
return new Promise((resolve: () => void, reject: () => void) => {
|
});
|
||||||
checkNotifications().then(({ status }: { status: string }) => {
|
|
||||||
if (status === RESULTS.GRANTED) {
|
|
||||||
resolve();
|
|
||||||
} else if (status === RESULTS.BLOCKED) {
|
|
||||||
reject();
|
|
||||||
} else {
|
|
||||||
requestNotifications([]).then((result: { status: string }) => {
|
|
||||||
if (result.status === RESULTS.GRANTED) {
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a notification for the given machine id at the given date.
|
* Creates a notification for the given machine id at the given date.
|
||||||
|
@ -79,7 +94,7 @@ function createNotifications(machineID: string, date: Date) {
|
||||||
message: i18n.t('screens.proxiwash.notifications.machineRunningBody', {
|
message: i18n.t('screens.proxiwash.notifications.machineRunningBody', {
|
||||||
number: machineID,
|
number: machineID,
|
||||||
}),
|
}),
|
||||||
id: id.toString(),
|
id: id,
|
||||||
date: reminderDate,
|
date: reminderDate,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -89,7 +104,7 @@ function createNotifications(machineID: string, date: Date) {
|
||||||
message: i18n.t('screens.proxiwash.notifications.machineFinishedBody', {
|
message: i18n.t('screens.proxiwash.notifications.machineFinishedBody', {
|
||||||
number: machineID,
|
number: machineID,
|
||||||
}),
|
}),
|
||||||
id: machineID,
|
id: parseInt(machineID, 10),
|
||||||
date,
|
date,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -104,26 +119,16 @@ function createNotifications(machineID: string, date: Date) {
|
||||||
* @param isEnabled True to enable notifications, false to disable
|
* @param isEnabled True to enable notifications, false to disable
|
||||||
* @param endDate The trigger date, or null if disabling notifications
|
* @param endDate The trigger date, or null if disabling notifications
|
||||||
*/
|
*/
|
||||||
export async function setupMachineNotification(
|
export function setupMachineNotification(
|
||||||
machineID: string,
|
machineID: string,
|
||||||
isEnabled: boolean,
|
isEnabled: boolean,
|
||||||
endDate: Date | null
|
endDate?: Date | null
|
||||||
): Promise<void> {
|
) {
|
||||||
return new Promise((resolve: () => void, reject: () => void) => {
|
if (isEnabled && endDate) {
|
||||||
if (isEnabled && endDate != null) {
|
|
||||||
askPermissions()
|
|
||||||
.then(() => {
|
|
||||||
createNotifications(machineID, endDate);
|
createNotifications(machineID, endDate);
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
reject();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
PushNotification.cancelLocalNotifications({ id: machineID });
|
PushNotification.cancelLocalNotifications({ id: machineID });
|
||||||
const reminderId = reminderIdFactor * parseInt(machineID, 10);
|
const reminderId = reminderIdFactor * parseInt(machineID, 10);
|
||||||
PushNotification.cancelLocalNotifications({ id: reminderId.toString() });
|
PushNotification.cancelLocalNotifications({ id: reminderId.toString() });
|
||||||
resolve();
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue