From 0610684e8fb963fab1f7dd51fd850a7b47287fca Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Fri, 17 Dec 2021 16:23:16 +0200 Subject: [PATCH] fix displaying indicator when navigation start --- src/lib/error/error.service.ts | 31 ++++++++++++++----- .../full-page-error.component.html | 7 ++++- .../full-page-error.component.ts | 14 +-------- src/lib/error/server-error-interceptor.ts | 2 +- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/lib/error/error.service.ts b/src/lib/error/error.service.ts index 3467b95..237ac1e 100644 --- a/src/lib/error/error.service.ts +++ b/src/lib/error/error.service.ts @@ -1,8 +1,8 @@ import { Injectable } from '@angular/core'; -import { Subject } from 'rxjs'; +import { fromEvent, merge, Observable, Subject } from 'rxjs'; import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; import { LoadingService } from '../loading'; -import { filter, map, skip } from 'rxjs/operators'; +import { delay, filter, map, mapTo } from 'rxjs/operators'; import { NavigationStart, Router } from '@angular/router'; import { shareLast } from '../utils'; @@ -19,18 +19,21 @@ const isOffline = (error?: HttpErrorResponse) => !!error && OFFLINE_STATUSES.inc @Injectable({ providedIn: 'root' }) export class ErrorService { readonly error$ = new Subject(); - readonly offlineError$ = this.error$.pipe( - skip(1), - filter(error => !error || isOffline(error)), - map(error => new Event(error ? 'offline' : 'online')), - shareLast(), - ); + readonly offline$: Observable; + readonly online$: Observable; readonly serverError$ = this.error$.pipe(filter(error => !error || !isOffline(error))); + readonly connectionStatus$: Observable; + private readonly _online$ = new Subject(); constructor(private readonly _loadingService: LoadingService, private readonly _router: Router) { _router.events.pipe(filter(event => event instanceof NavigationStart)).subscribe(() => { this.clear(); }); + this.offline$ = this._offline(); + this.online$ = this._online(); + const removeIndicator$ = this.online$.pipe(delay(3000), mapTo(undefined)); + + this.connectionStatus$ = merge(this.online$, this.offline$, removeIndicator$).pipe(map(event => event?.type)); } set(error: HttpErrorResponse): void { @@ -38,7 +41,19 @@ export class ErrorService { this.error$.next(error); } + setOnline(): void { + this._online$.next(); + } + clear(): void { this.error$.next(); } + + private _offline() { + return merge(fromEvent(window, 'offline'), this.error$.pipe(filter(isOffline), mapTo(new Event('offline')), shareLast())); + } + + private _online() { + return merge(fromEvent(window, 'online'), this._online$.pipe(mapTo(new Event('online')))).pipe(shareLast()); + } } diff --git a/src/lib/error/full-page-error/full-page-error.component.html b/src/lib/error/full-page-error/full-page-error.component.html index 00d45eb..864ed88 100644 --- a/src/lib/error/full-page-error/full-page-error.component.html +++ b/src/lib/error/full-page-error/full-page-error.component.html @@ -1,4 +1,9 @@ -
+
diff --git a/src/lib/error/full-page-error/full-page-error.component.ts b/src/lib/error/full-page-error/full-page-error.component.ts index b123ad1..1c29a90 100644 --- a/src/lib/error/full-page-error/full-page-error.component.ts +++ b/src/lib/error/full-page-error/full-page-error.component.ts @@ -2,9 +2,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { IconButtonTypes } from '../../buttons'; import { ErrorService } from '../error.service'; import { animate, state, style, transition, trigger } from '@angular/animations'; -import { fromEvent, merge, Observable } from 'rxjs'; -import { delay, filter, map, mapTo } from 'rxjs/operators'; -import { shareLast } from '../../utils'; import { connectionStatusTranslations } from '../../translations/connection-status-translations'; @Component({ @@ -24,17 +21,8 @@ import { connectionStatusTranslations } from '../../translations/connection-stat export class FullPageErrorComponent { translations = connectionStatusTranslations; readonly iconButtonTypes = IconButtonTypes; - readonly connectionStatus$: Observable; - constructor(readonly errorService: ErrorService) { - const offline$ = merge(fromEvent(window, 'offline'), this.errorService.offlineError$); - const online$ = fromEvent(window, 'online').pipe(shareLast()); - - const errorGone$ = this.errorService.offlineError$.pipe(filter(error => !error)); - const removeIndicator$ = merge(online$, errorGone$).pipe(delay(3000), mapTo(undefined)); - - this.connectionStatus$ = merge(online$, offline$, removeIndicator$).pipe(map(event => event?.type)); - } + constructor(readonly errorService: ErrorService) {} reload(): void { window.location.reload(); diff --git a/src/lib/error/server-error-interceptor.ts b/src/lib/error/server-error-interceptor.ts index 8d9976c..e63e850 100644 --- a/src/lib/error/server-error-interceptor.ts +++ b/src/lib/error/server-error-interceptor.ts @@ -60,7 +60,7 @@ export class ServerErrorInterceptor implements HttpInterceptor { backoffOnServerError(this._maxRetries || 3), tap(() => { if (this._urlsWithError.has(req.url)) { - this._errorService.clear(); + this._errorService.setOnline(); this._urlsWithError.delete(req.url); } }),