|  | /** | 
|  | * @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'; | 
|  | } | 
|  | } |