forked from CIT/Vmeda.Online
		
	MOBILE-3477 core: Reduce concurrent calls to local-notifications plugin
This commit is contained in:
		
							parent
							
								
									7901ed7de8
								
							
						
					
					
						commit
						e08439a91f
					
				| @ -1606,10 +1606,13 @@ export class AddonCalendarProvider { | |||||||
|      * @param siteId Site ID the event belongs to. If not defined, use current site. |      * @param siteId Site ID the event belongs to. If not defined, use current site. | ||||||
|      * @return Promise resolved when the notification is scheduled. |      * @return Promise resolved when the notification is scheduled. | ||||||
|      */ |      */ | ||||||
|     protected scheduleEventNotification(event: AddonCalendarAnyEvent, reminderId: number, time: number, siteId?: string) |     protected async scheduleEventNotification(event: AddonCalendarAnyEvent, reminderId: number, time: number, siteId?: string) | ||||||
|             : Promise<void> { |             : Promise<void> { | ||||||
| 
 | 
 | ||||||
|         if (this.localNotificationsProvider.isAvailable()) { |         if (!this.localNotificationsProvider.isAvailable()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); |         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
|         if (time === 0) { |         if (time === 0) { | ||||||
| @ -1617,25 +1620,21 @@ export class AddonCalendarProvider { | |||||||
|             return this.localNotificationsProvider.cancel(reminderId, AddonCalendarProvider.COMPONENT, siteId); |             return this.localNotificationsProvider.cancel(reminderId, AddonCalendarProvider.COMPONENT, siteId); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|             let promise; |  | ||||||
|         if (time == -1) { |         if (time == -1) { | ||||||
|             // If time is -1, get event default time to calculate the notification time.
 |             // If time is -1, get event default time to calculate the notification time.
 | ||||||
|                 promise = this.getDefaultNotificationTime(siteId).then((time) => { |             time = await this.getDefaultNotificationTime(siteId); | ||||||
|  | 
 | ||||||
|             if (time == 0) { |             if (time == 0) { | ||||||
|                 // Default notification time is disabled, do not show.
 |                 // Default notification time is disabled, do not show.
 | ||||||
|                 return this.localNotificationsProvider.cancel(reminderId, AddonCalendarProvider.COMPONENT, siteId); |                 return this.localNotificationsProvider.cancel(reminderId, AddonCalendarProvider.COMPONENT, siteId); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|                     return event.timestart - (time * 60); |             time = event.timestart - (time * 60); | ||||||
|                 }); |  | ||||||
|             } else { |  | ||||||
|                 promise = Promise.resolve(time); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|             return promise.then((time) => { |  | ||||||
|         time = time * 1000; |         time = time * 1000; | ||||||
| 
 | 
 | ||||||
|                 if (time <= new Date().getTime()) { |         if (time <= Date.now()) { | ||||||
|             // This reminder is over, don't schedule. Cancel if it was scheduled.
 |             // This reminder is over, don't schedule. Cancel if it was scheduled.
 | ||||||
|             return this.localNotificationsProvider.cancel(reminderId, AddonCalendarProvider.COMPONENT, siteId); |             return this.localNotificationsProvider.cancel(reminderId, AddonCalendarProvider.COMPONENT, siteId); | ||||||
|         } |         } | ||||||
| @ -1656,11 +1655,6 @@ export class AddonCalendarProvider { | |||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|         return this.localNotificationsProvider.schedule(notification, AddonCalendarProvider.COMPONENT, siteId); |         return this.localNotificationsProvider.schedule(notification, AddonCalendarProvider.COMPONENT, siteId); | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
|             return Promise.resolve(); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
							
								
								
									
										143
									
								
								src/classes/queue-runner.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								src/classes/queue-runner.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,143 @@ | |||||||
|  | // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||||
|  | //
 | ||||||
|  | // 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 { CoreUtils, PromiseDefer } from '@providers/utils/utils'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Function to add to the queue. | ||||||
|  |  */ | ||||||
|  | export type CoreQueueRunnerFunction<T> = (...args: any[]) => T | Promise<T>; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Queue item. | ||||||
|  |  */ | ||||||
|  | export type CoreQueueRunnerItem<T = any> = { | ||||||
|  |     /** | ||||||
|  |      * Item ID. | ||||||
|  |      */ | ||||||
|  |     id: string; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Function to execute. | ||||||
|  |      */ | ||||||
|  |     fn: CoreQueueRunnerFunction<T>; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Deferred with a promise resolved/rejected with the result of the function. | ||||||
|  |      */ | ||||||
|  |     deferred: PromiseDefer; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Options to pass to add item. | ||||||
|  |  */ | ||||||
|  | export type CoreQueueRunnerAddOptions = { | ||||||
|  |     /** | ||||||
|  |      * Whether to allow having multiple entries with same ID in the queue. | ||||||
|  |      */ | ||||||
|  |     allowRepeated?: boolean; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * A queue to prevent having too many concurrent executions. | ||||||
|  |  */ | ||||||
|  | export class CoreQueueRunner { | ||||||
|  |     protected queue: {[id: string]: CoreQueueRunnerItem} = {}; | ||||||
|  |     protected orderedQueue: CoreQueueRunnerItem[] = []; | ||||||
|  |     protected numberRunning = 0; | ||||||
|  | 
 | ||||||
|  |     constructor(protected maxParallel: number = 1) { } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get unique ID. | ||||||
|  |      * | ||||||
|  |      * @param id ID. | ||||||
|  |      * @return Unique ID. | ||||||
|  |      */ | ||||||
|  |     protected getUniqueId(id: string): string { | ||||||
|  |         let newId = id; | ||||||
|  |         let num = 1; | ||||||
|  | 
 | ||||||
|  |         do { | ||||||
|  |             newId = id + '-' + num; | ||||||
|  |             num++; | ||||||
|  |         } while (newId in this.queue); | ||||||
|  | 
 | ||||||
|  |         return newId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Process next item in the queue. | ||||||
|  |      * | ||||||
|  |      * @return Promise resolved when next item has been treated. | ||||||
|  |      */ | ||||||
|  |     protected async processNextItem(): Promise<void> { | ||||||
|  |         if (!this.orderedQueue.length || this.numberRunning >= this.maxParallel) { | ||||||
|  |             // Queue is empty or max number of parallel runs reached, stop.
 | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const item = this.orderedQueue.shift(); | ||||||
|  |         this.numberRunning++; | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             const result = await item.fn(); | ||||||
|  | 
 | ||||||
|  |             item.deferred.resolve(result); | ||||||
|  |         } catch (error) { | ||||||
|  |             item.deferred.reject(error); | ||||||
|  |         } finally { | ||||||
|  |             delete this.queue[item.id]; | ||||||
|  |             this.numberRunning--; | ||||||
|  | 
 | ||||||
|  |             this.processNextItem(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Add an item to the queue. | ||||||
|  |      * | ||||||
|  |      * @param id ID. | ||||||
|  |      * @param fn Function to call. | ||||||
|  |      * @param options Options. | ||||||
|  |      * @return Promise resolved when the function has been executed. | ||||||
|  |      */ | ||||||
|  |     run<T>(id: string, fn: CoreQueueRunnerFunction<T>, options?: CoreQueueRunnerAddOptions): Promise<T> { | ||||||
|  |         options = options || {}; | ||||||
|  | 
 | ||||||
|  |         if (id in this.queue) { | ||||||
|  |             if (!options.allowRepeated) { | ||||||
|  |                 // Item already in queue, return its promise.
 | ||||||
|  |                 return this.queue[id].deferred.promise; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             id = this.getUniqueId(id); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Add the item in the queue.
 | ||||||
|  |         const item = { | ||||||
|  |             id, | ||||||
|  |             fn, | ||||||
|  |             deferred: CoreUtils.instance.promiseDefer(), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         this.queue[id] = item; | ||||||
|  |         this.orderedQueue.push(item); | ||||||
|  | 
 | ||||||
|  |         // Process next item if we haven't reached the max yet.
 | ||||||
|  |         this.processNextItem(); | ||||||
|  | 
 | ||||||
|  |         return item.deferred.promise; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -20,7 +20,6 @@ import { CoreFileProvider } from '@providers/file'; | |||||||
| import { CoreEventsProvider } from '@providers/events'; | import { CoreEventsProvider } from '@providers/events'; | ||||||
| import { CoreLangProvider } from '@providers/lang'; | import { CoreLangProvider } from '@providers/lang'; | ||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
| import { CoreLocalNotificationsProvider } from '@providers/local-notifications'; |  | ||||||
| import { CorePushNotificationsProvider } from '@core/pushnotifications/providers/pushnotifications'; | import { CorePushNotificationsProvider } from '@core/pushnotifications/providers/pushnotifications'; | ||||||
| import { CoreConfigConstants } from '../../../../configconstants'; | import { CoreConfigConstants } from '../../../../configconstants'; | ||||||
| import { CoreSettingsHelper } from '../../providers/helper'; | import { CoreSettingsHelper } from '../../providers/helper'; | ||||||
| @ -54,7 +53,6 @@ export class CoreSettingsGeneralPage { | |||||||
|             protected langProvider: CoreLangProvider, |             protected langProvider: CoreLangProvider, | ||||||
|             protected domUtils: CoreDomUtilsProvider, |             protected domUtils: CoreDomUtilsProvider, | ||||||
|             protected pushNotificationsProvider: CorePushNotificationsProvider, |             protected pushNotificationsProvider: CorePushNotificationsProvider, | ||||||
|             localNotificationsProvider: CoreLocalNotificationsProvider, |  | ||||||
|             protected settingsHelper: CoreSettingsHelper) { |             protected settingsHelper: CoreSettingsHelper) { | ||||||
| 
 | 
 | ||||||
|         // Get the supported languages.
 |         // Get the supported languages.
 | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ import { CoreLoggerProvider } from './logger'; | |||||||
| import { CoreTextUtilsProvider } from './utils/text'; | 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 { CoreQueueRunner } from '@classes/queue-runner'; | ||||||
| import { CoreConstants } from '@core/constants'; | import { CoreConstants } from '@core/constants'; | ||||||
| import { CoreConfigConstants } from '../configconstants'; | import { CoreConfigConstants } from '../configconstants'; | ||||||
| import { Subject, Subscription } from 'rxjs'; | import { Subject, Subscription } from 'rxjs'; | ||||||
| @ -112,6 +113,7 @@ export class CoreLocalNotificationsProvider { | |||||||
|     protected cancelSubscription: Subscription; |     protected cancelSubscription: Subscription; | ||||||
|     protected addSubscription: Subscription; |     protected addSubscription: Subscription; | ||||||
|     protected updateSubscription: Subscription; |     protected updateSubscription: Subscription; | ||||||
|  |     protected queueRunner: CoreQueueRunner; // Queue to decrease the number of concurrent calls to the plugin (see MOBILE-3477).
 | ||||||
| 
 | 
 | ||||||
|     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, | ||||||
| @ -119,6 +121,7 @@ export class CoreLocalNotificationsProvider { | |||||||
|             eventsProvider: CoreEventsProvider, private push: Push, private zone: NgZone) { |             eventsProvider: CoreEventsProvider, private push: Push, private zone: NgZone) { | ||||||
| 
 | 
 | ||||||
|         this.logger = logger.getInstance('CoreLocalNotificationsProvider'); |         this.logger = logger.getInstance('CoreLocalNotificationsProvider'); | ||||||
|  |         this.queueRunner = new CoreQueueRunner(10); | ||||||
|         this.appDB = appProvider.getDB(); |         this.appDB = appProvider.getDB(); | ||||||
|         this.dbReady = appProvider.createTablesFromSchema(this.tablesSchema).catch(() => { |         this.dbReady = appProvider.createTablesFromSchema(this.tablesSchema).catch(() => { | ||||||
|             // Ignore errors.
 |             // Ignore errors.
 | ||||||
| @ -176,9 +179,13 @@ export class CoreLocalNotificationsProvider { | |||||||
|      * @param siteId Site ID. |      * @param siteId Site ID. | ||||||
|      * @return Promise resolved when the notification is cancelled. |      * @return Promise resolved when the notification is cancelled. | ||||||
|      */ |      */ | ||||||
|     cancel(id: number, component: string, siteId: string): Promise<any> { |     async cancel(id: number, component: string, siteId: string): Promise<void> { | ||||||
|         return this.getUniqueNotificationId(id, component, siteId).then((uniqueId) => { |         const uniqueId = await this.getUniqueNotificationId(id, component, siteId); | ||||||
|             return this.localNotifications.cancel(uniqueId); | 
 | ||||||
|  |         const queueId = 'cancel-' + uniqueId; | ||||||
|  | 
 | ||||||
|  |         await this.queueRunner.run(queueId, () => this.localNotifications.cancel(uniqueId), { | ||||||
|  |             allowRepeated: true, | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -188,28 +195,29 @@ export class CoreLocalNotificationsProvider { | |||||||
|      * @param siteId Site ID. |      * @param siteId Site ID. | ||||||
|      * @return Promise resolved when the notifications are cancelled. |      * @return Promise resolved when the notifications are cancelled. | ||||||
|      */ |      */ | ||||||
|     cancelSiteNotifications(siteId: string): Promise<any> { |     async cancelSiteNotifications(siteId: string): Promise<void> { | ||||||
| 
 | 
 | ||||||
|         if (!this.isAvailable()) { |         if (!this.isAvailable()) { | ||||||
|             return Promise.resolve(); |             return; | ||||||
|         } else if (!siteId) { |         } else if (!siteId) { | ||||||
|             return Promise.reject(null); |             throw new Error('No site ID supplied.'); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return this.localNotifications.getScheduled().then((scheduled) => { |         const scheduled = await this.getAllScheduled(); | ||||||
|  | 
 | ||||||
|         const ids = []; |         const ids = []; | ||||||
|  |         const queueId = 'cancelSiteNotifications-' + siteId; | ||||||
| 
 | 
 | ||||||
|         scheduled.forEach((notif) => { |         scheduled.forEach((notif) => { | ||||||
|                 if (typeof notif.data == 'string') { |             notif.data = this.parseNotificationData(notif.data); | ||||||
|                     notif.data = this.textUtils.parseJSON(notif.data); |  | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|             if (typeof notif.data == 'object' && notif.data.siteId === siteId) { |             if (typeof notif.data == 'object' && notif.data.siteId === siteId) { | ||||||
|                 ids.push(notif.id); |                 ids.push(notif.id); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|             return this.localNotifications.cancel(ids); |         await this.queueRunner.run(queueId, () => this.localNotifications.cancel(ids), { | ||||||
|  |             allowRepeated: true, | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -243,6 +251,15 @@ export class CoreLocalNotificationsProvider { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Get all scheduled notifications. | ||||||
|  |      * | ||||||
|  |      * @return Promise resolved with the notifications. | ||||||
|  |      */ | ||||||
|  |     protected getAllScheduled(): Promise<ILocalNotification[]> { | ||||||
|  |         return this.queueRunner.run('allScheduled', () => this.localNotifications.getScheduled()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Get a code to create unique notifications. If there's no code assigned, create a new one. |      * Get a code to create unique notifications. If there's no code assigned, create a new one. | ||||||
|      * |      * | ||||||
| @ -359,9 +376,10 @@ 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 notification Notification to check. |      * @param notification Notification to check. | ||||||
|  |      * @param useQueue Whether to add the call to the queue. | ||||||
|      * @return Promise resolved with a boolean indicating if promise is triggered (true) or not. |      * @return Promise resolved with a boolean indicating if promise is triggered (true) or not. | ||||||
|      */ |      */ | ||||||
|     async isTriggered(notification: ILocalNotification): Promise<boolean> { |     async isTriggered(notification: ILocalNotification, useQueue: boolean = true): Promise<boolean> { | ||||||
|         await this.dbReady; |         await this.dbReady; | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
| @ -374,9 +392,17 @@ export class CoreLocalNotificationsProvider { | |||||||
| 
 | 
 | ||||||
|             return stored.at === triggered; |             return stored.at === triggered; | ||||||
|         } catch (err) { |         } catch (err) { | ||||||
|  |             if (useQueue) { | ||||||
|  |                 const queueId = 'isTriggered-' + notification.id; | ||||||
|  | 
 | ||||||
|  |                 return this.queueRunner.run(queueId, () => this.localNotifications.isTriggered(notification.id), { | ||||||
|  |                     allowRepeated: true, | ||||||
|  |                 }); | ||||||
|  |             } else { | ||||||
|                 return this.localNotifications.isTriggered(notification.id); |                 return this.localNotifications.isTriggered(notification.id); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Notify notification click to observers. Only the observers with the same component as the notification will be notified. |      * Notify notification click to observers. Only the observers with the same component as the notification will be notified. | ||||||
| @ -405,6 +431,22 @@ export class CoreLocalNotificationsProvider { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Parse some notification data. | ||||||
|  |      * | ||||||
|  |      * @param data Notification data. | ||||||
|  |      * @return Parsed data. | ||||||
|  |      */ | ||||||
|  |     protected parseNotificationData(data: any): any { | ||||||
|  |         if (!data) { | ||||||
|  |             return {}; | ||||||
|  |         } else if (typeof data == 'string') { | ||||||
|  |             return this.textUtils.parseJSON(data, {}); | ||||||
|  |         } else { | ||||||
|  |             return data; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Process the next request in queue. |      * Process the next request in queue. | ||||||
|      */ |      */ | ||||||
| @ -531,20 +573,20 @@ export class CoreLocalNotificationsProvider { | |||||||
|      * |      * | ||||||
|      * @return Promise resolved when all notifications have been rescheduled. |      * @return Promise resolved when all notifications have been rescheduled. | ||||||
|      */ |      */ | ||||||
|     rescheduleAll(): Promise<any> { |     async rescheduleAll(): Promise<void> { | ||||||
|         // Get all the scheduled notifications.
 |         // Get all the scheduled notifications.
 | ||||||
|         return this.localNotifications.getScheduled().then((notifications) => { |         const notifications = await this.getAllScheduled(); | ||||||
|             const promises = []; |  | ||||||
| 
 | 
 | ||||||
|             notifications.forEach((notification) => { |         await Promise.all(notifications.map(async (notification) => { | ||||||
|             // Convert some properties to the needed types.
 |             // Convert some properties to the needed types.
 | ||||||
|                 notification.data = notification.data ? this.textUtils.parseJSON(notification.data, {}) : {}; |             notification.data = this.parseNotificationData(notification.data); | ||||||
| 
 | 
 | ||||||
|                 promises.push(this.scheduleNotification(notification)); |             const queueId = 'schedule-' + notification.id; | ||||||
|             }); |  | ||||||
| 
 | 
 | ||||||
|             return Promise.all(promises); |             await this.queueRunner.run(queueId, () => this.scheduleNotification(notification), { | ||||||
|  |                 allowRepeated: true, | ||||||
|             }); |             }); | ||||||
|  |         })); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -557,17 +599,12 @@ export class CoreLocalNotificationsProvider { | |||||||
|      * @param alreadyUnique Whether the ID is already unique. |      * @param alreadyUnique Whether the ID is already unique. | ||||||
|      * @return Promise resolved when the notification is scheduled. |      * @return Promise resolved when the notification is scheduled. | ||||||
|      */ |      */ | ||||||
|     schedule(notification: ILocalNotification, component: string, siteId: string, alreadyUnique?: boolean): Promise<any> { |     async schedule(notification: ILocalNotification, component: string, siteId: string, alreadyUnique?: boolean): Promise<void> { | ||||||
|         let promise; |  | ||||||
| 
 | 
 | ||||||
|         if (alreadyUnique) { |         if (!alreadyUnique) { | ||||||
|             promise = Promise.resolve(notification.id); |             notification.id = await this.getUniqueNotificationId(notification.id, component, siteId); | ||||||
|         } else { |  | ||||||
|             promise = this.getUniqueNotificationId(notification.id, component, siteId); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return promise.then((uniqueId) => { |  | ||||||
|             notification.id = uniqueId; |  | ||||||
|         notification.data = notification.data || {}; |         notification.data = notification.data || {}; | ||||||
|         notification.data.component = component; |         notification.data.component = component; | ||||||
|         notification.data.siteId = siteId; |         notification.data.siteId = siteId; | ||||||
| @ -585,7 +622,10 @@ export class CoreLocalNotificationsProvider { | |||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|             return this.scheduleNotification(notification); |         const queueId = 'schedule-' + notification.id; | ||||||
|  | 
 | ||||||
|  |         await this.queueRunner.run(queueId, () => this.scheduleNotification(notification), { | ||||||
|  |             allowRepeated: true, | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -595,9 +635,9 @@ export class CoreLocalNotificationsProvider { | |||||||
|      * @param notification Notification to schedule. |      * @param notification Notification to schedule. | ||||||
|      * @return Promise resolved when scheduled. |      * @return Promise resolved when scheduled. | ||||||
|      */ |      */ | ||||||
|     protected scheduleNotification(notification: ILocalNotification): Promise<any> { |     protected scheduleNotification(notification: ILocalNotification): Promise<void> { | ||||||
|         // 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, false).then((triggered) => { | ||||||
|             // Cancel the current notification in case it gets scheduled twice.
 |             // Cancel the current notification in case it gets scheduled twice.
 | ||||||
|             return this.localNotifications.cancel(notification.id).finally(() => { |             return this.localNotifications.cancel(notification.id).finally(() => { | ||||||
|                 if (!triggered) { |                 if (!triggered) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user