MOBILE-2814 localnotif: Adapt emulator to the new API
parent
3f84adca9a
commit
5c85a3345a
|
@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { CoreFileProvider } from '@providers/file';
|
import { CoreFileProvider } from '@providers/file';
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
import { File } from '@ionic-native/file';
|
import { File } from '@ionic-native/file';
|
||||||
import { LocalNotifications } from '@ionic-native/local-notifications';
|
import { LocalNotifications, ILocalNotification } from '@ionic-native/local-notifications';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider } from '@providers/app';
|
||||||
import { CoreInitDelegate, CoreInitHandler } from '@providers/init';
|
import { CoreInitDelegate, CoreInitHandler } from '@providers/init';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
@ -157,9 +157,11 @@ export class CoreEmulatorHelperProvider implements CoreInitHandler {
|
||||||
|
|
||||||
// There is a new notification, show it.
|
// There is a new notification, show it.
|
||||||
return getDataFn(notification).then((titleAndText) => {
|
return getDataFn(notification).then((titleAndText) => {
|
||||||
const localNotif = {
|
const localNotif: ILocalNotification = {
|
||||||
id: 1,
|
id: 1,
|
||||||
at: new Date(),
|
trigger: {
|
||||||
|
at: new Date()
|
||||||
|
},
|
||||||
title: titleAndText.title,
|
title: titleAndText.title,
|
||||||
text: titleAndText.text,
|
text: titleAndText.text,
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { LocalNotifications, ILocalNotification } from '@ionic-native/local-notifications';
|
import { LocalNotifications, ILocalNotification, ILocalNotificationAction } from '@ionic-native/local-notifications';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider } from '@providers/app';
|
||||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
|
@ -21,6 +21,7 @@ import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { CoreConfigConstants } from '../../../configconstants';
|
import { CoreConfigConstants } from '../../../configconstants';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
import { Subject, Observable } from 'rxjs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emulates the Cordova Globalization plugin in desktop apps and in browser.
|
* Emulates the Cordova Globalization plugin in desktop apps and in browser.
|
||||||
|
@ -76,16 +77,40 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
protected appDB: SQLiteDB;
|
protected appDB: SQLiteDB;
|
||||||
protected scheduled: { [i: number]: any } = {};
|
protected scheduled: { [i: number]: any } = {};
|
||||||
protected triggered: { [i: number]: any } = {};
|
protected triggered: { [i: number]: any } = {};
|
||||||
protected observers;
|
protected observers: {[event: string]: Subject<any>};
|
||||||
protected defaults = {
|
protected defaults = {
|
||||||
text: '',
|
actions : [],
|
||||||
title: '',
|
attachments : [],
|
||||||
sound: '',
|
autoClear : true,
|
||||||
badge: 0,
|
badge : null,
|
||||||
id: 0,
|
channel : null,
|
||||||
data: undefined,
|
clock : true,
|
||||||
every: undefined,
|
color : null,
|
||||||
at: undefined
|
data : null,
|
||||||
|
defaults : 0,
|
||||||
|
foreground : null,
|
||||||
|
group : null,
|
||||||
|
groupSummary : false,
|
||||||
|
icon : null,
|
||||||
|
id : 0,
|
||||||
|
launch : true,
|
||||||
|
led : true,
|
||||||
|
lockscreen : true,
|
||||||
|
mediaSession : null,
|
||||||
|
number : 0,
|
||||||
|
priority : 0,
|
||||||
|
progressBar : false,
|
||||||
|
silent : false,
|
||||||
|
smallIcon : 'res://icon',
|
||||||
|
sound : true,
|
||||||
|
sticky : false,
|
||||||
|
summary : null,
|
||||||
|
text : '',
|
||||||
|
timeoutAfter : false,
|
||||||
|
title : '',
|
||||||
|
trigger : { type : 'calendar' },
|
||||||
|
vibrate : false,
|
||||||
|
wakeup : true
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider) {
|
constructor(private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider) {
|
||||||
|
@ -96,20 +121,32 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
|
|
||||||
// Initialize observers.
|
// Initialize observers.
|
||||||
this.observers = {
|
this.observers = {
|
||||||
schedule: [],
|
schedule: new Subject<any>(),
|
||||||
trigger: [],
|
trigger: new Subject<any>(),
|
||||||
click: [],
|
click: new Subject<any>(),
|
||||||
update: [],
|
update: new Subject<any>(),
|
||||||
clear: [],
|
clear: new Subject<any>(),
|
||||||
clearall: [],
|
clearall: new Subject<any>(),
|
||||||
cancel: [],
|
cancel: new Subject<any>(),
|
||||||
cancelall: []
|
cancelall: new Subject<any>(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels single or multiple notifications
|
* Adds a group of actions.
|
||||||
* @param notificationId {any} A single notification id, or an array of notification ids.
|
*
|
||||||
|
* @param {any} groupId The id of the action group
|
||||||
|
* @param {ILocalNotificationAction[]} actions The actions of this group
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
addActions(groupId: any, actions: ILocalNotificationAction[]): Promise<any> {
|
||||||
|
return Promise.reject('Not supported in desktop apps.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels single or multiple notifications.
|
||||||
|
*
|
||||||
|
* @param {any} notificationId A single notification id, or an array of notification ids.
|
||||||
* @returns {Promise<any>} Returns a promise when the notification is canceled
|
* @returns {Promise<any>} Returns a promise when the notification is canceled
|
||||||
*/
|
*/
|
||||||
cancel(notificationId: any): Promise<any> {
|
cancel(notificationId: any): Promise<any> {
|
||||||
|
@ -135,7 +172,11 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
*/
|
*/
|
||||||
cancelAll(): Promise<any> {
|
cancelAll(): Promise<any> {
|
||||||
return this.cancel(Object.keys(this.scheduled)).then(() => {
|
return this.cancel(Object.keys(this.scheduled)).then(() => {
|
||||||
this.triggerEvent('cancelall', 'foreground');
|
this.fireEvent('cancelall', {
|
||||||
|
event: 'cancelall',
|
||||||
|
foreground: true,
|
||||||
|
queued: false
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +203,7 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
this.removeNotification(id);
|
this.removeNotification(id);
|
||||||
|
|
||||||
if (!omitEvent) {
|
if (!omitEvent) {
|
||||||
this.triggerEvent(eventName, notification, 'foreground');
|
this.fireEvent(eventName, notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +222,8 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
// Clear the notifications.
|
// Clear the notifications.
|
||||||
notificationId.forEach((id) => {
|
notificationId.forEach((id) => {
|
||||||
// Cancel only the notifications that aren't repeating.
|
// Cancel only the notifications that aren't repeating.
|
||||||
if (this.scheduled[id] && this.scheduled[id].notification && !this.scheduled[id].notification.every) {
|
if (this.scheduled[id] && this.scheduled[id].notification &&
|
||||||
|
(!this.scheduled[id].notification.trigger || !this.scheduled[id].notification.trigger.every)) {
|
||||||
promises.push(this.cancelNotification(id, false, 'clear'));
|
promises.push(this.cancelNotification(id, false, 'clear'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -195,7 +237,11 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
*/
|
*/
|
||||||
clearAll(): Promise<any> {
|
clearAll(): Promise<any> {
|
||||||
return this.clear(Object.keys(this.scheduled)).then(() => {
|
return this.clear(Object.keys(this.scheduled)).then(() => {
|
||||||
this.triggerEvent('clearall', 'foreground');
|
this.fireEvent('clearall', {
|
||||||
|
event: 'clearall',
|
||||||
|
foreground: true,
|
||||||
|
queued: false
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,44 +271,251 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
*/
|
*/
|
||||||
protected convertProperties(notification: ILocalNotification): ILocalNotification {
|
protected convertProperties(notification: ILocalNotification): ILocalNotification {
|
||||||
if (notification.id) {
|
if (notification.id) {
|
||||||
if (isNaN(notification.id)) {
|
notification.id = this.parseToInt('id', notification);
|
||||||
notification.id = this.defaults.id;
|
|
||||||
} else {
|
|
||||||
notification.id = Number(notification.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.title) {
|
if (notification.title) {
|
||||||
notification.title = notification.title.toString();
|
notification.title = notification.title.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.text) {
|
|
||||||
notification.text = notification.text.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notification.badge) {
|
if (notification.badge) {
|
||||||
if (isNaN(notification.badge)) {
|
notification.badge = this.parseToInt('badge', notification);
|
||||||
notification.badge = this.defaults.badge;
|
|
||||||
} else {
|
|
||||||
notification.badge = Number(notification.badge);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.at) {
|
if (notification.defaults) {
|
||||||
if (typeof notification.at == 'object') {
|
notification.defaults = this.parseToInt('defaults', notification);
|
||||||
notification.at = notification.at.getTime();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
notification.at = Math.round(notification.at / 1000);
|
if (typeof notification.timeoutAfter === 'boolean') {
|
||||||
|
notification.timeoutAfter = notification.timeoutAfter ? 3600000 : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification.timeoutAfter) {
|
||||||
|
notification.timeoutAfter = this.parseToInt('timeoutAfter', notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof notification.data == 'object') {
|
if (typeof notification.data == 'object') {
|
||||||
notification.data = JSON.stringify(notification.data);
|
notification.data = JSON.stringify(notification.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.convertPriority(notification);
|
||||||
|
this.convertTrigger(notification);
|
||||||
|
this.convertActions(notification);
|
||||||
|
this.convertProgressBar(notification);
|
||||||
|
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a property to number, returning the default value if not valid.
|
||||||
|
* Code extracted from the Cordova plugin.
|
||||||
|
*
|
||||||
|
* @param {string} prop Name of property to convert.
|
||||||
|
* @param {any} notification Notification where to search the property.
|
||||||
|
* @return {number} Converted number or default value.
|
||||||
|
*/
|
||||||
|
protected parseToInt(prop: string, notification: any): number {
|
||||||
|
if (isNaN(notification[prop])) {
|
||||||
|
return this.defaults[prop];
|
||||||
|
} else {
|
||||||
|
return Number(notification[prop]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the priority of a notification.
|
||||||
|
* Code extracted from the Cordova plugin.
|
||||||
|
*
|
||||||
|
* @param {any} notification Notification.
|
||||||
|
* @return {any} Notification.
|
||||||
|
*/
|
||||||
|
protected convertPriority(notification: any): any {
|
||||||
|
let prio = notification.priority || notification.prio || 0;
|
||||||
|
|
||||||
|
if (typeof prio === 'string') {
|
||||||
|
prio = { min: -2, low: -1, high: 1, max: 2 }[prio] || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification.foreground === true) {
|
||||||
|
prio = Math.max(prio, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification.foreground === false) {
|
||||||
|
prio = Math.min(prio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.priority = prio;
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the actions of a notification.
|
||||||
|
* Code extracted from the Cordova plugin.
|
||||||
|
*
|
||||||
|
* @param {any} notification Notification.
|
||||||
|
* @return {any} Notification.
|
||||||
|
*/
|
||||||
|
protected convertActions(notification: any): any {
|
||||||
|
const actions = [];
|
||||||
|
|
||||||
|
if (!notification.actions || typeof notification.actions === 'string') {
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0, len = notification.actions.length; i < len; i++) {
|
||||||
|
const action = notification.actions[i];
|
||||||
|
|
||||||
|
if (!action.id) {
|
||||||
|
// Ignore action, it has no ID.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
action.id = action.id.toString();
|
||||||
|
|
||||||
|
actions.push(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.actions = actions;
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the trigger of a notification.
|
||||||
|
* Code extracted from the Cordova plugin.
|
||||||
|
*
|
||||||
|
* @param {any} notification Notification.
|
||||||
|
* @return {any} Notification.
|
||||||
|
*/
|
||||||
|
protected convertTrigger(notification: any): any {
|
||||||
|
const trigger = notification.trigger || {};
|
||||||
|
let date = this.getValueFor(trigger, 'at', 'firstAt', 'date');
|
||||||
|
|
||||||
|
const dateToNum = (date: any): number => {
|
||||||
|
const num = typeof date == 'object' ? date.getTime() : date;
|
||||||
|
|
||||||
|
return Math.round(num);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!notification.trigger) {
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!trigger.type) {
|
||||||
|
trigger.type = trigger.center ? 'location' : 'calendar';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isCal = trigger.type == 'calendar';
|
||||||
|
|
||||||
|
if (isCal && !date) {
|
||||||
|
date = this.getValueFor(notification, 'at', 'firstAt', 'date');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCal && !trigger.every && notification.every) {
|
||||||
|
trigger.every = notification.every;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCal && (trigger.in || trigger.every)) {
|
||||||
|
date = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCal && date) {
|
||||||
|
trigger.at = dateToNum(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCal && trigger.firstAt) {
|
||||||
|
trigger.firstAt = dateToNum(trigger.firstAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCal && trigger.before) {
|
||||||
|
trigger.before = dateToNum(trigger.before);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCal && trigger.after) {
|
||||||
|
trigger.after = dateToNum(trigger.after);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!trigger.count) {
|
||||||
|
trigger.count = trigger.every ? 5 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isCal) {
|
||||||
|
trigger.notifyOnEntry = !!trigger.notifyOnEntry;
|
||||||
|
trigger.notifyOnExit = trigger.notifyOnExit === true;
|
||||||
|
trigger.radius = trigger.radius || 5;
|
||||||
|
trigger.single = !!trigger.single;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isCal || trigger.at) {
|
||||||
|
delete trigger.every;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete notification.every;
|
||||||
|
delete notification.at;
|
||||||
|
delete notification.firstAt;
|
||||||
|
delete notification.date;
|
||||||
|
|
||||||
|
notification.trigger = trigger;
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the progress bar of a notification.
|
||||||
|
* Code extracted from the Cordova plugin.
|
||||||
|
*
|
||||||
|
* @param {any} notification Notification.
|
||||||
|
* @return {any} Notification.
|
||||||
|
*/
|
||||||
|
protected convertProgressBar(notification: any): any {
|
||||||
|
let cfg = notification.progressBar;
|
||||||
|
|
||||||
|
if (cfg === undefined) {
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof cfg === 'boolean') {
|
||||||
|
cfg = notification.progressBar = { enabled: cfg };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof cfg.enabled !== 'boolean') {
|
||||||
|
cfg.enabled = !!(cfg.value || cfg.maxValue || cfg.indeterminate !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.value = cfg.value || 0;
|
||||||
|
|
||||||
|
cfg.enabled = !!cfg.enabled;
|
||||||
|
|
||||||
|
if (cfg.enabled && notification.clock === true) {
|
||||||
|
notification.clock = 'chronometer';
|
||||||
|
}
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not an official interface, however its possible to manually fire events.
|
||||||
|
*
|
||||||
|
* @param {string} eventName The name of the event. Available events: schedule, trigger, click, update, clear, clearall, cancel,
|
||||||
|
* cancelall. Custom event names are possible for actions
|
||||||
|
* @param {any} args Optional arguments
|
||||||
|
*/
|
||||||
|
fireEvent(eventName: string, args: any): void {
|
||||||
|
if (this.observers[eventName]) {
|
||||||
|
this.observers[eventName].next(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire queued events once the device is ready and all listeners are registered.
|
||||||
|
*
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
fireQueuedEvents(): Promise<any> {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a notification object.
|
* Get a notification object.
|
||||||
*
|
*
|
||||||
|
@ -282,12 +535,21 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
return Promise.resolve(this.getNotifications(undefined, true, true));
|
return Promise.resolve(this.getNotifications(undefined, true, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the (platform specific) default settings.
|
||||||
|
*
|
||||||
|
* @returns {Promise<any>} An object with all default settings
|
||||||
|
*/
|
||||||
|
getDefaults(): Promise<any> {
|
||||||
|
return Promise.resolve(this.defaults);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the notification ids.
|
* Get all the notification ids.
|
||||||
*
|
*
|
||||||
* @returns {Promise<Array<number>>}
|
* @returns {Promise<Array<number>>}
|
||||||
*/
|
*/
|
||||||
getAllIds(): Promise<Array<number>> {
|
getIds(): Promise<Array<number>> {
|
||||||
let ids = this.utils.mergeArraysWithoutDuplicates(Object.keys(this.scheduled), Object.keys(this.triggered));
|
let ids = this.utils.mergeArraysWithoutDuplicates(Object.keys(this.scheduled), Object.keys(this.triggered));
|
||||||
ids = ids.map((id) => {
|
ids = ids.map((id) => {
|
||||||
return Number(id);
|
return Number(id);
|
||||||
|
@ -304,9 +566,13 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
protected getAllNotifications(): Promise<any> {
|
protected getAllNotifications(): Promise<any> {
|
||||||
return this.appDB.getAllRecords(this.DESKTOP_NOTIFS_TABLE).then((notifications) => {
|
return this.appDB.getAllRecords(this.DESKTOP_NOTIFS_TABLE).then((notifications) => {
|
||||||
notifications.forEach((notification) => {
|
notifications.forEach((notification) => {
|
||||||
notification.at = new Date(notification.at);
|
notification.trigger = {
|
||||||
|
at: new Date(notification.at)
|
||||||
|
};
|
||||||
notification.data = this.textUtils.parseJSON(notification.data);
|
notification.data = this.textUtils.parseJSON(notification.data);
|
||||||
notification.triggered = !!notification.triggered;
|
notification.triggered = !!notification.triggered;
|
||||||
|
|
||||||
|
this.mergeWithDefaults(notification);
|
||||||
});
|
});
|
||||||
|
|
||||||
return notifications;
|
return notifications;
|
||||||
|
@ -318,7 +584,7 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
*
|
*
|
||||||
* @returns {Promise<Array<ILocalNotification>>}
|
* @returns {Promise<Array<ILocalNotification>>}
|
||||||
*/
|
*/
|
||||||
getAllScheduled(): Promise<Array<ILocalNotification>> {
|
getScheduled(): Promise<Array<ILocalNotification>> {
|
||||||
return Promise.resolve(this.getNotifications(undefined, true, false));
|
return Promise.resolve(this.getNotifications(undefined, true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,14 +593,14 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
*
|
*
|
||||||
* @returns {Promise<Array<ILocalNotification>>}
|
* @returns {Promise<Array<ILocalNotification>>}
|
||||||
*/
|
*/
|
||||||
getAllTriggered(): Promise<Array<ILocalNotification>> {
|
getTriggered(): Promise<Array<ILocalNotification>> {
|
||||||
return Promise.resolve(this.getNotifications(undefined, false, true));
|
return Promise.resolve(this.getNotifications(undefined, false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a set of notifications. If ids isn't specified, return all the notifications.
|
* Get a set of notifications. If ids isn't specified, return all the notifications.
|
||||||
*
|
*
|
||||||
* @param {Number[]} [ids] Ids of notifications to get. If not specified, get all notifications.
|
* @param {number[]} [ids] Ids of notifications to get. If not specified, get all notifications.
|
||||||
* @param {boolean} [getScheduled] Get scheduled notifications.
|
* @param {boolean} [getScheduled] Get scheduled notifications.
|
||||||
* @param {boolean} [getTriggered] Get triggered notifications.
|
* @param {boolean} [getTriggered] Get triggered notifications.
|
||||||
* @return {ILocalNotification[]} List of notifications.
|
* @return {ILocalNotification[]} List of notifications.
|
||||||
|
@ -362,13 +628,19 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a scheduled notification object.
|
* Get the trigger "at" in milliseconds.
|
||||||
*
|
*
|
||||||
* @param {any} notificationId The id of the notification to ge.
|
* @param {ILocalNotification} notification Notification to get the trigger from.
|
||||||
* @returns {Promise<ILocalNotification>}
|
* @return {number} Trigger time.
|
||||||
*/
|
*/
|
||||||
getScheduled(notificationId: any): Promise<ILocalNotification> {
|
protected getNotificationTriggerAt(notification: ILocalNotification): number {
|
||||||
return Promise.resolve(this.getNotifications([Number(notificationId)], true, false)[0]);
|
const triggerAt = (notification.trigger && notification.trigger.at) || 0;
|
||||||
|
|
||||||
|
if (typeof triggerAt != 'number') {
|
||||||
|
return triggerAt.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
return triggerAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -384,16 +656,6 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
return Promise.resolve(ids);
|
return Promise.resolve(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a triggered notification object.
|
|
||||||
*
|
|
||||||
* @param {any} notificationId The id of the notification to get.
|
|
||||||
* @returns {Promise<ILocalNotification>}
|
|
||||||
*/
|
|
||||||
getTriggered(notificationId: any): Promise<ILocalNotification> {
|
|
||||||
return Promise.resolve(this.getNotifications([Number(notificationId)], false, true)[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ids of triggered notifications.
|
* Get the ids of triggered notifications.
|
||||||
*
|
*
|
||||||
|
@ -407,12 +669,28 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
return Promise.resolve(ids);
|
return Promise.resolve(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type (triggered, scheduled) for the notification.
|
||||||
|
*
|
||||||
|
* @param {number} id The ID of the notification.
|
||||||
|
* @return {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
getType(id: number): Promise<any> {
|
||||||
|
if (this.scheduled[id]) {
|
||||||
|
return Promise.resolve('scheduled');
|
||||||
|
} else if (this.triggered[id]) {
|
||||||
|
return Promise.resolve('triggered');
|
||||||
|
} else {
|
||||||
|
return Promise.resolve('unknown');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an object of options and a list of properties, return the first property that exists.
|
* Given an object of options and a list of properties, return the first property that exists.
|
||||||
* Code extracted from the Cordova plugin.
|
* Code extracted from the Cordova plugin.
|
||||||
*
|
*
|
||||||
* @param {ILocalNotification} notification Notification.
|
* @param {ILocalNotification} notification Notification.
|
||||||
* @param {any} ...args List of keys to check.
|
* @param {any[]} ...args List of keys to check.
|
||||||
* @return {any} First value found.
|
* @return {any} First value found.
|
||||||
*/
|
*/
|
||||||
protected getValueFor(notification: ILocalNotification, ...args: any[]): any {
|
protected getValueFor(notification: ILocalNotification, ...args: any[]): any {
|
||||||
|
@ -424,6 +702,16 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a group of actions is defined.
|
||||||
|
*
|
||||||
|
* @param {any} groupId The id of the action group
|
||||||
|
* @returns {Promise<boolean>} Whether the group is defined.
|
||||||
|
*/
|
||||||
|
hasActions(groupId: any): Promise<boolean> {
|
||||||
|
return Promise.resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Informs if the app has the permission to show notifications.
|
* Informs if the app has the permission to show notifications.
|
||||||
*
|
*
|
||||||
|
@ -433,6 +721,19 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a notification has a given type.
|
||||||
|
*
|
||||||
|
* @param {number} id The ID of the notification.
|
||||||
|
* @param {string} type The type of the notification.
|
||||||
|
* @returns {Promise<boolean>} Promise resolved with boolean: whether it has the type.
|
||||||
|
*/
|
||||||
|
hasType(id: number, type: string): Promise<boolean> {
|
||||||
|
return this.getType(id).then((notifType) => {
|
||||||
|
return type == notifType;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks presence of a notification.
|
* Checks presence of a notification.
|
||||||
*
|
*
|
||||||
|
@ -512,26 +813,22 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
* @return {ILocalNotification} Treated notification.
|
* @return {ILocalNotification} Treated notification.
|
||||||
*/
|
*/
|
||||||
protected mergeWithDefaults(notification: ILocalNotification): ILocalNotification {
|
protected mergeWithDefaults(notification: ILocalNotification): ILocalNotification {
|
||||||
notification.at = this.getValueFor(notification, 'at', 'firstAt', 'date');
|
const values = this.getDefaults();
|
||||||
notification.text = this.getValueFor(notification, 'text', 'message');
|
|
||||||
notification.data = this.getValueFor(notification, 'data', 'json');
|
|
||||||
|
|
||||||
if (notification.at === undefined || notification.at === null) {
|
if (values.hasOwnProperty('sticky')) {
|
||||||
notification.at = new Date();
|
notification.sticky = this.getValueFor(notification, 'sticky', 'ongoing');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const key in this.defaults) {
|
if (notification.sticky && notification.autoClear !== true) {
|
||||||
if (notification[key] === null || notification[key] === undefined) {
|
notification.autoClear = false;
|
||||||
if (notification.hasOwnProperty(key) && ['data', 'sound'].indexOf(key) > -1) {
|
|
||||||
notification[key] = undefined;
|
|
||||||
} else {
|
|
||||||
notification[key] = this.defaults[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const key in notification) {
|
Object.assign(values, notification);
|
||||||
if (!this.defaults.hasOwnProperty(key)) {
|
|
||||||
|
for (const key in values) {
|
||||||
|
if (values[key] !== null) {
|
||||||
|
notification[key] = values[key];
|
||||||
|
} else {
|
||||||
delete notification[key];
|
delete notification[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,7 +842,7 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
* @param {ILocalNotification} notification Clicked notification.
|
* @param {ILocalNotification} notification Clicked notification.
|
||||||
*/
|
*/
|
||||||
protected notificationClicked(notification: ILocalNotification): void {
|
protected notificationClicked(notification: ILocalNotification): void {
|
||||||
this.triggerEvent('click', notification, 'foreground');
|
this.fireEvent('click', notification);
|
||||||
// Focus the app.
|
// Focus the app.
|
||||||
require('electron').ipcRenderer.send('focusApp');
|
require('electron').ipcRenderer.send('focusApp');
|
||||||
}
|
}
|
||||||
|
@ -553,20 +850,16 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
/**
|
/**
|
||||||
* Sets a callback for a specific event.
|
* Sets a callback for a specific event.
|
||||||
*
|
*
|
||||||
* @param {string} eventName Name of the event. Events: schedule, trigger, click, update, clear, clearall, cancel, cancelall
|
* @param {string} eventName The name of the event. Events: schedule, trigger, click, update, clear, clearall, cancel,
|
||||||
* @param {any} callback Call back function.
|
* cancelall. Custom event names are possible for actions.
|
||||||
|
* @return {Observable<any>} Observable
|
||||||
*/
|
*/
|
||||||
on(eventName: string, callback: any): void {
|
on(eventName: string): Observable<any> {
|
||||||
if (!this.observers[eventName] || typeof callback != 'function') {
|
return this.observers[eventName];
|
||||||
// Event not supported, stop.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.observers[eventName].push(callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a interval and convert it to a number of milliseconds (0 if not valid).
|
* Parse a interval and convert it to a number of milliseconds (0 if not valid).
|
||||||
* Code extracted from the Cordova plugin.
|
|
||||||
*
|
*
|
||||||
* @param {string} every Interval to convert.
|
* @param {string} every Interval to convert.
|
||||||
* @return {number} Number of milliseconds of the interval-
|
* @return {number} Number of milliseconds of the interval-
|
||||||
|
@ -607,12 +900,13 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register permission to show notifications if not already granted.
|
* Removes a group of actions.
|
||||||
*
|
*
|
||||||
* @returns {Promise<boolean>}
|
* @param {any} groupId The id of the action group
|
||||||
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
registerPermission(): Promise<boolean> {
|
removeActions(groupId: any): Promise<any> {
|
||||||
return Promise.resolve(true);
|
return Promise.reject('Not supported in desktop apps.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -625,6 +919,15 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
return this.appDB.deleteRecords(this.DESKTOP_NOTIFS_TABLE, { id: id });
|
return this.appDB.deleteRecords(this.DESKTOP_NOTIFS_TABLE, { id: id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request permission to show notifications if not already granted.
|
||||||
|
*
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
requestPermission(): Promise<boolean> {
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a single or multiple notifications.
|
* Schedules a single or multiple notifications.
|
||||||
*
|
*
|
||||||
|
@ -656,13 +959,15 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
};
|
};
|
||||||
this.storeNotification(notification, false);
|
this.storeNotification(notification, false);
|
||||||
|
|
||||||
if (Math.abs(moment().diff(notification.at * 1000, 'days')) > 15) {
|
const triggerAt = this.getNotificationTriggerAt(notification);
|
||||||
|
|
||||||
|
if (Math.abs(moment().diff(triggerAt, 'days')) > 15) {
|
||||||
// Notification should trigger more than 15 days from now, don't schedule it.
|
// Notification should trigger more than 15 days from now, don't schedule it.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule the notification.
|
// Schedule the notification.
|
||||||
const toTriggerTime = notification.at * 1000 - Date.now(),
|
const toTriggerTime = triggerAt - Date.now(),
|
||||||
trigger = (): void => {
|
trigger = (): void => {
|
||||||
// Trigger the notification.
|
// Trigger the notification.
|
||||||
this.triggerNotification(notification);
|
this.triggerNotification(notification);
|
||||||
|
@ -672,10 +977,12 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
this.storeNotification(notification, true);
|
this.storeNotification(notification, true);
|
||||||
|
|
||||||
// Launch the trigger event.
|
// Launch the trigger event.
|
||||||
this.triggerEvent('trigger', notification, 'foreground');
|
this.fireEvent('trigger', notification);
|
||||||
|
|
||||||
if (notification.every && this.scheduled[notification.id] && !this.scheduled[notification.id].interval) {
|
if (notification.trigger.every && this.scheduled[notification.id] &&
|
||||||
const interval = this.parseInterval(notification.every);
|
!this.scheduled[notification.id].interval) {
|
||||||
|
|
||||||
|
const interval = this.parseInterval(notification.trigger.every);
|
||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
this.scheduled[notification.id].interval = setInterval(trigger, interval);
|
this.scheduled[notification.id].interval = setInterval(trigger, interval);
|
||||||
}
|
}
|
||||||
|
@ -685,10 +992,22 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
this.scheduled[notification.id].timeout = setTimeout(trigger, toTriggerTime);
|
this.scheduled[notification.id].timeout = setTimeout(trigger, toTriggerTime);
|
||||||
|
|
||||||
// Launch the scheduled/update event.
|
// Launch the scheduled/update event.
|
||||||
this.triggerEvent(eventName, notification, 'foreground');
|
this.fireEvent(eventName, notification);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrites the (platform specific) default settings.
|
||||||
|
*
|
||||||
|
* @param {any} defaults The defaults to set.
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
setDefaults(defaults: any): Promise<any> {
|
||||||
|
this.defaults = defaults;
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a notification in local DB.
|
* Store a notification in local DB.
|
||||||
*
|
*
|
||||||
|
@ -702,7 +1021,7 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
id : notification.id,
|
id : notification.id,
|
||||||
title: notification.title,
|
title: notification.title,
|
||||||
text: notification.text,
|
text: notification.text,
|
||||||
at: notification.at ? (typeof notification.at == 'object' ? notification.at.getTime() : notification.at) : 0,
|
at: this.getNotificationTriggerAt(notification),
|
||||||
data: notification.data ? JSON.stringify(notification.data) : '{}',
|
data: notification.data ? JSON.stringify(notification.data) : '{}',
|
||||||
triggered: triggered ? 1 : 0
|
triggered: triggered ? 1 : 0
|
||||||
};
|
};
|
||||||
|
@ -710,20 +1029,6 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
return this.appDB.insertRecord(this.DESKTOP_NOTIFS_TABLE, entry);
|
return this.appDB.insertRecord(this.DESKTOP_NOTIFS_TABLE, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger an event.
|
|
||||||
*
|
|
||||||
* @param {string} eventName Event name.
|
|
||||||
* @param {any[]} ...args List of parameters to pass.
|
|
||||||
*/
|
|
||||||
protected triggerEvent(eventName: string, ...args: any[]): void {
|
|
||||||
if (this.observers[eventName]) {
|
|
||||||
this.observers[eventName].forEach((callback) => {
|
|
||||||
callback.apply(null, args);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger a notification, using the best method depending on the OS.
|
* Trigger a notification, using the best method depending on the OS.
|
||||||
*
|
*
|
||||||
|
@ -763,7 +1068,7 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
} else {
|
} else {
|
||||||
// Use Electron default notifications.
|
// Use Electron default notifications.
|
||||||
const notifInstance = new Notification(notification.title, {
|
const notifInstance = new Notification(notification.title, {
|
||||||
body: notification.text
|
body: <string> notification.text
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen for click events.
|
// Listen for click events.
|
||||||
|
@ -773,23 +1078,6 @@ export class LocalNotificationsMock extends LocalNotifications {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a callback of a specific event.
|
|
||||||
*
|
|
||||||
* @param {string} eventName Name of the event. Events: schedule, trigger, click, update, clear, clearall, cancel, cancelall
|
|
||||||
* @param {any} callback Call back function.
|
|
||||||
*/
|
|
||||||
un(eventName: string, callback: any): void {
|
|
||||||
if (this.observers[eventName] && this.observers[eventName].length) {
|
|
||||||
for (let i = 0; i < this.observers[eventName].length; i++) {
|
|
||||||
if (this.observers[eventName][i] == callback) {
|
|
||||||
this.observers[eventName].splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a previously scheduled notification. Must include the id in the options parameter.
|
* Updates a previously scheduled notification. Must include the id in the options parameter.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue