forked from vergnet/application-amicale
Replaced local notifications with push notifications
This commit is contained in:
parent
728e72b503
commit
8d4223333f
9 changed files with 103 additions and 93 deletions
4
App.js
4
App.js
|
@ -13,6 +13,8 @@ import * as Font from 'expo-font';
|
||||||
import {clearThemeCache} from 'native-base-shoutem-theme';
|
import {clearThemeCache} from 'native-base-shoutem-theme';
|
||||||
import AsyncStorageManager from "./utils/AsyncStorageManager";
|
import AsyncStorageManager from "./utils/AsyncStorageManager";
|
||||||
import CustomIntroSlider from "./components/CustomIntroSlider";
|
import CustomIntroSlider from "./components/CustomIntroSlider";
|
||||||
|
import {Notifications} from 'expo';
|
||||||
|
import NotificationsManager from "./utils/NotificationsManager";
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
|
@ -47,6 +49,8 @@ export default class App extends React.Component<Props, State> {
|
||||||
});
|
});
|
||||||
await AsyncStorageManager.getInstance().loadPreferences();
|
await AsyncStorageManager.getInstance().loadPreferences();
|
||||||
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
ThemeManager.getInstance().setUpdateThemeCallback(() => this.updateTheme());
|
||||||
|
await NotificationsManager.initExpoToken();
|
||||||
|
console.log(AsyncStorageManager.getInstance().preferences.expoToken.current);
|
||||||
// Only show intro if this is the first time starting the app
|
// Only show intro if this is the first time starting the app
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|
|
@ -17,11 +17,9 @@ type State = {
|
||||||
refreshing: boolean,
|
refreshing: boolean,
|
||||||
firstLoading: boolean,
|
firstLoading: boolean,
|
||||||
fetchedData: Object,
|
fetchedData: Object,
|
||||||
machinesWatched: Array<Object>,
|
machinesWatched: Array<string>,
|
||||||
};
|
};
|
||||||
|
|
||||||
const minTimeBetweenRefresh = 60;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to create a basic list view using online json data.
|
* Class used to create a basic list view using online json data.
|
||||||
* Used by inheriting from it and redefining getters.
|
* Used by inheriting from it and redefining getters.
|
||||||
|
@ -36,6 +34,8 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
refreshTime: number;
|
refreshTime: number;
|
||||||
lastRefresh: Date;
|
lastRefresh: Date;
|
||||||
|
|
||||||
|
minTimeBetweenRefresh = 60;
|
||||||
|
|
||||||
constructor(fetchUrl: string, refreshTime: number) {
|
constructor(fetchUrl: string, refreshTime: number) {
|
||||||
super();
|
super();
|
||||||
this.webDataManager = new WebDataManager(fetchUrl);
|
this.webDataManager = new WebDataManager(fetchUrl);
|
||||||
|
@ -65,6 +65,10 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
return ["whoa", "nah"];
|
return ["whoa", "nah"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setMinTimeRefresh(value: number) {
|
||||||
|
this.minTimeBetweenRefresh = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register react navigation events on first screen load.
|
* Register react navigation events on first screen load.
|
||||||
* Allows to detect when the screen is focused
|
* Allows to detect when the screen is focused
|
||||||
|
@ -117,7 +121,7 @@ export default class FetchedDataSectionList extends React.Component<Props, State
|
||||||
_onRefresh = () => {
|
_onRefresh = () => {
|
||||||
let canRefresh;
|
let canRefresh;
|
||||||
if (this.lastRefresh !== undefined)
|
if (this.lastRefresh !== undefined)
|
||||||
canRefresh = (new Date().getTime() - this.lastRefresh.getTime())/1000 > minTimeBetweenRefresh;
|
canRefresh = (new Date().getTime() - this.lastRefresh.getTime())/1000 > this.minTimeBetweenRefresh;
|
||||||
else
|
else
|
||||||
canRefresh = true;
|
canRefresh = true;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import ThemeManager from "../utils/ThemeManager";
|
||||||
|
|
||||||
const ICON_AMICALE = require('../assets/amicale.png');
|
const ICON_AMICALE = require('../assets/amicale.png');
|
||||||
const NAME_AMICALE = 'Amicale INSA Toulouse';
|
const NAME_AMICALE = 'Amicale INSA Toulouse';
|
||||||
const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~vergnet/appli-amicale/facebook_data.json";
|
const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/facebook/facebook_data.json";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,8 +16,8 @@ type Props = {
|
||||||
|
|
||||||
const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
|
const PLANEX_URL = 'http://planex.insa-toulouse.fr/';
|
||||||
|
|
||||||
const CUSTOM_CSS_LINK = 'https://srv-falcon.etud.insa-toulouse.fr/~vergnet/appli-amicale/planex/generalCustom.css';
|
const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/planex/customMobile.css';
|
||||||
|
const CUSTOM_CSS_NIGHTMODE = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/planex/customDark.css';
|
||||||
/**
|
/**
|
||||||
* Class defining the app's planex screen.
|
* Class defining the app's planex screen.
|
||||||
* This screen uses a webview to render the planex page
|
* This screen uses a webview to render the planex page
|
||||||
|
@ -31,9 +31,9 @@ export default class PlanningScreen extends React.Component<Props> {
|
||||||
super();
|
super();
|
||||||
this.customInjectedJS =
|
this.customInjectedJS =
|
||||||
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
|
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
|
||||||
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="https://srv-falcon.etud.insa-toulouse.fr/~vergnet/appli-amicale/planex/customMobile.css" type="text/css"/>\';';
|
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\';';
|
||||||
if (ThemeManager.getNightMode())
|
if (ThemeManager.getNightMode())
|
||||||
this.customInjectedJS += 'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="https://srv-falcon.etud.insa-toulouse.fr/~vergnet/appli-amicale/planex/customDark.css" type="text/css"/>\';';
|
this.customInjectedJS += 'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_NIGHTMODE + '" type="text/css"/>\';';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import i18n from "i18n-js";
|
||||||
import {Platform, View} from "react-native";
|
import {Platform, View} from "react-native";
|
||||||
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
||||||
import ThemeManager from "../utils/ThemeManager";
|
import ThemeManager from "../utils/ThemeManager";
|
||||||
import {Linking} from "expo";
|
import {Linking, Notifications} from "expo";
|
||||||
import BaseContainer from "../components/BaseContainer";
|
import BaseContainer from "../components/BaseContainer";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -25,6 +25,7 @@ function openWebLink(link) {
|
||||||
* Class defining the app's planning screen
|
* Class defining the app's planning screen
|
||||||
*/
|
*/
|
||||||
export default class PlanningScreen extends React.Component<Props> {
|
export default class PlanningScreen extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const nav = this.props.navigation;
|
const nav = this.props.navigation;
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -13,9 +13,7 @@ import Touchable from "react-native-platform-touchable";
|
||||||
import AsyncStorageManager from "../utils/AsyncStorageManager";
|
import AsyncStorageManager from "../utils/AsyncStorageManager";
|
||||||
import * as Expo from "expo";
|
import * as Expo from "expo";
|
||||||
|
|
||||||
const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~vergnet/appli-amicale/washinsa/washinsa.json";
|
const DATA_URL = "https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/washinsa/washinsa.json";
|
||||||
|
|
||||||
let reminderNotifTime = 5;
|
|
||||||
|
|
||||||
const MACHINE_STATES = {
|
const MACHINE_STATES = {
|
||||||
"TERMINE": "0",
|
"TERMINE": "0",
|
||||||
|
@ -43,7 +41,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(DATA_URL, 1000 * 60); // Refresh every minute
|
super(DATA_URL, 1000 * 30); // Refresh every half minute
|
||||||
let colors = ThemeManager.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;
|
||||||
|
@ -69,13 +67,15 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
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;
|
// let dataString = AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.current;
|
||||||
this.state = {
|
this.state = {
|
||||||
refreshing: false,
|
refreshing: false,
|
||||||
firstLoading: true,
|
firstLoading: true,
|
||||||
fetchedData: {},
|
fetchedData: {},
|
||||||
machinesWatched: JSON.parse(dataString),
|
// machinesWatched: JSON.parse(dataString),
|
||||||
|
machinesWatched: [],
|
||||||
};
|
};
|
||||||
|
this.setMinTimeRefresh(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,14 +90,6 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
vibrate: [0, 250, 250, 250],
|
vibrate: [0, 250, 250, 250],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Remove machine from watch list when receiving last notification
|
|
||||||
Expo.Notifications.addListener((notification) => {
|
|
||||||
if (notification.data !== undefined) {
|
|
||||||
if (this.isMachineWatched(notification.data.id) && notification.data.isMachineFinished === true) {
|
|
||||||
this.removeNotificationFromPrefs(this.getMachineIndexInWatchList(notification.data.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getHeaderTranslation() {
|
getHeaderTranslation() {
|
||||||
|
@ -140,49 +132,16 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
* Another will be send a few minutes before the end, based on the value of reminderNotifTime
|
* Another will be send a few minutes before the end, based on the value of reminderNotifTime
|
||||||
*
|
*
|
||||||
* @param machineId The machine's ID
|
* @param machineId The machine's ID
|
||||||
* @param remainingTime The time remaining for this machine
|
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async setupNotifications(machineId: string, remainingTime: number) {
|
setupNotifications(machineId: string) {
|
||||||
if (!this.isMachineWatched(machineId)) {
|
if (!this.isMachineWatched(machineId)) {
|
||||||
let endNotificationID = await NotificationsManager.scheduleNotification(
|
NotificationsManager.setupMachineNotification(machineId, true);
|
||||||
i18n.t('proxiwashScreen.notifications.machineFinishedTitle'),
|
this.saveNotificationToPrefs(machineId);
|
||||||
i18n.t('proxiwashScreen.notifications.machineFinishedBody', {number: machineId}),
|
|
||||||
new Date().getTime() + remainingTime * (60 * 1000), // Convert back to milliseconds
|
|
||||||
{id: machineId, isMachineFinished: true},
|
|
||||||
'reminders'
|
|
||||||
);
|
|
||||||
let reminderNotificationID = await ProxiwashScreen.setupReminderNotification(machineId, remainingTime);
|
|
||||||
this.saveNotificationToPrefs(machineId, endNotificationID, reminderNotificationID);
|
|
||||||
} 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
|
|
||||||
{id: machineId, isMachineFinished: false},
|
|
||||||
'reminders'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return reminderNotificationID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static getReminderNotificationTime(): number {
|
|
||||||
let val = AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current;
|
|
||||||
if (val !== "never")
|
|
||||||
reminderNotifTime = parseInt(val);
|
|
||||||
else
|
|
||||||
reminderNotifTime = -1;
|
|
||||||
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.
|
||||||
|
@ -192,43 +151,22 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
disableNotification(machineId: string) {
|
disableNotification(machineId: string) {
|
||||||
let data = this.state.machinesWatched;
|
let data = this.state.machinesWatched;
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
let arrayIndex = this.getMachineIndexInWatchList(machineId);
|
let arrayIndex = data.indexOf(machineId);
|
||||||
if (arrayIndex !== -1) {
|
if (arrayIndex !== -1) {
|
||||||
NotificationsManager.cancelScheduledNotification(data[arrayIndex].endNotificationID);
|
NotificationsManager.setupMachineNotification(machineId, false);
|
||||||
if (data[arrayIndex].reminderNotificationID !== null)
|
|
||||||
NotificationsManager.cancelScheduledNotification(data[arrayIndex].reminderNotificationID);
|
|
||||||
this.removeNotificationFromPrefs(arrayIndex);
|
this.removeNotificationFromPrefs(arrayIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the index of the given machine ID in the watchlist array
|
|
||||||
*
|
|
||||||
* @param machineId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
getMachineIndexInWatchList(machineId: string): number {
|
|
||||||
let elem = this.state.machinesWatched.find(function (elem) {
|
|
||||||
return elem.machineNumber === machineId
|
|
||||||
});
|
|
||||||
return this.state.machinesWatched.indexOf(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the given notifications associated to a machine ID to the watchlist, and save the array to the preferences
|
* Add the given notifications associated to a machine ID to the watchlist, and save the array to the preferences
|
||||||
*
|
*
|
||||||
* @param machineId
|
* @param machineId
|
||||||
* @param endNotificationID
|
|
||||||
* @param reminderNotificationID
|
|
||||||
*/
|
*/
|
||||||
saveNotificationToPrefs(machineId: string, endNotificationID: string, reminderNotificationID: string | null) {
|
saveNotificationToPrefs(machineId: string) {
|
||||||
let data = this.state.machinesWatched;
|
let data = this.state.machinesWatched;
|
||||||
data.push({
|
data.push(machineId);
|
||||||
machineNumber: machineId,
|
|
||||||
endNotificationID: endNotificationID,
|
|
||||||
reminderNotificationID: reminderNotificationID
|
|
||||||
});
|
|
||||||
this.updateNotificationPrefs(data);
|
this.updateNotificationPrefs(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +188,8 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
*/
|
*/
|
||||||
updateNotificationPrefs(data: Array<Object>) {
|
updateNotificationPrefs(data: Array<Object>) {
|
||||||
this.setState({machinesWatched: data});
|
this.setState({machinesWatched: data});
|
||||||
let prefKey = AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.key;
|
// let prefKey = AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.key;
|
||||||
AsyncStorageManager.getInstance().savePref(prefKey, JSON.stringify(data));
|
// AsyncStorageManager.getInstance().savePref(prefKey, JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -261,9 +199,7 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
isMachineWatched(machineID: string) {
|
isMachineWatched(machineID: string) {
|
||||||
return this.state.machinesWatched.find(function (elem) {
|
return this.state.machinesWatched.indexOf(machineID) !== -1;
|
||||||
return elem.machineNumber === machineID
|
|
||||||
}) !== undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createDataset(fetchedData: Object) {
|
createDataset(fetchedData: Object) {
|
||||||
|
@ -307,7 +243,7 @@ export default class ProxiwashScreen extends FetchedDataSectionList {
|
||||||
text: this.isMachineWatched(item.number) ?
|
text: this.isMachineWatched(item.number) ?
|
||||||
i18n.t("proxiwashScreen.modal.disableNotifications") :
|
i18n.t("proxiwashScreen.modal.disableNotifications") :
|
||||||
i18n.t("proxiwashScreen.modal.enableNotifications"),
|
i18n.t("proxiwashScreen.modal.enableNotifications"),
|
||||||
onPress: () => this.setupNotifications(item.number, remainingTime)
|
onPress: () => this.setupNotifications(item.number)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: i18n.t("proxiwashScreen.modal.cancel")
|
text: i18n.t("proxiwashScreen.modal.cancel")
|
||||||
|
|
|
@ -16,6 +16,8 @@ type Props = {
|
||||||
|
|
||||||
|
|
||||||
const RU_URL = 'http://m.insa-toulouse.fr/ru.html';
|
const RU_URL = 'http://m.insa-toulouse.fr/ru.html';
|
||||||
|
const CUSTOM_CSS_GENERAL = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/RU/customGeneral.css';
|
||||||
|
const CUSTOM_CSS_LIGHT = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/custom_css/RU/customLight.css';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining the app's planex screen.
|
* Class defining the app's planex screen.
|
||||||
|
@ -30,9 +32,9 @@ export default class SelfMenuScreen extends React.Component<Props> {
|
||||||
super();
|
super();
|
||||||
this.customInjectedJS =
|
this.customInjectedJS =
|
||||||
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
|
'document.querySelector(\'head\').innerHTML += \'<meta name="viewport" content="width=device-width, initial-scale=1.0">\';' +
|
||||||
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="https://srv-falcon.etud.insa-toulouse.fr/~vergnet/appli-amicale/RU/customGeneral.css" type="text/css"/>\';';
|
'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_GENERAL + '" type="text/css"/>\';';
|
||||||
if (!ThemeManager.getNightMode())
|
if (!ThemeManager.getNightMode())
|
||||||
this.customInjectedJS += 'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="https://srv-falcon.etud.insa-toulouse.fr/~vergnet/appli-amicale/RU/customLight.css" type="text/css"/>\';';
|
this.customInjectedJS += 'document.querySelector(\'head\').innerHTML += \'<link rel="stylesheet" href="' + CUSTOM_CSS_LIGHT + '" type="text/css"/>\';';
|
||||||
}
|
}
|
||||||
|
|
||||||
getRefreshButton() {
|
getRefreshButton() {
|
||||||
|
|
|
@ -43,6 +43,11 @@ export default class AsyncStorageManager {
|
||||||
key: 'nightMode',
|
key: 'nightMode',
|
||||||
default: '0',
|
default: '0',
|
||||||
current: '',
|
current: '',
|
||||||
|
},
|
||||||
|
expoToken: {
|
||||||
|
key: 'expoToken',
|
||||||
|
default: '',
|
||||||
|
current: '',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
import * as Permissions from 'expo-permissions';
|
import * as Permissions from 'expo-permissions';
|
||||||
import {Notifications} from 'expo';
|
import {Notifications} from 'expo';
|
||||||
|
import AsyncStorageManager from "./AsyncStorageManager";
|
||||||
|
|
||||||
|
const EXPO_TOKEN_SERVER = 'https://srv-falcon.etud.insa-toulouse.fr/~amicale_app/expo_notifications/save_token.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static class used to manage notifications sent to the user
|
* Static class used to manage notifications sent to the user
|
||||||
|
@ -45,10 +48,15 @@ export default class NotificationsManager {
|
||||||
* @param body Notification body text
|
* @param body Notification body text
|
||||||
* @param time Time at which we should send the notification
|
* @param time Time at which we should send the notification
|
||||||
* @param data Data to send with the notification, used for listeners
|
* @param data Data to send with the notification, used for listeners
|
||||||
|
* @param androidChannelID
|
||||||
* @returns {Promise<import("react").ReactText>} Notification Id
|
* @returns {Promise<import("react").ReactText>} Notification Id
|
||||||
*/
|
*/
|
||||||
static async scheduleNotification(title: string, body: string, time: number, data: Object, androidChannelID: string): Promise<string> {
|
static async scheduleNotification(title: string, body: string, time: number, data: Object, androidChannelID: string): Promise<string> {
|
||||||
await NotificationsManager.askPermissions();
|
await NotificationsManager.askPermissions();
|
||||||
|
console.log(time);
|
||||||
|
let date = new Date();
|
||||||
|
date.setTime(time);
|
||||||
|
console.log(date);
|
||||||
return Notifications.scheduleLocalNotificationAsync(
|
return Notifications.scheduleLocalNotificationAsync(
|
||||||
{
|
{
|
||||||
title: title,
|
title: title,
|
||||||
|
@ -75,4 +83,54 @@ export default class NotificationsManager {
|
||||||
static async cancelScheduledNotification(notificationID: number) {
|
static async cancelScheduledNotification(notificationID: number) {
|
||||||
await Notifications.cancelScheduledNotificationAsync(notificationID);
|
await Notifications.cancelScheduledNotificationAsync(notificationID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save expo token to allow sending notifications to this device.
|
||||||
|
* This token is unique for each device and won't change.
|
||||||
|
* It only needs to be fetched once, then it will be saved in storage.
|
||||||
|
*
|
||||||
|
* @return {Promise<void>}
|
||||||
|
*/
|
||||||
|
static async initExpoToken() {
|
||||||
|
let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
|
||||||
|
if (AsyncStorageManager.getInstance().preferences.expoToken.current === '') {
|
||||||
|
let expoToken = await Notifications.getExpoPushTokenAsync();
|
||||||
|
// Save token for instant use later on
|
||||||
|
AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.expoToken.key, expoToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the server to enable/disable notifications for the specified machine
|
||||||
|
*
|
||||||
|
* @param machineID
|
||||||
|
* @param isEnabled
|
||||||
|
*/
|
||||||
|
static setupMachineNotification(machineID: string, isEnabled: boolean) {
|
||||||
|
let token = AsyncStorageManager.getInstance().preferences.expoToken.current;
|
||||||
|
if (token === '') {
|
||||||
|
throw Error('Expo token not available');
|
||||||
|
}
|
||||||
|
let data = {
|
||||||
|
function: 'setup_machine_notification',
|
||||||
|
token: token,
|
||||||
|
machine_id: machineID,
|
||||||
|
enabled: isEnabled
|
||||||
|
};
|
||||||
|
fetch(EXPO_TOKEN_SERVER, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: new Headers({
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}),
|
||||||
|
body: JSON.stringify(data) // <-- Post parameters
|
||||||
|
})
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((responseText) => {
|
||||||
|
console.log(responseText);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue