2017-11-14 14:43:03 +00:00
|
|
|
|
// (C) Copyright 2015 Martin Dougiamas
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
|
|
import { Injectable } from '@angular/core';
|
|
|
|
|
import { Platform } from 'ionic-angular';
|
|
|
|
|
import { LocalNotifications, ILocalNotification } from '@ionic-native/local-notifications';
|
|
|
|
|
import { CoreAppProvider } from './app';
|
|
|
|
|
import { CoreConfigProvider } from './config';
|
|
|
|
|
import { CoreLoggerProvider } from './logger';
|
|
|
|
|
import { CoreDomUtilsProvider } from './utils/dom';
|
|
|
|
|
import { CoreUtilsProvider } from './utils/utils';
|
|
|
|
|
import { SQLiteDB } from '../classes/sqlitedb';
|
|
|
|
|
import { CoreConstants } from '../core/constants';
|
|
|
|
|
import { Subject } from 'rxjs';
|
|
|
|
|
|
|
|
|
|
export interface CoreILocalNotification extends ILocalNotification {
|
|
|
|
|
ledOnTime?: number;
|
|
|
|
|
ledOffTime?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Generated class for the LocalNotificationsProvider provider.
|
|
|
|
|
|
|
|
|
|
See https://angular.io/guide/dependency-injection for more info on providers
|
|
|
|
|
and Angular DI.
|
|
|
|
|
*/
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class CoreLocalNotificationsProvider {
|
|
|
|
|
// Variables for the database.
|
|
|
|
|
protected SITES_TABLE = 'notification_sites'; // Store to asigne unique codes to each site.
|
|
|
|
|
protected COMPONENTS_TABLE = 'notification_components'; // Store to asigne unique codes to each component.
|
|
|
|
|
protected TRIGGERED_TABLE = 'notifications_triggered'; // Store to prevent re-triggering notifications.
|
|
|
|
|
protected tablesSchema = [
|
|
|
|
|
{
|
|
|
|
|
name: this.SITES_TABLE,
|
|
|
|
|
columns: [
|
|
|
|
|
{
|
|
|
|
|
name: 'id',
|
|
|
|
|
type: 'TEXT',
|
|
|
|
|
primaryKey: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'code',
|
|
|
|
|
type: 'INTEGER',
|
|
|
|
|
notNull: true
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: this.COMPONENTS_TABLE,
|
|
|
|
|
columns: [
|
|
|
|
|
{
|
|
|
|
|
name: 'id',
|
|
|
|
|
type: 'TEXT',
|
|
|
|
|
primaryKey: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'code',
|
|
|
|
|
type: 'INTEGER',
|
|
|
|
|
notNull: true
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: this.TRIGGERED_TABLE,
|
|
|
|
|
columns: [
|
|
|
|
|
{
|
|
|
|
|
name: 'id',
|
|
|
|
|
type: 'INTEGER',
|
|
|
|
|
primaryKey: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'at',
|
|
|
|
|
type: 'INTEGER',
|
|
|
|
|
notNull: true
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
protected logger;
|
|
|
|
|
protected appDB: SQLiteDB;
|
|
|
|
|
protected codes: {[s: string]: number} = {};
|
|
|
|
|
protected codeRequestsQueue = {};
|
|
|
|
|
protected observables = {};
|
|
|
|
|
|
|
|
|
|
constructor(logger: CoreLoggerProvider, private localNotifications: LocalNotifications, private platform: Platform,
|
|
|
|
|
private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private configProvider: CoreConfigProvider,
|
|
|
|
|
private domUtils: CoreDomUtilsProvider) {
|
|
|
|
|
this.logger = logger.getInstance('CoreLocalNotificationsProvider');
|
|
|
|
|
this.appDB = appProvider.getDB();
|
|
|
|
|
this.appDB.createTablesFromSchema(this.tablesSchema);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cancel a local notification.
|
|
|
|
|
*
|
|
|
|
|
* @param {number} id Notification id.
|
|
|
|
|
* @param {string} component Component of the notification.
|
|
|
|
|
* @param {string} siteId Site ID.
|
|
|
|
|
* @return {Promise<any>} Promise resolved when the notification is cancelled.
|
|
|
|
|
*/
|
|
|
|
|
cancel(id, component, siteId) : Promise<any> {
|
|
|
|
|
return this.getUniqueNotificationId(id, component, siteId).then((uniqueId) => {
|
|
|
|
|
return this.localNotifications.cancel(uniqueId);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cancel all the scheduled notifications belonging to a certain site.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} siteId Site ID.
|
|
|
|
|
* @return {Promise<any>} Promise resolved when the notifications are cancelled.
|
|
|
|
|
*/
|
|
|
|
|
cancelSiteNotifications(siteId) : Promise<any> {
|
|
|
|
|
|
|
|
|
|
if (!this.isAvailable()) {
|
|
|
|
|
return Promise.resolve();
|
|
|
|
|
} else if (!siteId) {
|
|
|
|
|
return Promise.reject(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.localNotifications.getAllScheduled().then((scheduled) => {
|
|
|
|
|
let ids = [];
|
|
|
|
|
|
|
|
|
|
scheduled.forEach((notif) => {
|
|
|
|
|
if (typeof notif.data == 'string') {
|
|
|
|
|
notif.data = JSON.parse(notif.data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof notif.data == 'object' && notif.data.siteId === siteId) {
|
|
|
|
|
ids.push(notif.id);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return this.localNotifications.cancel(ids);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a code to create unique notifications. If there's no code assigned, create a new one.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} table Table to search in local DB.
|
|
|
|
|
* @param {string} id ID of the element to get its code.
|
|
|
|
|
* @return {Promise<number>} Promise resolved when the code is retrieved.
|
|
|
|
|
*/
|
|
|
|
|
protected getCode(table, id) : Promise<number> {
|
|
|
|
|
const key = table + '#' + id;
|
|
|
|
|
|
|
|
|
|
// Check if the code is already in memory.
|
|
|
|
|
if (typeof this.codes[key] != 'undefined') {
|
|
|
|
|
return Promise.resolve(this.codes[key]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if we already have a code stored for that ID.
|
|
|
|
|
return this.appDB.getRecord(table, {id: id}).then((entry) => {
|
|
|
|
|
this.codes[key] = entry.code;
|
|
|
|
|
return entry.code;
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
// No code stored for that ID. Create a new code for it.
|
|
|
|
|
return this.appDB.getRecords(table, undefined, 'code DESC').then((entries) => {
|
|
|
|
|
let newCode = 0;
|
|
|
|
|
if (entries.length > 0) {
|
|
|
|
|
newCode = entries[0].code + 1;
|
|
|
|
|
}
|
|
|
|
|
return this.appDB.insertRecord(table, {id: id, code: newCode}).then(() => {
|
|
|
|
|
this.codes[key] = newCode;
|
|
|
|
|
return newCode;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a notification component code to be used.
|
|
|
|
|
* If it's the first time this component is used to send notifications, create a new code for it.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} component Component name.
|
|
|
|
|
* @return {Promise<number>} Promise resolved when the component code is retrieved.
|
|
|
|
|
*/
|
|
|
|
|
protected getComponentCode(component: string) : Promise<number> {
|
|
|
|
|
return this.requestCode(this.COMPONENTS_TABLE, component);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get a site code to be used.
|
|
|
|
|
* If it's the first time this site is used to send notifications, create a new code for it.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} siteId Site ID.
|
|
|
|
|
* @return {Promise<number>} Promise resolved when the site code is retrieved.
|
|
|
|
|
*/
|
|
|
|
|
protected getSiteCode(siteId: string) : Promise<number> {
|
|
|
|
|
return this.requestCode(this.SITES_TABLE, siteId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a unique notification ID, trying to prevent collisions. Generated ID must be a Number (Android).
|
|
|
|
|
* The generated ID shouldn't be higher than 2147483647 or it's going to cause problems in Android.
|
|
|
|
|
* This function will prevent collisions and keep the number under Android limit if:
|
|
|
|
|
* -User has used less than 21 sites.
|
|
|
|
|
* -There are less than 11 components.
|
|
|
|
|
* -The notificationId passed as parameter is lower than 10000000.
|
|
|
|
|
*
|
|
|
|
|
* @param {number} notificationId Notification ID.
|
|
|
|
|
* @param {string} component Component triggering the notification.
|
|
|
|
|
* @param {string} siteId Site ID.
|
|
|
|
|
* @return {Promise<number>} Promise resolved when the notification ID is generated.
|
|
|
|
|
*/
|
|
|
|
|
protected getUniqueNotificationId(notificationId: number, component: string, siteId: string) : Promise<number> {
|
|
|
|
|
if (!siteId || !component) {
|
|
|
|
|
return Promise.reject(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.getSiteCode(siteId).then((siteCode) => {
|
|
|
|
|
return this.getComponentCode(component).then((componentCode) => {
|
|
|
|
|
// We use the % operation to keep the number under Android's limit.
|
|
|
|
|
return (siteCode * 100000000 + componentCode * 10000000 + notificationId) % 2147483647;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns whether local notifications plugin is installed.
|
|
|
|
|
*
|
|
|
|
|
* @return {boolean} Whether local notifications plugin is installed.
|
|
|
|
|
*/
|
|
|
|
|
isAvailable() : boolean {
|
|
|
|
|
let win = <any>window;
|
|
|
|
|
return this.appProvider.isDesktop() || !!(win.plugin && win.plugin.notification && win.plugin.notification.local);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a notification has been triggered with the same trigger time.
|
|
|
|
|
*
|
|
|
|
|
* @param {CoreILocalNotification} notification Notification to check.
|
|
|
|
|
* @return {Promise} Promise resolved with a boolean indicating if promise is triggered (true) or not.
|
|
|
|
|
*/
|
|
|
|
|
isTriggered(notification: CoreILocalNotification) {
|
|
|
|
|
return this.appDB.getRecord(this.TRIGGERED_TABLE, {id: notification.id}).then((stored) => {
|
|
|
|
|
return stored.at === notification.at.getTime() / 1000;
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Notify notification click to observers. Only the observers with the same component as the notification will be notified.
|
|
|
|
|
*
|
|
|
|
|
* @param {any} data Data received by the notification.
|
|
|
|
|
*/
|
|
|
|
|
notifyClick(data: any) : void {
|
|
|
|
|
const component = data.component;
|
|
|
|
|
if (component) {
|
|
|
|
|
if (this.observables[component]) {
|
|
|
|
|
this.observables[component].next(data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Process the next request in queue.
|
|
|
|
|
*/
|
|
|
|
|
protected processNextRequest() : void {
|
|
|
|
|
let nextKey = Object.keys(this.codeRequestsQueue)[0],
|
|
|
|
|
request,
|
|
|
|
|
promise;
|
|
|
|
|
|
|
|
|
|
if (typeof nextKey == 'undefined') {
|
|
|
|
|
// No more requests in queue, stop.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
request = this.codeRequestsQueue[nextKey];
|
|
|
|
|
|
|
|
|
|
// Check if request is valid.
|
|
|
|
|
if (typeof request == 'object' && typeof request.table != 'undefined' && typeof request.id != 'undefined') {
|
|
|
|
|
// Get the code and resolve/reject all the promises of this request.
|
|
|
|
|
promise = this.getCode(request.table, request.id).then((code) => {
|
|
|
|
|
request.promises.forEach((p) => {
|
|
|
|
|
p.resolve(code);
|
|
|
|
|
});
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
request.promises.forEach((p) => {
|
|
|
|
|
p.reject(error);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
promise = Promise.resolve();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Once this item is treated, remove it and process next.
|
|
|
|
|
promise.finally(() => {
|
|
|
|
|
delete this.codeRequestsQueue[nextKey];
|
|
|
|
|
this.processNextRequest();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Register an observer to be notified when a notification belonging to a certain component is clicked.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} component Component to listen notifications for.
|
|
|
|
|
* @param {Function} callback Function to call with the data received by the notification.
|
|
|
|
|
* @return {any} Object with an "off" property to stop listening for clicks.
|
|
|
|
|
*/
|
|
|
|
|
registerClick(component: string, callback: Function) : any {
|
|
|
|
|
this.logger.debug(`Register observer '${component}' for notification click.`);
|
|
|
|
|
|
|
|
|
|
if (typeof this.observables[component] == 'undefined') {
|
|
|
|
|
// No observable for this component, create a new one.
|
|
|
|
|
this.observables[component] = new Subject<any>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.observables[component].subscribe(callback);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
off: () => {
|
|
|
|
|
this.observables[component].unsubscribe(callback);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove a notification from triggered store.
|
|
|
|
|
*
|
|
|
|
|
* @param {number} id Notification ID.
|
|
|
|
|
* @return {Promise<any>} Promise resolved when it is removed.
|
|
|
|
|
*/
|
|
|
|
|
removeTriggered(id: number) : Promise<any> {
|
|
|
|
|
return this.appDB.deleteRecords(this.TRIGGERED_TABLE, {id: id});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Request a unique code. The request will be added to the queue and the queue is going to be started if it's paused.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} table Table to search in local DB.
|
|
|
|
|
* @param {string} id ID of the element to get its code.
|
|
|
|
|
* @return {Promise} Promise resolved when the code is retrieved.
|
|
|
|
|
*/
|
|
|
|
|
protected requestCode(table: string, id: string) : Promise<number> {
|
|
|
|
|
let deferred = this.utils.promiseDefer(),
|
|
|
|
|
key = table + '#' + id,
|
|
|
|
|
isQueueEmpty = Object.keys(this.codeRequestsQueue).length == 0;
|
|
|
|
|
|
|
|
|
|
if (typeof this.codeRequestsQueue[key] != 'undefined') {
|
|
|
|
|
// There's already a pending request for this store and ID, add the promise to it.
|
|
|
|
|
this.codeRequestsQueue[key].promises.push(deferred);
|
|
|
|
|
} else {
|
|
|
|
|
// Add a pending request to the queue.
|
|
|
|
|
this.codeRequestsQueue[key] = {
|
|
|
|
|
table: table,
|
|
|
|
|
id: id,
|
|
|
|
|
promises: [deferred]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isQueueEmpty) {
|
|
|
|
|
this.processNextRequest();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return deferred.promise;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reschedule all notifications that are already scheduled.
|
|
|
|
|
*
|
|
|
|
|
* @return {Promise<any>} Promise resolved when all notifications have been rescheduled.
|
|
|
|
|
*/
|
|
|
|
|
rescheduleAll() : Promise<any> {
|
|
|
|
|
// Get all the scheduled notifications.
|
|
|
|
|
return this.localNotifications.getAllScheduled().then((notifications) => {
|
|
|
|
|
let promises = [];
|
|
|
|
|
|
|
|
|
|
notifications.forEach((notification) => {
|
|
|
|
|
// Convert some properties to the needed types.
|
|
|
|
|
notification.at = new Date(notification.at * 1000);
|
|
|
|
|
notification.data = notification.data ? JSON.parse(notification.data) : {};
|
|
|
|
|
|
|
|
|
|
promises.push(this.scheduleNotification(notification));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return Promise.all(promises);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Schedule a local notification.
|
|
|
|
|
*
|
|
|
|
|
* @param {CoreILocalNotification} notification Notification to schedule. Its ID should be lower than 10000000 and it should
|
|
|
|
|
* be unique inside its component and site.
|
|
|
|
|
* @param {string} component Component triggering the notification. It is used to generate unique IDs.
|
|
|
|
|
* @param {string} siteId Site ID.
|
|
|
|
|
* @return {Promise<any>} Promise resolved when the notification is scheduled.
|
|
|
|
|
*/
|
|
|
|
|
schedule(notification: CoreILocalNotification, component: string, siteId: string) : Promise<any> {
|
|
|
|
|
return this.getUniqueNotificationId(notification.id, component, siteId).then((uniqueId) => {
|
|
|
|
|
notification.id = uniqueId;
|
|
|
|
|
notification.data = notification.data || {};
|
|
|
|
|
notification.data.component = component;
|
|
|
|
|
notification.data.siteId = siteId;
|
|
|
|
|
|
|
|
|
|
if (this.platform.is('android')) {
|
|
|
|
|
notification.icon = notification.icon || 'res://icon';
|
|
|
|
|
notification.smallIcon = notification.smallIcon || 'res://icon';
|
|
|
|
|
notification.led = notification.led || 'FF9900';
|
|
|
|
|
notification.ledOnTime = notification.ledOnTime || 1000;
|
|
|
|
|
notification.ledOffTime = notification.ledOffTime || 1000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.scheduleNotification(notification);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper function to schedule a notification object if it hasn't been triggered already.
|
|
|
|
|
*
|
|
|
|
|
* @param {CoreILocalNotification} notification Notification to schedule.
|
|
|
|
|
* @return {Promise<any>} Promise resolved when scheduled.
|
|
|
|
|
*/
|
|
|
|
|
protected scheduleNotification(notification: CoreILocalNotification) : Promise<any> {
|
|
|
|
|
// Check if the notification has been triggered already.
|
|
|
|
|
return this.isTriggered(notification).then((triggered) => {
|
|
|
|
|
if (!triggered) {
|
|
|
|
|
// Check if sound is enabled for notifications.
|
2018-01-12 13:28:46 +00:00
|
|
|
|
return this.configProvider.get(CoreConstants.SETTINGS_NOTIFICATION_SOUND, true).then((soundEnabled) => {
|
2017-11-14 14:43:03 +00:00
|
|
|
|
if (!soundEnabled) {
|
|
|
|
|
notification.sound = null;
|
|
|
|
|
} else {
|
|
|
|
|
delete notification.sound; // Use default value.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove from triggered, since the notification could be in there with a different time.
|
|
|
|
|
this.removeTriggered(notification.id);
|
|
|
|
|
this.localNotifications.schedule(notification);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Show an in app notification popover.
|
|
|
|
|
*
|
|
|
|
|
* @param {CoreILocalNotification} notification Notification.
|
|
|
|
|
*/
|
|
|
|
|
showNotificationPopover(notification: CoreILocalNotification) : void {
|
|
|
|
|
// @todo Improve it. For now, show Toast.
|
|
|
|
|
if (!notification || !notification.title || !notification.text) {
|
|
|
|
|
// Invalid data.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.domUtils.showToast(notification.text, false, 4000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Function to call when a notification is triggered. Stores the notification so it's not scheduled again unless the
|
|
|
|
|
* time is changed.
|
|
|
|
|
*
|
|
|
|
|
* @param {CoreILocalNotification} notification Triggered notification.
|
|
|
|
|
* @return {Promise<any>} Promise resolved when stored, rejected otherwise.
|
|
|
|
|
*/
|
|
|
|
|
trigger(notification: CoreILocalNotification) : Promise<any> {
|
|
|
|
|
if (this.platform.is('ios') && this.platform.version().num >= 10) {
|
|
|
|
|
// In iOS10 show in app notification.
|
|
|
|
|
this.showNotificationPopover(notification);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let entry = {
|
|
|
|
|
id: notification.id,
|
|
|
|
|
at: parseInt(notification.at, 10)
|
|
|
|
|
};
|
|
|
|
|
return this.appDB.insertOrUpdateRecord(this.TRIGGERED_TABLE, entry, {id: notification.id});
|
|
|
|
|
}
|
|
|
|
|
}
|