|
|
|
@ -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(); |
|
|
|
} |
|
|
|
} |
|
|
|
|