RED-6802, fixed the reconnect notification changing rapidly.
This commit is contained in:
parent
8ebd5f760d
commit
58d4ece28d
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import { connectionStatusTranslations } from '../../translations';
|
||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||
import { ErrorService } from '../error.service';
|
||||
@ -19,6 +19,5 @@ import { ErrorService } from '../error.service';
|
||||
})
|
||||
export class ConnectionStatusComponent {
|
||||
connectionStatusTranslations = connectionStatusTranslations;
|
||||
|
||||
constructor(readonly errorService: ErrorService) {}
|
||||
protected readonly errorService = inject(ErrorService);
|
||||
}
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
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 { delay, filter, map } from 'rxjs/operators';
|
||||
import { filter, map, tap } from 'rxjs/operators';
|
||||
import { NavigationStart, Router } from '@angular/router';
|
||||
import { shareLast } from '../utils';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
export class CustomError {
|
||||
readonly label: string;
|
||||
@ -39,41 +40,72 @@ export class ErrorService {
|
||||
readonly offline$: Observable<Event>;
|
||||
readonly online$: Observable<Event>;
|
||||
readonly connectionStatus$: Observable<string | undefined>;
|
||||
private readonly _error$ = new Subject<ErrorType>();
|
||||
readonly error$ = this._error$.pipe(filter(error => !error || !isOffline(error)));
|
||||
private readonly _online$ = new Subject();
|
||||
readonly #error$ = new Subject<ErrorType>();
|
||||
readonly error$ = this.#error$.pipe(filter(error => !error || !isOffline(error)));
|
||||
readonly #online$ = new Subject();
|
||||
readonly #loadingService = inject(LoadingService);
|
||||
readonly #router = inject(Router);
|
||||
readonly #clearNotification$ = new Subject<undefined>();
|
||||
// eslint-disable-next-line no-undef
|
||||
#timeout: NodeJS.Timeout | undefined;
|
||||
|
||||
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),
|
||||
map(() => undefined),
|
||||
constructor() {
|
||||
this.#router.events
|
||||
.pipe(
|
||||
filter(event => event instanceof NavigationStart),
|
||||
tap(() => this.clear()),
|
||||
takeUntilDestroyed(),
|
||||
)
|
||||
// eslint-disable-next-line rxjs/no-ignored-subscription
|
||||
.subscribe();
|
||||
|
||||
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();
|
||||
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)),
|
||||
);
|
||||
|
||||
this.connectionStatus$ = merge(this.online$, this.offline$, removeIndicator$).pipe(map(event => event?.type));
|
||||
}
|
||||
|
||||
set(error: ErrorType): void {
|
||||
this._loadingService.stop();
|
||||
this._error$.next(error);
|
||||
this.#loadingService.stop();
|
||||
this.#error$.next(error);
|
||||
}
|
||||
|
||||
setOnline(): void {
|
||||
this._online$.next(true);
|
||||
this.#online$.next(true);
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this._error$.next(undefined);
|
||||
this.#error$.next(undefined);
|
||||
}
|
||||
|
||||
private _offline() {
|
||||
#setOnlineTimeout() {
|
||||
this.#timeout ??= setTimeout(() => {
|
||||
this.#online$.next(new Event('display-online'));
|
||||
setTimeout(() => this.#clearNotification$.next(undefined), 3000);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
#clearOnlineTimeout() {
|
||||
clearTimeout(this.#timeout);
|
||||
this.#timeout = undefined;
|
||||
}
|
||||
|
||||
#offline() {
|
||||
return merge(
|
||||
fromEvent(window, 'offline'),
|
||||
this._error$.pipe(
|
||||
this.#error$.pipe(
|
||||
filter(isOffline),
|
||||
map(() => new Event('offline')),
|
||||
shareLast(),
|
||||
@ -81,7 +113,9 @@ export class ErrorService {
|
||||
);
|
||||
}
|
||||
|
||||
private _online() {
|
||||
return merge(fromEvent(window, 'online'), this._online$.pipe(map(() => new Event('online')))).pipe(shareLast());
|
||||
#online() {
|
||||
return merge(fromEvent(window, 'online'), this.#online$.pipe(map(v => (v instanceof Event ? v : new Event('online'))))).pipe(
|
||||
shareLast(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user