Merge pull request #4693 from tsiegleauq/no-notification-on-projector

Enhance update service
This commit is contained in:
Emanuel Schütze 2019-05-15 14:58:59 +02:00 committed by GitHub
commit 183f671fee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 24 deletions

View File

@ -23,7 +23,11 @@ const routes: Routes = [
{ path: 'privacypolicy', component: LoginPrivacyPolicyComponent }
]
},
{ path: 'projector', loadChildren: './fullscreen-projector/fullscreen-projector.module#FullscreenProjectorModule' },
{
path: 'projector',
loadChildren: './fullscreen-projector/fullscreen-projector.module#FullscreenProjectorModule',
data: { noInterruption: true }
},
{ path: '', loadChildren: './site/site.module#SiteModule' },
{ path: '**', redirectTo: '' }
];

View File

@ -12,7 +12,6 @@ import { OperatorService } from './core/core-services/operator.service';
import { ServertimeService } from './core/core-services/servertime.service';
import { ThemeService } from './core/ui-services/theme.service';
import { DataStoreUpgradeService } from './core/core-services/data-store-upgrade.service';
import { UpdateService } from './core/ui-services/update.service';
import { PrioritizeService } from './core/core-services/prioritize.service';
import { PingService } from './core/core-services/ping.service';
import { SpinnerService } from './core/ui-services/spinner.service';
@ -44,7 +43,6 @@ export class AppComponent {
* @param configService to call the constructor of the ConfigService
* @param loadFontService to call the constructor of the LoadFontService
* @param dataStoreUpgradeService
* @param update Service Worker Updates
*/
public constructor(
translate: TranslateService,
@ -60,7 +58,6 @@ export class AppComponent {
configService: ConfigService,
loadFontService: LoadFontService,
dataStoreUpgradeService: DataStoreUpgradeService, // to start it.
update: UpdateService,
prioritizeService: PrioritizeService,
pingService: PingService
) {

View File

@ -1,8 +1,8 @@
import { Injectable } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';
import { MatSnackBar } from '@angular/material';
import { SwUpdate, UpdateAvailableEvent } from '@angular/service-worker';
import { NotifyService } from '../core-services/notify.service';
import { Observable } from 'rxjs';
/**
* Handle Service Worker updates using the SwUpdate service form angular.
@ -13,6 +13,13 @@ import { NotifyService } from '../core-services/notify.service';
export class UpdateService {
private static NOTIFY_NAME = 'swCheckForUpdate';
/**
* @returns the updateSubscription
*/
public get updateObservable(): Observable<UpdateAvailableEvent> {
return this.swUpdate.available;
}
/**
* Constructor.
* Listens to available updates
@ -20,27 +27,22 @@ export class UpdateService {
* @param swUpdate Service Worker update service
* @param matSnackBar Currently to show that an update is available
*/
public constructor(private swUpdate: SwUpdate, matSnackBar: MatSnackBar, private notify: NotifyService) {
swUpdate.available.subscribe(() => {
// TODO: Find a better solution OR make an update-bar like for history mode
const ref = matSnackBar.open('A new update is available!', 'Refresh', {
duration: 0
});
// Enforces an update
ref.onAction().subscribe(() => {
this.swUpdate.activateUpdate().then(() => {
document.location.reload();
});
});
});
public constructor(private swUpdate: SwUpdate, private notify: NotifyService) {
// Listen on requests from other users to check for updates.
this.notify.getMessageObservable(UpdateService.NOTIFY_NAME).subscribe(() => {
this.checkForUpdate();
});
}
/**
* Manually applies the update if one was found
*/
public applyUpdate(): void {
this.swUpdate.activateUpdate().then(() => {
document.location.reload();
});
}
/**
* Trigger that to manually check for updates
*/

View File

@ -7,6 +7,7 @@
<mat-card class="os-card">
<div class="app-content" translate>
<h1>{{ welcomeTitle | translate }}</h1>
<div [innerHTML]="welcomeText | translate"></div>
</div>
</mat-card>

View File

@ -1,7 +1,7 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { Router, NavigationEnd, ActivationEnd } from '@angular/router';
import { FormGroup, FormControl } from '@angular/forms';
import { MatDialog, MatSidenav } from '@angular/material';
import { MatDialog, MatSidenav, MatSnackBar } from '@angular/material';
import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core';
@ -16,6 +16,16 @@ import { OpenSlidesStatusService } from '../core/core-services/openslides-status
import { TimeTravelService } from '../core/core-services/time-travel.service';
import { langToLocale } from 'app/shared/utils/lang-to-locale';
import { ConfigService } from 'app/core/ui-services/config.service';
import { UpdateService } from 'app/core/ui-services/update.service';
import { filter } from 'rxjs/operators';
/**
* Interface to describe possible routing data
*/
interface RoutingData {
basePerm?: string;
noInterruption?: boolean;
}
@Component({
selector: 'os-site',
@ -45,6 +55,16 @@ export class SiteComponent extends BaseComponent implements OnInit {
*/
public searchform: FormGroup;
/**
* Hold the current routing data to make certain checks
*/
private routingData: RoutingData;
/**
* Set to true if an update was suppressed
*/
private delayedUpdateAvailable = false;
/**
* Constructor
*
@ -62,6 +82,7 @@ export class SiteComponent extends BaseComponent implements OnInit {
title: Title,
translate: TranslateService,
configService: ConfigService,
private updateService: UpdateService,
private authService: AuthService,
private router: Router,
public operator: OperatorService,
@ -69,7 +90,8 @@ export class SiteComponent extends BaseComponent implements OnInit {
public dialog: MatDialog,
public mainMenuService: MainMenuService,
public OSStatus: OpenSlidesStatusService,
public timeTravel: TimeTravelService
public timeTravel: TimeTravelService,
private matSnackBar: MatSnackBar
) {
super(title, translate);
@ -83,6 +105,18 @@ export class SiteComponent extends BaseComponent implements OnInit {
});
this.searchform = new FormGroup({ query: new FormControl([]) });
// detect routing data such as base perm and noInterruption
this.router.events
.pipe(filter(event => event instanceof ActivationEnd && event.snapshot.children.length === 0))
.subscribe((event: ActivationEnd) => {
this.routingData = event.snapshot.data as RoutingData;
// if the current route has no "noInterruption" flag and an update is available, show the update
if (this.delayedUpdateAvailable && !this.routingData.noInterruption) {
this.showUpdateNotification();
}
});
}
/**
@ -125,6 +159,29 @@ export class SiteComponent extends BaseComponent implements OnInit {
}
}
});
// check for updates
this.updateService.updateObservable.subscribe(() => {
if (this.routingData.noInterruption) {
this.delayedUpdateAvailable = true;
} else {
this.showUpdateNotification();
}
});
}
/**
* Shows the update notification
*/
private showUpdateNotification(): void {
const ref = this.matSnackBar.open('A new update is available!', 'Refresh', {
duration: 0
});
// Enforces an update
ref.onAction().subscribe(() => {
this.updateService.applyUpdate();
});
}
/**