import { ApplicationRef , Inject , Injectable } from "@angular/core" ; import { SwUpdate } from "@angular/service-worker" ; import { first } from "rxjs/operators" ; import { concat , interval } from "rxjs" ; import { MatSnackBar } from "@angular/material/snack-bar" ; import { LoggingService } from "../logging/logging.service" ; import { LatestChangesDialogService } from "./latest-changes-dialog.service" ; import { LOCATION_TOKEN } from "./latest-changes.module" ; /**
 * Check with the server whether a new version of the app is available in order to notify the user.
 *
 * As we are using ServiceWorkers to cache the app to also work offline, explicit checking for updates is necessary.
 * The user receives a toast (hover message) if an update is available
 * and can click that to reload the app with the new version.
 */ @ Injectable ( ) export class UpdateManagerService { private notificationRef ; constructor ( private appRef , private updates , private snackBar , private logger , @ Inject ( LOCATION_TOKEN ) private location ) { const currentVersion = window . localStorage . getItem ( LatestChangesDialogService . VERSION_KEY ) ; if ( currentVersion && currentVersion . startsWith ( "update-" ) ) { window . localStorage . setItem ( LatestChangesDialogService . VERSION_KEY , currentVersion . replace ( "update-" , "" ) ) ; this . location . reload ( ) ; } } /**
     * Display a notification to the user in case a new app version is detected by the ServiceWorker.
     */ public notifyUserWhenUpdateAvailable ( ) { if ( ! this . updates . isEnabled ) { return ; } this . updates . available . subscribe ( ( ) => { this . showUpdateNotification ( ) ; } ) ; } /**
     * Schedule a regular check with the server for updates.
     */ public regularlyCheckForUpdates ( ) { if ( ! this . updates . isEnabled ) { return ; } const appIsStable$ = this . appRef . isStable . pipe ( first ( ( isStable ) => isStable === true ) ) ; const everyHours$ = interval ( 60 * 60 * 1000 ) ; const everyHoursOnceAppIsStable$ = concat ( appIsStable$ , everyHours$ ) ; everyHoursOnceAppIsStable$ . subscribe ( async ( ) => { try { await this . updates . checkForUpdate ( ) ; } catch ( err ) { this . logger . error ( err ) ; } } ) ; } private showUpdateNotification ( ) { const currentVersion = window . localStorage . getItem ( LatestChangesDialogService . VERSION_KEY ) ; window . localStorage . setItem ( LatestChangesDialogService . VERSION_KEY , "update-" + currentVersion ) ; this . notificationRef = this . snackBar . open ( $localize `A new version of the app is available!` , $localize `:Action that a user can update the app with:Update` ) ; this . notificationRef . onAction ( ) . subscribe ( ( ) => { window . localStorage . setItem ( LatestChangesDialogService . VERSION_KEY , currentVersion ) ; this . location . reload ( ) ; } ) ; } }