|
|
|
@ -1,13 +1,14 @@
|
|
|
|
|
import { Injectable } from '@angular/core';
|
|
|
|
|
import { Injectable, Injector } from '@angular/core';
|
|
|
|
|
import { HttpRequest } from '@angular/common/http';
|
|
|
|
|
import { InternalStore } from '../utils/internal-store-utils';
|
|
|
|
|
import { getPathName } from '../utils/http-utils';
|
|
|
|
|
import { debounceTime, tap } from 'rxjs/operators';
|
|
|
|
|
import { map, mapTo, switchMap, takeUntil, tap } from 'rxjs/operators';
|
|
|
|
|
import { of, Subject, timer } from 'rxjs';
|
|
|
|
|
import { LOADER_DELAY } from '../tokens/lodaer-delay.token';
|
|
|
|
|
|
|
|
|
|
export interface HttpWaitState {
|
|
|
|
|
requests: Set<HttpRequest<any>>;
|
|
|
|
|
requests: HttpRequest<any>[];
|
|
|
|
|
filteredRequests: Array<HttpRequestInfo>;
|
|
|
|
|
delay: number;
|
|
|
|
|
}
|
|
|
|
|
export interface HttpRequestInfo {
|
|
|
|
|
method: string;
|
|
|
|
@ -18,19 +19,35 @@ export interface HttpRequestInfo {
|
|
|
|
|
})
|
|
|
|
|
export class HttpWaitService {
|
|
|
|
|
protected store = new InternalStore<HttpWaitState>({
|
|
|
|
|
requests: new Set(),
|
|
|
|
|
requests: [],
|
|
|
|
|
filteredRequests: [],
|
|
|
|
|
delay: 0,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
private delay: number;
|
|
|
|
|
private destroy$ = new Subject();
|
|
|
|
|
|
|
|
|
|
constructor(injector: Injector) {
|
|
|
|
|
this.delay = injector.get(LOADER_DELAY, 500);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getLoading() {
|
|
|
|
|
return !!this.applyFilter(this.store.state.requests).length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getLoading$() {
|
|
|
|
|
return this.store
|
|
|
|
|
.sliceState(({ requests }) => !!this.applyFilter(requests).length)
|
|
|
|
|
.pipe(this.debounceWhenLoading());
|
|
|
|
|
.sliceState(({ requests }) => requests)
|
|
|
|
|
.pipe(
|
|
|
|
|
map(requests => !!this.applyFilter(requests).length),
|
|
|
|
|
switchMap(condition =>
|
|
|
|
|
condition
|
|
|
|
|
? this.delay === 0
|
|
|
|
|
? of(true)
|
|
|
|
|
: timer(this.delay).pipe(mapTo(true), takeUntil(this.destroy$))
|
|
|
|
|
: of(false),
|
|
|
|
|
),
|
|
|
|
|
tap(() => this.destroy$.next()),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateLoading$() {
|
|
|
|
@ -38,19 +55,15 @@ export class HttpWaitService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clearLoading() {
|
|
|
|
|
this.store.patch({ requests: new Set() });
|
|
|
|
|
this.store.patch({ requests: [] });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addRequest(request: HttpRequest<any>) {
|
|
|
|
|
let { requests } = this.store.state;
|
|
|
|
|
requests = new Set(requests.values());
|
|
|
|
|
requests.add(request);
|
|
|
|
|
this.store.patch({ requests });
|
|
|
|
|
this.store.patch({ requests: [...this.store.state.requests, request] });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteRequest(request: HttpRequest<any>) {
|
|
|
|
|
const { requests } = this.store.state;
|
|
|
|
|
requests.delete(request);
|
|
|
|
|
const requests = this.store.state.requests.filter(r => r !== request);
|
|
|
|
|
this.store.patch({ requests });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -73,13 +86,9 @@ export class HttpWaitService {
|
|
|
|
|
this.store.patch({ filteredRequests });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setDelay(delay: number) {
|
|
|
|
|
this.store.patch({ delay });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private applyFilter(requests: Set<HttpRequest<any>>) {
|
|
|
|
|
private applyFilter(requests: HttpRequest<any>[]) {
|
|
|
|
|
const { filteredRequests } = this.store.state;
|
|
|
|
|
return Array.from(requests).filter(
|
|
|
|
|
return requests.filter(
|
|
|
|
|
({ method, url }) =>
|
|
|
|
|
!filteredRequests.find(filteredRequest =>
|
|
|
|
|
this.isSameRequest(filteredRequest, { method, endpoint: getPathName(url) }),
|
|
|
|
@ -91,10 +100,4 @@ export class HttpWaitService {
|
|
|
|
|
const { method, endpoint } = filteredRequest;
|
|
|
|
|
return endpoint === request.endpoint && method === request.method;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private debounceWhenLoading() {
|
|
|
|
|
return this.store.state.delay && !!this.applyFilter(this.store.state.requests).length
|
|
|
|
|
? debounceTime(this.store.state.delay)
|
|
|
|
|
: tap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|