feat(aio): allow reloading page from ServiceWorker update notification
This commit is contained in:
parent
b1a3c47766
commit
2535769a65
5
aio/src/app/sw-updates/global.value.ts
Normal file
5
aio/src/app/sw-updates/global.value.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { InjectionToken } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
export const Global = new InjectionToken<Window>('global');
|
||||||
|
export const globalProvider = { provide: Global, useValue: window };
|
@ -5,6 +5,7 @@ import { Observable } from 'rxjs/Observable';
|
|||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
|
||||||
import { MockSwUpdatesService } from 'testing/sw-updates.service';
|
import { MockSwUpdatesService } from 'testing/sw-updates.service';
|
||||||
|
import { Global } from './global.value';
|
||||||
import { SwUpdateNotificationsService } from './sw-update-notifications.service';
|
import { SwUpdateNotificationsService } from './sw-update-notifications.service';
|
||||||
import { SwUpdatesService } from './sw-updates.service';
|
import { SwUpdatesService } from './sw-updates.service';
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ describe('SwUpdateNotificationsService', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
injector = ReflectiveInjector.resolveAndCreate([
|
injector = ReflectiveInjector.resolveAndCreate([
|
||||||
|
{ provide: Global, useClass: MockGlobal },
|
||||||
{ provide: MdSnackBar, useClass: MockMdSnackBar },
|
{ provide: MdSnackBar, useClass: MockMdSnackBar },
|
||||||
{ provide: SwUpdatesService, useClass: MockSwUpdatesService },
|
{ provide: SwUpdatesService, useClass: MockSwUpdatesService },
|
||||||
SwUpdateNotificationsService
|
SwUpdateNotificationsService
|
||||||
@ -87,10 +89,22 @@ describe('SwUpdateNotificationsService', () => {
|
|||||||
activateUpdate(true);
|
activateUpdate(true);
|
||||||
|
|
||||||
expect(snackBar.$$lastRef.$$message).toContain('Update activated successfully');
|
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();
|
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(() => {
|
it('should report a failed activation', fakeAsync(() => {
|
||||||
activateUpdate(false);
|
activateUpdate(false);
|
||||||
|
|
||||||
@ -158,6 +172,12 @@ describe('SwUpdateNotificationsService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Mocks
|
// Mocks
|
||||||
|
class MockGlobal {
|
||||||
|
location = {
|
||||||
|
reload: jasmine.createSpy('MockGlobal.reload')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class MockMdSnackBarRef {
|
class MockMdSnackBarRef {
|
||||||
$$afterDismissedSubj = new Subject();
|
$$afterDismissedSubj = new Subject();
|
||||||
$$onActionSubj = new Subject();
|
$$onActionSubj = new Subject();
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Inject, Injectable } from '@angular/core';
|
||||||
import { MdSnackBar, MdSnackBarConfig, MdSnackBarRef } from '@angular/material';
|
import { MdSnackBar, MdSnackBarConfig, MdSnackBarRef } from '@angular/material';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
import 'rxjs/add/operator/filter';
|
import 'rxjs/add/operator/filter';
|
||||||
|
|
||||||
|
import { Global } from './global.value';
|
||||||
import { SwUpdatesService } from './sw-updates.service';
|
import { SwUpdatesService } from './sw-updates.service';
|
||||||
|
|
||||||
|
|
||||||
@ -29,7 +30,9 @@ export class SwUpdateNotificationsService {
|
|||||||
private snackBars: MdSnackBarRef<any>[] = [];
|
private snackBars: MdSnackBarRef<any>[] = [];
|
||||||
private enabled = false;
|
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()));
|
this.onDisable.subscribe(() => this.snackBars.forEach(sb => sb.dismiss()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +74,9 @@ export class SwUpdateNotificationsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onActivateSuccess() {
|
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> {
|
private openSnackBar(message: string, action?: string, config?: MdSnackBarConfig): MdSnackBarRef<any> {
|
||||||
@ -82,4 +87,11 @@ export class SwUpdateNotificationsService {
|
|||||||
|
|
||||||
return snackBar;
|
return snackBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private reloadPage() {
|
||||||
|
const location = this.global && (this.global as Window).location;
|
||||||
|
if (location && location.reload) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,19 @@ import { NgModule } from '@angular/core';
|
|||||||
import { MdSnackBarModule } from '@angular/material';
|
import { MdSnackBarModule } from '@angular/material';
|
||||||
import { ServiceWorkerModule } from '@angular/service-worker';
|
import { ServiceWorkerModule } from '@angular/service-worker';
|
||||||
|
|
||||||
|
import { globalProvider } from './global.value';
|
||||||
import { noopNgServiceWorkerProviders } from './noop-ng-service-worker';
|
import { noopNgServiceWorkerProviders } from './noop-ng-service-worker';
|
||||||
import { SwUpdateNotificationsService } from './sw-update-notifications.service';
|
import { SwUpdateNotificationsService } from './sw-update-notifications.service';
|
||||||
import { SwUpdatesService } from './sw-updates.service';
|
import { SwUpdatesService } from './sw-updates.service';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
MdSnackBarModule,
|
MdSnackBarModule,
|
||||||
ServiceWorkerModule
|
ServiceWorkerModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
globalProvider,
|
||||||
noopNgServiceWorkerProviders,
|
noopNgServiceWorkerProviders,
|
||||||
SwUpdateNotificationsService,
|
SwUpdateNotificationsService,
|
||||||
SwUpdatesService
|
SwUpdatesService
|
||||||
|
Loading…
x
Reference in New Issue
Block a user