blob: 0eec23aff805107c51cc7ca6a7419af501407697 [file] [log] [blame]
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {FlagsService, KnownExperimentId} from './flags/flags';
import {
areNotificationsEnabled,
registerServiceWorker,
} from '../utils/worker-util';
import {UserModel} from '../models/user/user-model';
import {AccountDetailInfo} from '../api/rest-api';
import {until} from '../utils/async-util';
/** Type of incoming messages for ServiceWorker. */
export enum ServiceWorkerMessageType {
TRIGGER_NOTIFICATIONS = 'TRIGGER_NOTIFICATIONS',
}
export const TRIGGER_NOTIFICATION_UPDATES_MS = 5 * 60 * 1000;
export class ServiceWorkerInstaller {
initialized = false;
account?: AccountDetailInfo;
constructor(
private readonly flagsService: FlagsService,
private readonly userModel: UserModel
) {
this.userModel.account$.subscribe(acc => (this.account = acc));
}
async init() {
if (this.initialized) return;
if (
!this.flagsService.isEnabled(
KnownExperimentId.PUSH_NOTIFICATIONS_DEVELOPER
)
) {
if (!this.flagsService.isEnabled(KnownExperimentId.PUSH_NOTIFICATIONS)) {
return;
}
const timeout1s = new Promise(resolve => {
setTimeout(resolve, 1000);
});
// We wait for account to be defined, if its not defined in 1s, it's guest
await Promise.race([
timeout1s,
until(this.userModel.account$, account => !!account),
]);
if (!areNotificationsEnabled(this.account)) return;
}
if (!('serviceWorker' in navigator)) {
console.error('Service worker API not available');
return;
}
await registerServiceWorker('/service-worker.js');
const permission = await Notification.requestPermission();
if (this.isPermitted(permission)) this.startTriggerTimer();
this.initialized = true;
}
/**
* Every 5 minutes, we trigger service-worker to get
* latest updates in attention set and service-worker will create
* notifications.
*/
startTriggerTimer() {
setTimeout(() => {
this.startTriggerTimer();
navigator.serviceWorker.controller?.postMessage({
type: ServiceWorkerMessageType.TRIGGER_NOTIFICATIONS,
account: this.account,
});
}, TRIGGER_NOTIFICATION_UPDATES_MS);
}
isPermitted(permission: NotificationPermission) {
return permission === 'granted';
}
}