feat(aio): allow reloading page from ServiceWorker update notification

This commit is contained in:
Georgios Kalpakas 2017-04-01 02:21:11 +03:00 committed by Pete Bacon Darwin
parent b1a3c47766
commit 2535769a65
4 changed files with 44 additions and 4 deletions

View File

@ -0,0 +1,5 @@
import { InjectionToken } from '@angular/core';
export const Global = new InjectionToken<Window>('global');
export const globalProvider = { provide: Global, useValue: window };

View File

@ -5,6 +5,7 @@ import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { MockSwUpdatesService } from 'testing/sw-updates.service';
import { Global } from './global.value';
import { SwUpdateNotificationsService } from './sw-update-notifications.service';
import { SwUpdatesService } from './sw-updates.service';
@ -26,6 +27,7 @@ describe('SwUpdateNotificationsService', () => {
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
{ provide: Global, useClass: MockGlobal },
{ provide: MdSnackBar, useClass: MockMdSnackBar },
{ provide: SwUpdatesService, useClass: MockSwUpdatesService },
SwUpdateNotificationsService
@ -87,10 +89,22 @@ describe('SwUpdateNotificationsService', () => {
activateUpdate(true);
expect(snackBar.$$lastRef.$$message).toContain('Update activated successfully');
expect(snackBar.$$lastRef.$$action).toBeNull();
expect(snackBar.$$lastRef.$$action).toBe('Reload');
expect(snackBar.$$lastRef.$$config.duration).toBeUndefined();
}));
it('should reload the page when clicking on `Reload` (after a successful activation)',
fakeAsync(() => {
const global = injector.get(Global);
activateUpdate(true);
expect(global.location.reload).not.toHaveBeenCalled();
snackBar.$$lastRef.$$onActionSubj.next();
expect(global.location.reload).toHaveBeenCalled();
})
);
it('should report a failed activation', fakeAsync(() => {
activateUpdate(false);
@ -158,6 +172,12 @@ describe('SwUpdateNotificationsService', () => {
});
// Mocks
class MockGlobal {
location = {
reload: jasmine.createSpy('MockGlobal.reload')
};
}
class MockMdSnackBarRef {
$$afterDismissedSubj = new Subject();
$$onActionSubj = new Subject();

View File

@ -1,8 +1,9 @@
import { Injectable } from '@angular/core';
import { Inject, Injectable } from '@angular/core';
import { MdSnackBar, MdSnackBarConfig, MdSnackBarRef } from '@angular/material';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/filter';
import { Global } from './global.value';
import { SwUpdatesService } from './sw-updates.service';
@ -29,7 +30,9 @@ export class SwUpdateNotificationsService {
private snackBars: MdSnackBarRef<any>[] = [];
private enabled = false;
constructor(private snackBarService: MdSnackBar, private swUpdates: SwUpdatesService) {
constructor(@Inject(Global) private global: any,
private snackBarService: MdSnackBar,
private swUpdates: SwUpdatesService) {
this.onDisable.subscribe(() => this.snackBars.forEach(sb => sb.dismiss()));
}
@ -71,7 +74,9 @@ export class SwUpdateNotificationsService {
}
private onActivateSuccess() {
this.openSnackBar('Update activated successfully! Reload the page to see the latest content.');
const message = 'Update activated successfully! Reload the page to see the latest content.';
this.openSnackBar(message, 'Reload')
.onAction().subscribe(() => this.reloadPage());
}
private openSnackBar(message: string, action?: string, config?: MdSnackBarConfig): MdSnackBarRef<any> {
@ -82,4 +87,11 @@ export class SwUpdateNotificationsService {
return snackBar;
}
private reloadPage() {
const location = this.global && (this.global as Window).location;
if (location && location.reload) {
location.reload();
}
}
}

View File

@ -2,16 +2,19 @@ import { NgModule } from '@angular/core';
import { MdSnackBarModule } from '@angular/material';
import { ServiceWorkerModule } from '@angular/service-worker';
import { globalProvider } from './global.value';
import { noopNgServiceWorkerProviders } from './noop-ng-service-worker';
import { SwUpdateNotificationsService } from './sw-update-notifications.service';
import { SwUpdatesService } from './sw-updates.service';
@NgModule({
imports: [
MdSnackBarModule,
ServiceWorkerModule
],
providers: [
globalProvider,
noopNgServiceWorkerProviders,
SwUpdateNotificationsService,
SwUpdatesService