diff --git a/src/lib/error/error.service.ts b/src/lib/error/error.service.ts index f19a90c..a2988d3 100644 --- a/src/lib/error/error.service.ts +++ b/src/lib/error/error.service.ts @@ -45,9 +45,10 @@ export class ErrorService { readonly #online$ = new Subject(); readonly #loadingService = inject(LoadingService); readonly #router = inject(Router); - readonly #clearNotification$ = new Subject(); + readonly #displayNotification$ = new Subject(); // eslint-disable-next-line no-undef - #timeout: NodeJS.Timeout | undefined; + #notificationTimeout: Record = {}; + #lastDisplayedNotification: string | undefined; constructor() { this.#router.events @@ -62,18 +63,20 @@ export class ErrorService { this.offline$ = this.#offline(); this.online$ = this.#online(); - this.connectionStatus$ = merge(this.online$, this.offline$, this.#clearNotification$.asObservable()).pipe( - map(event => event?.type), - filter(type => { - if (type === 'online') { - this.#setOnlineTimeout(); + this.connectionStatus$ = merge(this.online$, this.offline$, this.#displayNotification$).pipe( + filter(value => { + if (value instanceof Event) { + this.#clearNotificationTimeouts(); + this.#setNotificationTimeout(value.type); return false; } - this.#clearOnlineTimeout(); return true; }), - // used display-online when I manually generate a new event to bypass the above filter - map(type => (type === 'display-online' ? 'online' : type)), + map(value => { + const casted = value as string | undefined; + this.#lastDisplayedNotification = casted; + return casted; + }), ); } @@ -90,16 +93,25 @@ export class ErrorService { this.#error$.next(undefined); } - #setOnlineTimeout() { - this.#timeout ??= setTimeout(() => { - this.#online$.next(new Event('display-online')); - setTimeout(() => this.#clearNotification$.next(undefined), 3000); - }, 3000); + #clearNotificationTimeouts() { + Object.keys(this.#notificationTimeout).forEach(key => { + clearTimeout(this.#notificationTimeout[key]); + this.#notificationTimeout[key] = undefined; + }); } - #clearOnlineTimeout() { - clearTimeout(this.#timeout); - this.#timeout = undefined; + #setNotificationTimeout(status: string) { + if (status === 'online') { + if (this.#lastDisplayedNotification !== 'offline') { + return; + } + } + this.#notificationTimeout[status] ??= setTimeout(() => { + this.#displayNotification$.next(status); + if (status === 'online') { + setTimeout(() => this.#displayNotification$.next(undefined), 3000); + } + }, 3000); } #offline() {