From 1a8ab7b4b99722a8a09cc00a8871d375edbf8589 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 21 Jun 2023 19:30:52 +0300 Subject: [PATCH] RED-6802, fixed notification not appearing if emitted quickly. --- src/lib/error/error.service.ts | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/lib/error/error.service.ts b/src/lib/error/error.service.ts index a2988d3..0b15339 100644 --- a/src/lib/error/error.service.ts +++ b/src/lib/error/error.service.ts @@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core'; import { fromEvent, merge, Observable, Subject } from 'rxjs'; import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; import { LoadingService } from '../loading'; -import { filter, map, tap } from 'rxjs/operators'; +import { distinctUntilChanged, filter, map, tap } from 'rxjs/operators'; import { NavigationStart, Router } from '@angular/router'; import { shareLast } from '../utils'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -34,6 +34,8 @@ const OFFLINE_STATUSES = [ ] as const; const isOffline = (error?: ErrorType) => error instanceof HttpErrorResponse && OFFLINE_STATUSES.includes(error.status); +const isSameEventType = (previous: Event | string | undefined, current: Event | string | undefined) => + previous instanceof Event && current instanceof Event ? previous.type === current.type : false; @Injectable({ providedIn: 'root' }) export class ErrorService { @@ -48,7 +50,7 @@ export class ErrorService { readonly #displayNotification$ = new Subject(); // eslint-disable-next-line no-undef #notificationTimeout: Record = {}; - #lastDisplayedNotification: string | undefined; + #displayedNotificationType: string | undefined; constructor() { this.#router.events @@ -64,19 +66,15 @@ export class ErrorService { this.online$ = this.#online(); this.connectionStatus$ = merge(this.online$, this.offline$, this.#displayNotification$).pipe( + distinctUntilChanged(isSameEventType), filter(value => { - if (value instanceof Event) { - this.#clearNotificationTimeouts(); - this.#setNotificationTimeout(value.type); - return false; - } - return true; - }), - map(value => { - const casted = value as string | undefined; - this.#lastDisplayedNotification = casted; - return casted; + if (!(value instanceof Event)) return true; + this.#clearNotificationTimeouts(); + this.#setNotificationTimeout(value.type); + return false; }), + map(value => value as string | undefined), + tap(value => (this.#displayedNotificationType = value)), ); } @@ -101,11 +99,7 @@ export class ErrorService { } #setNotificationTimeout(status: string) { - if (status === 'online') { - if (this.#lastDisplayedNotification !== 'offline') { - return; - } - } + if (status === 'online' && this.#displayedNotificationType !== 'offline') return; this.#notificationTimeout[status] ??= setTimeout(() => { this.#displayNotification$.next(status); if (status === 'online') {