MOBILE-3936 core: Add LocalNotifications mock
parent
43cec87112
commit
12c19080f2
|
@ -15,8 +15,8 @@
|
||||||
iconAction="fas-th-list" (action)="toggleDisplay()"></core-context-menu-item>
|
iconAction="fas-th-list" (action)="toggleDisplay()"></core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="!showCalendar" [priority]="800" [content]="'addon.calendar.monthlyview' | translate"
|
<core-context-menu-item *ngIf="!showCalendar" [priority]="800" [content]="'addon.calendar.monthlyview' | translate"
|
||||||
iconAction="fas-calendar-alt" (action)="toggleDisplay()"></core-context-menu-item>
|
iconAction="fas-calendar-alt" (action)="toggleDisplay()"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600" [content]="'core.settings.settings' | translate"
|
<core-context-menu-item [priority]="600" [content]="'core.settings.settings' | translate" (action)="openSettings()"
|
||||||
(action)="openSettings()" iconAction="fas-cogs">
|
iconAction="fas-cogs">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
|
<core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
|
||||||
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
|
[content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
|
||||||
|
|
|
@ -31,7 +31,6 @@ import { AddonCalendarCalendarComponent } from '../../components/calendar/calend
|
||||||
import { AddonCalendarUpcomingEventsComponent } from '../../components/upcoming-events/upcoming-events';
|
import { AddonCalendarUpcomingEventsComponent } from '../../components/upcoming-events/upcoming-events';
|
||||||
import { AddonCalendarFilterComponent } from '../../components/filter/filter';
|
import { AddonCalendarFilterComponent } from '../../components/filter/filter';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreLocalNotifications } from '@services/local-notifications';
|
|
||||||
import { CoreConstants } from '@/core/constants';
|
import { CoreConstants } from '@/core/constants';
|
||||||
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-link-manager';
|
||||||
|
|
||||||
|
@ -64,7 +63,6 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
|
||||||
month?: number;
|
month?: number;
|
||||||
canCreate = false;
|
canCreate = false;
|
||||||
courses: Partial<CoreEnrolledCourseData>[] = [];
|
courses: Partial<CoreEnrolledCourseData>[] = [];
|
||||||
notificationsEnabled = false;
|
|
||||||
loaded = false;
|
loaded = false;
|
||||||
hasOffline = false;
|
hasOffline = false;
|
||||||
isOnline = false;
|
isOnline = false;
|
||||||
|
@ -165,8 +163,6 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
|
||||||
* View loaded.
|
* View loaded.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.notificationsEnabled = CoreLocalNotifications.isAvailable();
|
|
||||||
|
|
||||||
this.loadUpcoming = !!CoreNavigator.getRouteBooleanParam('upcoming');
|
this.loadUpcoming = !!CoreNavigator.getRouteBooleanParam('upcoming');
|
||||||
this.showCalendar = !this.loadUpcoming;
|
this.showCalendar = !this.loadUpcoming;
|
||||||
|
|
||||||
|
|
|
@ -1384,10 +1384,6 @@ export class AddonCalendarProvider {
|
||||||
async updateAllSitesEventReminders(): Promise<void> {
|
async updateAllSitesEventReminders(): Promise<void> {
|
||||||
await CorePlatform.ready();
|
await CorePlatform.ready();
|
||||||
|
|
||||||
if (!CoreLocalNotifications.isAvailable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const siteIds = await CoreSites.getSitesIds();
|
const siteIds = await CoreSites.getSitesIds();
|
||||||
|
|
||||||
await Promise.all(siteIds.map((siteId: string) => async () => {
|
await Promise.all(siteIds.map((siteId: string) => async () => {
|
||||||
|
@ -1430,11 +1426,6 @@ export class AddonCalendarProvider {
|
||||||
events: ({ id: number; timestart: number; name: string})[],
|
events: ({ id: number; timestart: number; name: string})[],
|
||||||
siteId: string,
|
siteId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
|
||||||
if (!CoreLocalNotifications.isAvailable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(events.map(async (event) => {
|
await Promise.all(events.map(async (event) => {
|
||||||
if (event.timestart * 1000 <= Date.now()) {
|
if (event.timestart * 1000 <= Date.now()) {
|
||||||
// The event has already started, don't schedule it.
|
// The event has already started, don't schedule it.
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { FileOpener } from '@ionic-native/file-opener/ngx';
|
||||||
import { FileTransfer } from '@ionic-native/file-transfer/ngx';
|
import { FileTransfer } from '@ionic-native/file-transfer/ngx';
|
||||||
import { Geolocation } from '@ionic-native/geolocation/ngx';
|
import { Geolocation } from '@ionic-native/geolocation/ngx';
|
||||||
import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';
|
import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';
|
||||||
|
import { LocalNotifications } from '@ionic-native/local-notifications/ngx';
|
||||||
import { MediaCapture } from '@ionic-native/media-capture/ngx';
|
import { MediaCapture } from '@ionic-native/media-capture/ngx';
|
||||||
import { Zip } from '@ionic-native/zip/ngx';
|
import { Zip } from '@ionic-native/zip/ngx';
|
||||||
|
|
||||||
|
@ -36,9 +37,11 @@ import { FileOpenerMock } from './services/file-opener';
|
||||||
import { FileTransferMock } from './services/file-transfer';
|
import { FileTransferMock } from './services/file-transfer';
|
||||||
import { GeolocationMock } from './services/geolocation';
|
import { GeolocationMock } from './services/geolocation';
|
||||||
import { InAppBrowserMock } from './services/inappbrowser';
|
import { InAppBrowserMock } from './services/inappbrowser';
|
||||||
|
import { LocalNotificationsMock } from './services/local-notifications';
|
||||||
import { MediaCaptureMock } from './services/media-capture';
|
import { MediaCaptureMock } from './services/media-capture';
|
||||||
import { ZipMock } from './services/zip';
|
import { ZipMock } from './services/zip';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
|
import { CoreLocalNotifications } from '@services/local-notifications';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This module handles the emulation of Cordova plugins in browser and desktop.
|
* This module handles the emulation of Cordova plugins in browser and desktop.
|
||||||
|
@ -90,6 +93,12 @@ import { CorePlatform } from '@services/platform';
|
||||||
provide: Zip,
|
provide: Zip,
|
||||||
useFactory: (): Zip => CorePlatform.is('cordova') ? new Zip() : new ZipMock(),
|
useFactory: (): Zip => CorePlatform.is('cordova') ? new Zip() : new ZipMock(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: LocalNotifications,
|
||||||
|
useFactory: (): LocalNotifications => CoreLocalNotifications.isPluginAvailable()
|
||||||
|
? new LocalNotifications()
|
||||||
|
: new LocalNotificationsMock(),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: () => () => {
|
useFactory: () => () => {
|
||||||
|
|
|
@ -0,0 +1,407 @@
|
||||||
|
// (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 { CoreError } from '@classes/errors/error';
|
||||||
|
import { ILocalNotification, ILocalNotificationAction, LocalNotifications } from '@ionic-native/local-notifications/ngx';
|
||||||
|
import { Observable, Subject } from 'rxjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock LocalNotifications service.
|
||||||
|
*/
|
||||||
|
export class LocalNotificationsMock extends LocalNotifications {
|
||||||
|
|
||||||
|
protected scheduledNotifications: ILocalNotification[] = [];
|
||||||
|
protected triggeredNotifications: ILocalNotification[] = [];
|
||||||
|
protected presentNotifications: Record<number, Notification> = {};
|
||||||
|
protected nextTimeout = 0;
|
||||||
|
protected hasGranted?: boolean;
|
||||||
|
protected observables = {
|
||||||
|
trigger: new Subject<ILocalNotification>(),
|
||||||
|
click: new Subject<ILocalNotification>(),
|
||||||
|
clear: new Subject<Notification>(),
|
||||||
|
clearall: new Subject<void>(),
|
||||||
|
cancel: new Subject<ILocalNotification>(),
|
||||||
|
cancelall: new Subject<void>(),
|
||||||
|
schedule: new Subject<ILocalNotification>(),
|
||||||
|
update: new Subject<ILocalNotification>(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
schedule(options?: ILocalNotification | Array<ILocalNotification>): void {
|
||||||
|
this.hasPermission().then(() => {
|
||||||
|
// Do not check permission here, it could be denied by Selenium.
|
||||||
|
if (!options) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(options)) {
|
||||||
|
options = [options];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scheduledNotifications = this.scheduledNotifications.concat(options);
|
||||||
|
this.scheduledNotifications.sort((a, b) =>
|
||||||
|
(a.trigger?.at?.getTime() || 0) - (b.trigger?.at?.getTime() || 0));
|
||||||
|
|
||||||
|
options.forEach((notification) => {
|
||||||
|
this.observables.schedule.next(notification);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scheduleNotifications();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets timeout for next nofitication.
|
||||||
|
*/
|
||||||
|
protected scheduleNotifications(): void {
|
||||||
|
window.clearTimeout(this.nextTimeout);
|
||||||
|
|
||||||
|
const nextNotification = this.scheduledNotifications[0];
|
||||||
|
if (!nextNotification) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const notificationTime = nextNotification.trigger?.at?.getTime() || 0;
|
||||||
|
const timeout = notificationTime - Date.now();
|
||||||
|
if (timeout <= 0) {
|
||||||
|
this.triggerNextNotification();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.nextTimeout = window.setTimeout(() => {
|
||||||
|
this.triggerNextNotification();
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the next notification.
|
||||||
|
*/
|
||||||
|
protected triggerNextNotification(): void {
|
||||||
|
const dateNow = Date.now();
|
||||||
|
|
||||||
|
const nextNotification = this.scheduledNotifications[0];
|
||||||
|
if (!nextNotification) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const notificationTime = nextNotification.trigger?.at?.getTime() || 0;
|
||||||
|
if (notificationTime === 0 || notificationTime <= dateNow) {
|
||||||
|
const body = Array.isArray(nextNotification.text) ? nextNotification.text.join() : nextNotification.text;
|
||||||
|
const notification = new Notification(nextNotification.title || '', {
|
||||||
|
body,
|
||||||
|
data: nextNotification.data,
|
||||||
|
icon: nextNotification.icon,
|
||||||
|
requireInteraction: true,
|
||||||
|
tag: nextNotification.data?.component,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.triggeredNotifications.push(nextNotification);
|
||||||
|
|
||||||
|
this.observables.trigger.next(nextNotification);
|
||||||
|
|
||||||
|
notification.addEventListener('click', () => {
|
||||||
|
this.observables.click.next(nextNotification);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nextNotification.id) {
|
||||||
|
this.presentNotifications[nextNotification.id] = notification;
|
||||||
|
|
||||||
|
notification.addEventListener('close', () => {
|
||||||
|
delete(this.presentNotifications[nextNotification.id ?? 0]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scheduledNotifications.shift();
|
||||||
|
this.triggerNextNotification();
|
||||||
|
} else {
|
||||||
|
this.scheduleNotifications();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
update(options?: ILocalNotification): void {
|
||||||
|
if (!options?.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const index = this.scheduledNotifications.findIndex((notification) => notification.id === options.id);
|
||||||
|
if (index < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.observables.update.next(options);
|
||||||
|
|
||||||
|
this.scheduledNotifications[index] = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async clear(notificationId: number | Array<number>): Promise<void> {
|
||||||
|
if (!Array.isArray(notificationId)) {
|
||||||
|
notificationId = [notificationId];
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationId.forEach((id) => {
|
||||||
|
if (!this.presentNotifications[id]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.presentNotifications[id].close();
|
||||||
|
|
||||||
|
this.observables.clear.next(this.presentNotifications[id]);
|
||||||
|
delete this.presentNotifications[id];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async clearAll(): Promise<void> {
|
||||||
|
for (const x in this.presentNotifications) {
|
||||||
|
this.presentNotifications[x].close();
|
||||||
|
}
|
||||||
|
this.presentNotifications = {};
|
||||||
|
|
||||||
|
this.observables.clearall.next();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async cancel(notificationId: number | Array<number>): Promise<void> {
|
||||||
|
if (!Array.isArray(notificationId)) {
|
||||||
|
notificationId = [notificationId];
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationId.forEach((id) => {
|
||||||
|
const index = this.scheduledNotifications.findIndex((notification) => notification.id === id);
|
||||||
|
this.observables.cancel.next(this.scheduledNotifications[index]);
|
||||||
|
|
||||||
|
this.scheduledNotifications.splice(index, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scheduleNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async cancelAll(): Promise<void> {
|
||||||
|
window.clearTimeout(this.nextTimeout);
|
||||||
|
this.scheduledNotifications = [];
|
||||||
|
|
||||||
|
this.observables.cancelall.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async isPresent(notificationId: number): Promise<boolean> {
|
||||||
|
return !!this.presentNotifications[notificationId];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async isScheduled(notificationId: number): Promise<boolean> {
|
||||||
|
return this.scheduledNotifications.some((notification) => notification.id === notificationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async isTriggered(notificationId: number): Promise<boolean> {
|
||||||
|
return this.triggeredNotifications.some((notification) => notification.id === notificationId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getIds(): Promise<Array<number>> {
|
||||||
|
const ids = await this.getScheduledIds();
|
||||||
|
const triggeredIds = await this.getTriggeredIds();
|
||||||
|
|
||||||
|
return Promise.resolve(ids.concat(triggeredIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getTriggeredIds(): Promise<Array<number>> {
|
||||||
|
const ids = this.triggeredNotifications
|
||||||
|
.map((notification) => notification.id || 0)
|
||||||
|
.filter((id) => id > 0);
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getScheduledIds(): Promise<Array<number>> {
|
||||||
|
const ids = this.scheduledNotifications
|
||||||
|
.map((notification) => notification.id || 0)
|
||||||
|
.filter((id) => id > 0);
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async get(notificationId: number): Promise<ILocalNotification> {
|
||||||
|
const notification = this.scheduledNotifications
|
||||||
|
.find((notification) => notification.id === notificationId);
|
||||||
|
|
||||||
|
if (!notification) {
|
||||||
|
throw new Error('Invalid Notification Id.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getAll(): Promise<Array<ILocalNotification>> {
|
||||||
|
return this.scheduledNotifications.concat(this.triggeredNotifications);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getAllScheduled(): Promise<Array<ILocalNotification>> {
|
||||||
|
return this.scheduledNotifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getAllTriggered(): Promise<Array<ILocalNotification>> {
|
||||||
|
return this.triggeredNotifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async registerPermission(): Promise<boolean> {
|
||||||
|
// We need to ask the user for permission
|
||||||
|
const permission = await Notification.requestPermission();
|
||||||
|
|
||||||
|
this.hasGranted = permission === 'granted';
|
||||||
|
|
||||||
|
// If the user accepts, let's create a notification
|
||||||
|
return this.hasGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async hasPermission(): Promise<boolean> {
|
||||||
|
if (this.hasGranted !== undefined) {
|
||||||
|
return this.hasGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!('Notification' in window)) {
|
||||||
|
// Check if the browser supports notifications
|
||||||
|
throw new CoreError('This browser does not support desktop notification');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.registerPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async addActions(groupId: unknown, actions: Array<ILocalNotificationAction>): Promise<Array<ILocalNotificationAction>> {
|
||||||
|
// Not implemented.
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async removeActions(groupId: unknown): Promise<unknown> {
|
||||||
|
// Not implemented.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async hasActions(groupId: unknown): Promise<boolean> {
|
||||||
|
// Not implemented.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async getDefaults(): Promise<unknown> {
|
||||||
|
// Not implemented.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async setDefaults(defaults: unknown): Promise<unknown> {
|
||||||
|
// Not implemented.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
on(eventName: string): Observable<unknown> {
|
||||||
|
if (!this.observables[eventName]) {
|
||||||
|
this.observables[eventName] = new Subject<ILocalNotification>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.observables[eventName];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
fireEvent(eventName: string, args: unknown): void {
|
||||||
|
if (!this.observables[eventName]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.observables[eventName].next(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
async fireQueuedEvents(): Promise<unknown> {
|
||||||
|
return this.triggerNextNotification();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -473,11 +473,6 @@ export class CorePushNotificationsProvider {
|
||||||
return this.notificationClicked(data);
|
return this.notificationClicked(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the app is in foreground when the notification is received, it's not shown. Let's show it ourselves.
|
|
||||||
if (!CoreLocalNotifications.isAvailable()) {
|
|
||||||
return this.notifyReceived(notification, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
const localNotif: ILocalNotification = {
|
const localNotif: ILocalNotification = {
|
||||||
id: Number(data.notId) || 1,
|
id: Number(data.notId) || 1,
|
||||||
data: data,
|
data: data,
|
||||||
|
|
|
@ -67,7 +67,7 @@ export class CoreRemindersService {
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
async initialize(): Promise<void> {
|
async initialize(): Promise<void> {
|
||||||
if (!CoreLocalNotifications.isAvailable()) {
|
if (!this.isEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ export class CoreRemindersService {
|
||||||
* @return True if reminders are enabled and available, false otherwise.
|
* @return True if reminders are enabled and available, false otherwise.
|
||||||
*/
|
*/
|
||||||
isEnabled(): boolean {
|
isEnabled(): boolean {
|
||||||
return CoreLocalNotifications.isAvailable();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -314,7 +314,8 @@ export class CoreRemindersService {
|
||||||
async scheduleAllNotifications(): Promise<void> {
|
async scheduleAllNotifications(): Promise<void> {
|
||||||
await CorePlatform.ready();
|
await CorePlatform.ready();
|
||||||
|
|
||||||
if (!this.isEnabled()) {
|
if (CoreLocalNotifications.isPluginAvailable()) {
|
||||||
|
// Notifications are already scheduled.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ export class CoreSettingsDeviceInfoPage implements OnDestroy {
|
||||||
lastCommit: CoreConstants.BUILD.lastCommitHash || '',
|
lastCommit: CoreConstants.BUILD.lastCommitHash || '',
|
||||||
networkStatus: CoreNetwork.isOnline() ? 'online' : 'offline',
|
networkStatus: CoreNetwork.isOnline() ? 'online' : 'offline',
|
||||||
wifiConnection: CoreNetwork.isWifi() ? 'yes' : 'no',
|
wifiConnection: CoreNetwork.isWifi() ? 'yes' : 'no',
|
||||||
localNotifAvailable: CoreLocalNotifications.isAvailable() ? 'yes' : 'no',
|
localNotifAvailable: CoreLocalNotifications.isPluginAvailable() ? 'yes' : 'no',
|
||||||
pushId: CorePushNotifications.getPushId(),
|
pushId: CorePushNotifications.getPushId(),
|
||||||
deviceType: '',
|
deviceType: '',
|
||||||
};
|
};
|
||||||
|
|
|
@ -319,14 +319,26 @@ export class CoreLocalNotificationsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether local notifications plugin is installed.
|
* Returns whether local notifications are available.
|
||||||
*
|
*
|
||||||
* @return Whether local notifications plugin is installed.
|
* @return Whether local notifications are available.
|
||||||
|
* @deprecated since 4.1. It will always return true.
|
||||||
*/
|
*/
|
||||||
isAvailable(): boolean {
|
isAvailable(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether local notifications plugin is available.
|
||||||
|
*
|
||||||
|
* @return Whether local notifications plugin is available.
|
||||||
|
*/
|
||||||
|
isPluginAvailable(): boolean {
|
||||||
const win = <any> window; // eslint-disable-line @typescript-eslint/no-explicit-any
|
const win = <any> window; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
|
||||||
return !!win.cordova?.plugins?.notification?.local;
|
const enabled = !!win.cordova?.plugins?.notification?.local;
|
||||||
|
|
||||||
|
return enabled && CorePlatform.is('cordova');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue