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 { connectionStatusTranslations } from '../../translations';
|
||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
import { ErrorService } from '../error.service';
|
import { ErrorService } from '../error.service';
|
||||||
@ -19,6 +19,5 @@ import { ErrorService } from '../error.service';
|
|||||||
})
|
})
|
||||||
export class ConnectionStatusComponent {
|
export class ConnectionStatusComponent {
|
||||||
connectionStatusTranslations = connectionStatusTranslations;
|
connectionStatusTranslations = connectionStatusTranslations;
|
||||||
|
protected readonly errorService = inject(ErrorService);
|
||||||
constructor(readonly errorService: ErrorService) {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { inject, Injectable } from '@angular/core';
|
||||||
import { fromEvent, merge, Observable, Subject } from 'rxjs';
|
import { fromEvent, merge, Observable, Subject } from 'rxjs';
|
||||||
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
||||||
import { LoadingService } from '../loading';
|
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 { NavigationStart, Router } from '@angular/router';
|
||||||
import { shareLast } from '../utils';
|
import { shareLast } from '../utils';
|
||||||
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
|
||||||
export class CustomError {
|
export class CustomError {
|
||||||
readonly label: string;
|
readonly label: string;
|
||||||
@ -39,41 +40,72 @@ export class ErrorService {
|
|||||||
readonly offline$: Observable<Event>;
|
readonly offline$: Observable<Event>;
|
||||||
readonly online$: Observable<Event>;
|
readonly online$: Observable<Event>;
|
||||||
readonly connectionStatus$: Observable<string | undefined>;
|
readonly connectionStatus$: Observable<string | undefined>;
|
||||||
private readonly _error$ = new Subject<ErrorType>();
|
readonly #error$ = new Subject<ErrorType>();
|
||||||
readonly error$ = this._error$.pipe(filter(error => !error || !isOffline(error)));
|
readonly error$ = this.#error$.pipe(filter(error => !error || !isOffline(error)));
|
||||||
private readonly _online$ = new Subject();
|
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) {
|
constructor() {
|
||||||
_router.events.pipe(filter(event => event instanceof NavigationStart)).subscribe(() => {
|
this.#router.events
|
||||||
this.clear();
|
.pipe(
|
||||||
});
|
filter(event => event instanceof NavigationStart),
|
||||||
this.offline$ = this._offline();
|
tap(() => this.clear()),
|
||||||
this.online$ = this._online();
|
takeUntilDestroyed(),
|
||||||
const removeIndicator$ = this.online$.pipe(
|
)
|
||||||
delay(3000),
|
// eslint-disable-next-line rxjs/no-ignored-subscription
|
||||||
map(() => undefined),
|
.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 {
|
set(error: ErrorType): void {
|
||||||
this._loadingService.stop();
|
this.#loadingService.stop();
|
||||||
this._error$.next(error);
|
this.#error$.next(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
setOnline(): void {
|
setOnline(): void {
|
||||||
this._online$.next(true);
|
this.#online$.next(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(): void {
|
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(
|
return merge(
|
||||||
fromEvent(window, 'offline'),
|
fromEvent(window, 'offline'),
|
||||||
this._error$.pipe(
|
this.#error$.pipe(
|
||||||
filter(isOffline),
|
filter(isOffline),
|
||||||
map(() => new Event('offline')),
|
map(() => new Event('offline')),
|
||||||
shareLast(),
|
shareLast(),
|
||||||
@ -81,7 +113,9 @@ export class ErrorService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _online() {
|
#online() {
|
||||||
return merge(fromEvent(window, 'online'), this._online$.pipe(map(() => new Event('online')))).pipe(shareLast());
|
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