commit
9c33cf4268
|
@ -111,7 +111,7 @@
|
||||||
<plugin name="cordova-plugin-globalization" spec="^1.11.0" />
|
<plugin name="cordova-plugin-globalization" spec="^1.11.0" />
|
||||||
<plugin name="cordova-plugin-inappbrowser" spec="^3.0.0" />
|
<plugin name="cordova-plugin-inappbrowser" spec="^3.0.0" />
|
||||||
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.1.3" />
|
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.1.3" />
|
||||||
<plugin name="cordova-plugin-local-notifications-mm" spec="^1.0.13" />
|
<plugin name="cordova-plugin-local-notification" spec="^0.9.0-beta.2" />
|
||||||
<plugin name="cordova-plugin-media-capture" spec="^3.0.2" />
|
<plugin name="cordova-plugin-media-capture" spec="^3.0.2" />
|
||||||
<plugin name="cordova-plugin-network-information" spec="^2.0.1" />
|
<plugin name="cordova-plugin-network-information" spec="^2.0.1" />
|
||||||
<plugin name="cordova-plugin-screen-orientation" spec="^3.0.1" />
|
<plugin name="cordova-plugin-screen-orientation" spec="^3.0.1" />
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
|
@ -59,7 +59,7 @@
|
||||||
"@ionic-native/globalization": "^4.17.0",
|
"@ionic-native/globalization": "^4.17.0",
|
||||||
"@ionic-native/in-app-browser": "^4.17.0",
|
"@ionic-native/in-app-browser": "^4.17.0",
|
||||||
"@ionic-native/keyboard": "^4.17.0",
|
"@ionic-native/keyboard": "^4.17.0",
|
||||||
"@ionic-native/local-notifications": "4.5.2",
|
"@ionic-native/local-notifications": "^4.17.0",
|
||||||
"@ionic-native/media-capture": "^4.17.0",
|
"@ionic-native/media-capture": "^4.17.0",
|
||||||
"@ionic-native/network": "^4.17.0",
|
"@ionic-native/network": "^4.17.0",
|
||||||
"@ionic-native/push": "^4.17.0",
|
"@ionic-native/push": "^4.17.0",
|
||||||
|
@ -83,7 +83,6 @@
|
||||||
"cordova-android-support-gradle-release": "^2.0.1",
|
"cordova-android-support-gradle-release": "^2.0.1",
|
||||||
"cordova-clipboard": "^1.2.1",
|
"cordova-clipboard": "^1.2.1",
|
||||||
"cordova-ios": "4.5.5",
|
"cordova-ios": "4.5.5",
|
||||||
"cordova-plugin-app-event": "1.2.1",
|
|
||||||
"cordova-plugin-badge": "^0.8.8",
|
"cordova-plugin-badge": "^0.8.8",
|
||||||
"cordova-plugin-camera": "^4.0.3",
|
"cordova-plugin-camera": "^4.0.3",
|
||||||
"cordova-plugin-customurlscheme": "^4.3.0",
|
"cordova-plugin-customurlscheme": "^4.3.0",
|
||||||
|
@ -94,7 +93,7 @@
|
||||||
"cordova-plugin-globalization": "^1.11.0",
|
"cordova-plugin-globalization": "^1.11.0",
|
||||||
"cordova-plugin-inappbrowser": "^3.0.0",
|
"cordova-plugin-inappbrowser": "^3.0.0",
|
||||||
"cordova-plugin-ionic-keyboard": "^2.1.3",
|
"cordova-plugin-ionic-keyboard": "^2.1.3",
|
||||||
"cordova-plugin-local-notifications-mm": "^1.0.13",
|
"cordova-plugin-local-notification": "^0.9.0-beta.2",
|
||||||
"cordova-plugin-media-capture": "^3.0.2",
|
"cordova-plugin-media-capture": "^3.0.2",
|
||||||
"cordova-plugin-network-information": "^2.0.1",
|
"cordova-plugin-network-information": "^2.0.1",
|
||||||
"cordova-plugin-screen-orientation": "^3.0.1",
|
"cordova-plugin-screen-orientation": "^3.0.1",
|
||||||
|
@ -119,9 +118,9 @@
|
||||||
"zone.js": "^0.8.26"
|
"zone.js": "^0.8.26"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ionic/app-scripts": "3.1.9",
|
"@ionic/app-scripts": "^3.2.1",
|
||||||
"electron-rebuild": "^1.8.1",
|
|
||||||
"electron-builder-lib": "^20.23.1",
|
"electron-builder-lib": "^20.23.1",
|
||||||
|
"electron-rebuild": "^1.8.1",
|
||||||
"gulp": "^4.0.0",
|
"gulp": "^4.0.0",
|
||||||
"gulp-clip-empty-files": "^0.1.2",
|
"gulp-clip-empty-files": "^0.1.2",
|
||||||
"gulp-flatten": "^0.4.0",
|
"gulp-flatten": "^0.4.0",
|
||||||
|
@ -159,7 +158,7 @@
|
||||||
"cordova-plugin-globalization": {},
|
"cordova-plugin-globalization": {},
|
||||||
"cordova-plugin-inappbrowser": {},
|
"cordova-plugin-inappbrowser": {},
|
||||||
"cordova-plugin-ionic-keyboard": {},
|
"cordova-plugin-ionic-keyboard": {},
|
||||||
"cordova-plugin-local-notifications-mm": {},
|
"cordova-plugin-local-notification": {},
|
||||||
"cordova-plugin-media-capture": {},
|
"cordova-plugin-media-capture": {},
|
||||||
"cordova-plugin-network-information": {},
|
"cordova-plugin-network-information": {},
|
||||||
"cordova-plugin-screen-orientation": {},
|
"cordova-plugin-screen-orientation": {},
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreSite } from '@classes/site';
|
import { CoreSite } from '@classes/site';
|
||||||
|
@ -23,6 +22,7 @@ import { CoreGroupsProvider } from '@providers/groups';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { CoreLocalNotificationsProvider } from '@providers/local-notifications';
|
import { CoreLocalNotificationsProvider } from '@providers/local-notifications';
|
||||||
import { CoreConfigProvider } from '@providers/config';
|
import { CoreConfigProvider } from '@providers/config';
|
||||||
|
import { ILocalNotification } from '@ionic-native/local-notifications';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to handle calendar events.
|
* Service to handle calendar events.
|
||||||
|
@ -132,8 +132,7 @@ export class AddonCalendarProvider {
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private groupsProvider: CoreGroupsProvider,
|
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private groupsProvider: CoreGroupsProvider,
|
||||||
private coursesProvider: CoreCoursesProvider, private timeUtils: CoreTimeUtilsProvider,
|
private coursesProvider: CoreCoursesProvider, private timeUtils: CoreTimeUtilsProvider,
|
||||||
private localNotificationsProvider: CoreLocalNotificationsProvider, private configProvider: CoreConfigProvider,
|
private localNotificationsProvider: CoreLocalNotificationsProvider, private configProvider: CoreConfigProvider) {
|
||||||
private translate: TranslateService) {
|
|
||||||
this.logger = logger.getInstance('AddonCalendarProvider');
|
this.logger = logger.getInstance('AddonCalendarProvider');
|
||||||
this.sitesProvider.createTablesFromSchema(this.tablesSchema);
|
this.sitesProvider.createTablesFromSchema(this.tablesSchema);
|
||||||
}
|
}
|
||||||
|
@ -526,16 +525,12 @@ export class AddonCalendarProvider {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const dateTriggered = new Date((event.timestart - (time * 60)) * 1000),
|
const notification: ILocalNotification = {
|
||||||
notification = {
|
|
||||||
id: event.id,
|
id: event.id,
|
||||||
title: event.name,
|
title: event.name,
|
||||||
text: this.timeUtils.userDate(event.timestart * 1000, 'core.strftimedaydatetime', true),
|
text: this.timeUtils.userDate(event.timestart * 1000, 'core.strftimedaydatetime', true),
|
||||||
at: dateTriggered,
|
trigger: {
|
||||||
channelParams: {
|
at: new Date((event.timestart - (time * 60)) * 1000)
|
||||||
channelID: 'notifications',
|
|
||||||
channelName: this.translate.instant('addon.notifications.notifications'),
|
|
||||||
importance: 4 // IMPORTANCE_HIGH
|
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
eventid: event.id,
|
eventid: event.id,
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable, NgZone } from '@angular/core';
|
import { Injectable, NgZone } from '@angular/core';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { Badge } from '@ionic-native/badge';
|
import { Badge } from '@ionic-native/badge';
|
||||||
import { Push, PushObject, PushOptions } from '@ionic-native/push';
|
import { Push, PushObject, PushOptions } from '@ionic-native/push';
|
||||||
import { Device } from '@ionic-native/device';
|
import { Device } from '@ionic-native/device';
|
||||||
|
@ -28,6 +27,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||||
import { CoreConfigProvider } from '@providers/config';
|
import { CoreConfigProvider } from '@providers/config';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { CoreConfigConstants } from '../../../configconstants';
|
import { CoreConfigConstants } from '../../../configconstants';
|
||||||
|
import { ILocalNotification } from '@ionic-native/local-notifications';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to handle push notifications.
|
* Service to handle push notifications.
|
||||||
|
@ -66,8 +66,7 @@ export class AddonPushNotificationsProvider {
|
||||||
protected pushNotificationsDelegate: AddonPushNotificationsDelegate, protected sitesProvider: CoreSitesProvider,
|
protected pushNotificationsDelegate: AddonPushNotificationsDelegate, protected sitesProvider: CoreSitesProvider,
|
||||||
private badge: Badge, private localNotificationsProvider: CoreLocalNotificationsProvider,
|
private badge: Badge, private localNotificationsProvider: CoreLocalNotificationsProvider,
|
||||||
private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider, private push: Push,
|
private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider, private push: Push,
|
||||||
private configProvider: CoreConfigProvider, private device: Device, private zone: NgZone,
|
private configProvider: CoreConfigProvider, private device: Device, private zone: NgZone) {
|
||||||
private translate: TranslateService) {
|
|
||||||
this.logger = logger.getInstance('AddonPushNotificationsProvider');
|
this.logger = logger.getInstance('AddonPushNotificationsProvider');
|
||||||
this.appDB = appProvider.getDB();
|
this.appDB = appProvider.getDB();
|
||||||
this.appDB.createTablesFromSchema(this.tablesSchema);
|
this.appDB.createTablesFromSchema(this.tablesSchema);
|
||||||
|
@ -153,13 +152,10 @@ export class AddonPushNotificationsProvider {
|
||||||
if (this.utils.isTrueOrOne(data.foreground)) {
|
if (this.utils.isTrueOrOne(data.foreground)) {
|
||||||
// If the app is in foreground when the notification is received, it's not shown. Let's show it ourselves.
|
// If the app is in foreground when the notification is received, it's not shown. Let's show it ourselves.
|
||||||
if (this.localNotificationsProvider.isAvailable()) {
|
if (this.localNotificationsProvider.isAvailable()) {
|
||||||
const localNotif = {
|
const localNotif: ILocalNotification = {
|
||||||
id: 1,
|
id: 1,
|
||||||
at: new Date(),
|
trigger: {
|
||||||
channelParams: {
|
at: new Date()
|
||||||
channelID: 'notifications',
|
|
||||||
channelName: this.translate.instant('addon.notifications.notifications'),
|
|
||||||
importance: 4 // IMPORTANCE_HIGH
|
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
notif: data.notif,
|
notif: data.notif,
|
||||||
|
|
|
@ -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;
|
|
||||||
|
Object.assign(values, notification);
|
||||||
|
|
||||||
|
for (const key in values) {
|
||||||
|
if (values[key] !== null) {
|
||||||
|
notification[key] = values[key];
|
||||||
} else {
|
} else {
|
||||||
notification[key] = this.defaults[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const key in notification) {
|
|
||||||
if (!this.defaults.hasOwnProperty(key)) {
|
|
||||||
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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -24,24 +24,7 @@ import { CoreTextUtilsProvider } from './utils/text';
|
||||||
import { CoreUtilsProvider } from './utils/utils';
|
import { CoreUtilsProvider } from './utils/utils';
|
||||||
import { SQLiteDB } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
|
|
||||||
/**
|
|
||||||
* Local notification.
|
|
||||||
*/
|
|
||||||
export interface CoreILocalNotification extends ILocalNotification {
|
|
||||||
/**
|
|
||||||
* Number of milliseconds to turn the led on (Android only).
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ledOnTime?: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of milliseconds to turn the led off (Android only).
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ledOffTime?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generated class for the LocalNotificationsProvider provider.
|
* Generated class for the LocalNotificationsProvider provider.
|
||||||
|
@ -115,6 +98,8 @@ export class CoreLocalNotificationsProvider {
|
||||||
ids: [],
|
ids: [],
|
||||||
timeouts: []
|
timeouts: []
|
||||||
};
|
};
|
||||||
|
protected triggerSubscription: Subscription;
|
||||||
|
protected clickSubscription: Subscription;
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private localNotifications: LocalNotifications, private platform: Platform,
|
constructor(logger: CoreLoggerProvider, private localNotifications: LocalNotifications, private platform: Platform,
|
||||||
private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private configProvider: CoreConfigProvider,
|
private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private configProvider: CoreConfigProvider,
|
||||||
|
@ -126,16 +111,15 @@ export class CoreLocalNotificationsProvider {
|
||||||
this.appDB.createTablesFromSchema(this.tablesSchema);
|
this.appDB.createTablesFromSchema(this.tablesSchema);
|
||||||
|
|
||||||
platform.ready().then(() => {
|
platform.ready().then(() => {
|
||||||
localNotifications.on('trigger', (notification, state) => {
|
this.triggerSubscription = localNotifications.on('trigger').subscribe((notification: ILocalNotification) => {
|
||||||
this.trigger(notification);
|
this.trigger(notification);
|
||||||
});
|
});
|
||||||
|
|
||||||
localNotifications.on('click', (notification, state) => {
|
this.clickSubscription = localNotifications.on('click').subscribe((notification: ILocalNotification) => {
|
||||||
if (notification && notification.data) {
|
if (notification && notification.data) {
|
||||||
this.logger.debug('Notification clicked: ', notification.data);
|
this.logger.debug('Notification clicked: ', notification.data);
|
||||||
|
|
||||||
const data = textUtils.parseJSON(notification.data);
|
this.notifyClick(notification.data);
|
||||||
this.notifyClick(data);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -175,7 +159,7 @@ export class CoreLocalNotificationsProvider {
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.localNotifications.getAllScheduled().then((scheduled) => {
|
return this.localNotifications.getScheduled().then((scheduled) => {
|
||||||
const ids = [];
|
const ids = [];
|
||||||
|
|
||||||
scheduled.forEach((notif) => {
|
scheduled.forEach((notif) => {
|
||||||
|
@ -291,12 +275,18 @@ export class CoreLocalNotificationsProvider {
|
||||||
/**
|
/**
|
||||||
* Check if a notification has been triggered with the same trigger time.
|
* Check if a notification has been triggered with the same trigger time.
|
||||||
*
|
*
|
||||||
* @param {CoreILocalNotification} notification Notification to check.
|
* @param {ILocalNotification} notification Notification to check.
|
||||||
* @return {Promise<any>} Promise resolved with a boolean indicating if promise is triggered (true) or not.
|
* @return {Promise<any>} Promise resolved with a boolean indicating if promise is triggered (true) or not.
|
||||||
*/
|
*/
|
||||||
isTriggered(notification: CoreILocalNotification): Promise<any> {
|
isTriggered(notification: ILocalNotification): Promise<any> {
|
||||||
return this.appDB.getRecord(this.TRIGGERED_TABLE, { id: notification.id }).then((stored) => {
|
return this.appDB.getRecord(this.TRIGGERED_TABLE, { id: notification.id }).then((stored) => {
|
||||||
return stored.at === notification.at.getTime() / 1000;
|
let triggered = (notification.trigger && notification.trigger.at) || 0;
|
||||||
|
|
||||||
|
if (typeof triggered != 'number') {
|
||||||
|
triggered = triggered.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
return stored.at === triggered;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
return this.localNotifications.isTriggered(notification.id);
|
return this.localNotifications.isTriggered(notification.id);
|
||||||
});
|
});
|
||||||
|
@ -426,12 +416,11 @@ export class CoreLocalNotificationsProvider {
|
||||||
*/
|
*/
|
||||||
rescheduleAll(): Promise<any> {
|
rescheduleAll(): Promise<any> {
|
||||||
// Get all the scheduled notifications.
|
// Get all the scheduled notifications.
|
||||||
return this.localNotifications.getAllScheduled().then((notifications) => {
|
return this.localNotifications.getScheduled().then((notifications) => {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
notifications.forEach((notification) => {
|
notifications.forEach((notification) => {
|
||||||
// Convert some properties to the needed types.
|
// Convert some properties to the needed types.
|
||||||
notification.at = new Date(notification.at * 1000);
|
|
||||||
notification.data = notification.data ? this.textUtils.parseJSON(notification.data, {}) : {};
|
notification.data = notification.data ? this.textUtils.parseJSON(notification.data, {}) : {};
|
||||||
|
|
||||||
promises.push(this.scheduleNotification(notification));
|
promises.push(this.scheduleNotification(notification));
|
||||||
|
@ -444,13 +433,13 @@ export class CoreLocalNotificationsProvider {
|
||||||
/**
|
/**
|
||||||
* Schedule a local notification.
|
* Schedule a local notification.
|
||||||
*
|
*
|
||||||
* @param {CoreILocalNotification} notification Notification to schedule. Its ID should be lower than 10000000 and it should
|
* @param {ILocalNotification} notification Notification to schedule. Its ID should be lower than 10000000 and it should
|
||||||
* be unique inside its component and site.
|
* be unique inside its component and site.
|
||||||
* @param {string} component Component triggering the notification. It is used to generate unique IDs.
|
* @param {string} component Component triggering the notification. It is used to generate unique IDs.
|
||||||
* @param {string} siteId Site ID.
|
* @param {string} siteId Site ID.
|
||||||
* @return {Promise<any>} Promise resolved when the notification is scheduled.
|
* @return {Promise<any>} Promise resolved when the notification is scheduled.
|
||||||
*/
|
*/
|
||||||
schedule(notification: CoreILocalNotification, component: string, siteId: string): Promise<any> {
|
schedule(notification: ILocalNotification, component: string, siteId: string): Promise<any> {
|
||||||
return this.getUniqueNotificationId(notification.id, component, siteId).then((uniqueId) => {
|
return this.getUniqueNotificationId(notification.id, component, siteId).then((uniqueId) => {
|
||||||
notification.id = uniqueId;
|
notification.id = uniqueId;
|
||||||
notification.data = notification.data || {};
|
notification.data = notification.data || {};
|
||||||
|
@ -460,9 +449,13 @@ export class CoreLocalNotificationsProvider {
|
||||||
if (this.platform.is('android')) {
|
if (this.platform.is('android')) {
|
||||||
notification.icon = notification.icon || 'res://icon';
|
notification.icon = notification.icon || 'res://icon';
|
||||||
notification.smallIcon = notification.smallIcon || 'res://icon';
|
notification.smallIcon = notification.smallIcon || 'res://icon';
|
||||||
notification.led = notification.led || 'FF9900';
|
|
||||||
notification.ledOnTime = notification.ledOnTime || 1000;
|
const led: any = notification.led || {};
|
||||||
notification.ledOffTime = notification.ledOffTime || 1000;
|
notification.led = {
|
||||||
|
color: led.color || 'FF9900',
|
||||||
|
on: led.on || 1000,
|
||||||
|
off: led.off || 1000
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.scheduleNotification(notification);
|
return this.scheduleNotification(notification);
|
||||||
|
@ -472,10 +465,10 @@ export class CoreLocalNotificationsProvider {
|
||||||
/**
|
/**
|
||||||
* Helper function to schedule a notification object if it hasn't been triggered already.
|
* Helper function to schedule a notification object if it hasn't been triggered already.
|
||||||
*
|
*
|
||||||
* @param {CoreILocalNotification} notification Notification to schedule.
|
* @param {ILocalNotification} notification Notification to schedule.
|
||||||
* @return {Promise<any>} Promise resolved when scheduled.
|
* @return {Promise<any>} Promise resolved when scheduled.
|
||||||
*/
|
*/
|
||||||
protected scheduleNotification(notification: CoreILocalNotification): Promise<any> {
|
protected scheduleNotification(notification: ILocalNotification): Promise<any> {
|
||||||
// Check if the notification has been triggered already.
|
// Check if the notification has been triggered already.
|
||||||
return this.isTriggered(notification).then((triggered) => {
|
return this.isTriggered(notification).then((triggered) => {
|
||||||
// Cancel the current notification in case it gets scheduled twice.
|
// Cancel the current notification in case it gets scheduled twice.
|
||||||
|
@ -503,9 +496,9 @@ export class CoreLocalNotificationsProvider {
|
||||||
* This function was used because local notifications weren't displayed when the app was in foreground in iOS10+,
|
* This function was used because local notifications weren't displayed when the app was in foreground in iOS10+,
|
||||||
* but the issue was fixed in the plugin and this function is no longer used.
|
* but the issue was fixed in the plugin and this function is no longer used.
|
||||||
*
|
*
|
||||||
* @param {CoreILocalNotification} notification Notification.
|
* @param {ILocalNotification} notification Notification.
|
||||||
*/
|
*/
|
||||||
showNotificationPopover(notification: CoreILocalNotification): void {
|
showNotificationPopover(notification: ILocalNotification): void {
|
||||||
|
|
||||||
if (!notification || !notification.title || !notification.text) {
|
if (!notification || !notification.title || !notification.text) {
|
||||||
// Invalid data.
|
// Invalid data.
|
||||||
|
@ -595,13 +588,13 @@ export class CoreLocalNotificationsProvider {
|
||||||
* Function to call when a notification is triggered. Stores the notification so it's not scheduled again unless the
|
* Function to call when a notification is triggered. Stores the notification so it's not scheduled again unless the
|
||||||
* time is changed.
|
* time is changed.
|
||||||
*
|
*
|
||||||
* @param {CoreILocalNotification} notification Triggered notification.
|
* @param {ILocalNotification} notification Triggered notification.
|
||||||
* @return {Promise<any>} Promise resolved when stored, rejected otherwise.
|
* @return {Promise<any>} Promise resolved when stored, rejected otherwise.
|
||||||
*/
|
*/
|
||||||
trigger(notification: CoreILocalNotification): Promise<any> {
|
trigger(notification: ILocalNotification): Promise<any> {
|
||||||
const entry = {
|
const entry = {
|
||||||
id: notification.id,
|
id: notification.id,
|
||||||
at: parseInt(notification.at, 10)
|
at: notification.trigger && notification.trigger.at ? notification.trigger.at : Date.now()
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.appDB.insertRecord(this.TRIGGERED_TABLE, entry);
|
return this.appDB.insertRecord(this.TRIGGERED_TABLE, entry);
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
This files describes API changes in the Moodle Mobile app,
|
This files describes API changes in the Moodle Mobile app,
|
||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
|
=== 3.6.1 ===
|
||||||
|
|
||||||
|
- The local notifications plugin was updated to its latest version. The new API has some breaking changes, so please check its documentation if you're using local notifications. Also, you need to run "npm install" to update the ionic-native library.
|
||||||
|
|
||||||
=== 3.6.0 ===
|
=== 3.6.0 ===
|
||||||
|
|
||||||
- gulp was updated to v4. In order for gulp to work, you need to install gulp-cli: npm install -g gulp-cli
|
- gulp was updated to v4. In order for gulp to work, you need to install gulp-cli: npm install -g gulp-cli
|
||||||
|
|
Loading…
Reference in New Issue