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: '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: '', loadChildren: './site/site.module#SiteModule' },
{ path: '**', redirectTo: '' } { 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 { ServertimeService } from './core/core-services/servertime.service';
import { ThemeService } from './core/ui-services/theme.service'; import { ThemeService } from './core/ui-services/theme.service';
import { DataStoreUpgradeService } from './core/core-services/data-store-upgrade.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 { PrioritizeService } from './core/core-services/prioritize.service';
import { PingService } from './core/core-services/ping.service'; import { PingService } from './core/core-services/ping.service';
import { SpinnerService } from './core/ui-services/spinner.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 configService to call the constructor of the ConfigService
* @param loadFontService to call the constructor of the LoadFontService * @param loadFontService to call the constructor of the LoadFontService
* @param dataStoreUpgradeService * @param dataStoreUpgradeService
* @param update Service Worker Updates
*/ */
public constructor( public constructor(
translate: TranslateService, translate: TranslateService,
@ -60,7 +58,6 @@ export class AppComponent {
configService: ConfigService, configService: ConfigService,
loadFontService: LoadFontService, loadFontService: LoadFontService,
dataStoreUpgradeService: DataStoreUpgradeService, // to start it. dataStoreUpgradeService: DataStoreUpgradeService, // to start it.
update: UpdateService,
prioritizeService: PrioritizeService, prioritizeService: PrioritizeService,
pingService: PingService pingService: PingService
) { ) {

View File

@ -1,8 +1,8 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { SwUpdate } from '@angular/service-worker'; import { SwUpdate, UpdateAvailableEvent } from '@angular/service-worker';
import { MatSnackBar } from '@angular/material';
import { NotifyService } from '../core-services/notify.service'; import { NotifyService } from '../core-services/notify.service';
import { Observable } from 'rxjs';
/** /**
* Handle Service Worker updates using the SwUpdate service form angular. * Handle Service Worker updates using the SwUpdate service form angular.
@ -13,6 +13,13 @@ import { NotifyService } from '../core-services/notify.service';
export class UpdateService { export class UpdateService {
private static NOTIFY_NAME = 'swCheckForUpdate'; private static NOTIFY_NAME = 'swCheckForUpdate';
/**
* @returns the updateSubscription
*/
public get updateObservable(): Observable<UpdateAvailableEvent> {
return this.swUpdate.available;
}
/** /**
* Constructor. * Constructor.
* Listens to available updates * Listens to available updates
@ -20,27 +27,22 @@ export class UpdateService {
* @param swUpdate Service Worker update service * @param swUpdate Service Worker update service
* @param matSnackBar Currently to show that an update is available * @param matSnackBar Currently to show that an update is available
*/ */
public constructor(private swUpdate: SwUpdate, matSnackBar: MatSnackBar, private notify: NotifyService) { public constructor(private swUpdate: SwUpdate, 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();
});
});
});
// Listen on requests from other users to check for updates. // Listen on requests from other users to check for updates.
this.notify.getMessageObservable(UpdateService.NOTIFY_NAME).subscribe(() => { this.notify.getMessageObservable(UpdateService.NOTIFY_NAME).subscribe(() => {
this.checkForUpdate(); 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 * Trigger that to manually check for updates
*/ */

View File

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

View File

@ -1,7 +1,7 @@
import { Component, OnInit, ViewChild } from '@angular/core'; 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 { 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 { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; 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 { TimeTravelService } from '../core/core-services/time-travel.service';
import { langToLocale } from 'app/shared/utils/lang-to-locale'; import { langToLocale } from 'app/shared/utils/lang-to-locale';
import { ConfigService } from 'app/core/ui-services/config.service'; 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({ @Component({
selector: 'os-site', selector: 'os-site',
@ -45,6 +55,16 @@ export class SiteComponent extends BaseComponent implements OnInit {
*/ */
public searchform: FormGroup; 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 * Constructor
* *
@ -62,6 +82,7 @@ export class SiteComponent extends BaseComponent implements OnInit {
title: Title, title: Title,
translate: TranslateService, translate: TranslateService,
configService: ConfigService, configService: ConfigService,
private updateService: UpdateService,
private authService: AuthService, private authService: AuthService,
private router: Router, private router: Router,
public operator: OperatorService, public operator: OperatorService,
@ -69,7 +90,8 @@ export class SiteComponent extends BaseComponent implements OnInit {
public dialog: MatDialog, public dialog: MatDialog,
public mainMenuService: MainMenuService, public mainMenuService: MainMenuService,
public OSStatus: OpenSlidesStatusService, public OSStatus: OpenSlidesStatusService,
public timeTravel: TimeTravelService public timeTravel: TimeTravelService,
private matSnackBar: MatSnackBar
) { ) {
super(title, translate); super(title, translate);
@ -83,6 +105,18 @@ export class SiteComponent extends BaseComponent implements OnInit {
}); });
this.searchform = new FormGroup({ query: new FormControl([]) }); 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();
});
} }
/** /**