in web/frontend/src/app/pages/order-book/order-book-page/order-book-page.component.ts [75:269]
ngOnInit() {
this.initForm();
this.activatedRoute.params.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.orderBookFiltersReady = false;
});
this.orientation$ = this.tabStorageService
.getData()
.pipe(map((data) => data?.orientation || EOrientations.price));
this.hiddenExchanges$ = this.getActiveTab().pipe(
switchMap(() => this.tabStorageService.getData(['hiddenExchanges'])),
map((data) => data?.hiddenExchanges || []),
);
const storageData$ = this.getActiveTab().pipe(
switchMap((tab) =>
this.tabStorageService.getData().pipe(map((data) => ({data, tab: tab.tab}))),
),
map(({data, tab}) => ({
...data,
streams: data?.streams || (tab.stream ? [tab.stream] : null),
symbol: data?.symbol || (tab?.symbol ? [tab.symbol] : null),
})),
distinctUntilChanged(equal),
shareReplay(1),
);
this.exchanges$ = storageData$.pipe(
map((data) => {
if (!data?.symbol?.length) {
return null;
}
return data?.exchanges ? this.sortByName(data?.exchanges) : null;
}),
distinctUntilChanged(equal),
);
let patching = false;
const patchFilters = (callback) => {
patching = true;
callback();
patching = false;
};
combineLatest([this.exchanges$.pipe(filter((e) => !!e)), this.hiddenExchanges$])
.pipe(takeUntil(this.destroy$))
.subscribe(([exchanges, hiddenExchanges]) => {
patchFilters(() =>
this.filters.get('exchanges').patchValue(
exchanges.filter((e) => !hiddenExchanges.includes(e)),
{emitEvent: false},
));
});
storageData$.pipe(takeUntil(this.destroy$)).subscribe((data) => {
patchFilters(() =>
this.filters.patchValue({
streams: data?.streams || [],
symbol: data?.symbol || [],
}),
);
});
storageData$
.pipe(
take(1),
switchMap(() => this.filters.valueChanges.pipe(startWith(this.filters.value))),
distinctUntilChanged(equal),
pairwise(),
filter(() => !patching),
takeUntil(this.destroy$),
)
.subscribe(([prev, current]) => {
const freshExchanges =
(prev.symbol[0] && prev.symbol[0] !== current.symbol[0]) ||
(prev.streams && JSON.stringify(prev.streams) !== JSON.stringify(current.streams));
this.updateTab();
this.tabStorageService.updateDataSync((data) => ({
...data,
streams: current.streams,
symbol: current.symbol,
hiddenExchanges: freshExchanges ? [] : data?.hiddenExchanges,
exchanges: freshExchanges ? null : data?.exchanges,
}));
});
this.streams$ = this.streamsUpdated$.pipe(
switchMap(() => this.streamsService.getList(true)),
map((streams) =>
streams
.filter((s) => !!s.chartType?.find((ct) => ct.chartType === ChartTypes.PRICES_L2))
.map(({key, name}) => ( { key, name } ))
),
);
this.streamNames$ = this.streams$.pipe(map((s) => s.map(str => str.name)));
this.symbols$ = this.streams$.pipe(
tap(streams => this.streams = streams),
switchMap(() => storageData$),
switchMap((data) => {
if (!data?.streams?.length) {
return of([]);
}
return combineLatest(
data.streams.map((streamName: string) => {
const stream = this.streams.find(streamItem => streamItem.name === streamName);
return this.symbolsService.getSymbols(stream.key).pipe(
catchError((e: HttpErrorResponse) => {
if (e.status === 400 && e.error.message.startsWith('Unknown stream')) {
this.streamsUpdated$.next();
this.filters.get('streams').patchValue(data.streams.filter((s) => s !== stream));
}
return of([]);
})
)
}),
);
}),
map((responses) => {
const unique = new Set<string>();
responses.forEach((symbols) => symbols.forEach((symbol) => unique.add(symbol)));
return [...unique].sort((a, b) => (a > b ? 1 : -1));
}),
shareReplay(1),
);
this.symbols$.pipe(takeUntil(this.destroy$)).subscribe((symbols) => {
const chosen = this.filters.get('symbol').value[0];
if (chosen && !symbols.includes(chosen)) {
this.filters.get('symbol').patchValue([]);
}
});
storageData$
.pipe(
tap((data) => {
this.orderBookFiltersReady = !!(
data?.symbol?.length &&
data?.streams?.length &&
(data.exchanges?.length !== data.hiddenExchanges?.length ||
!data.hiddenExchanges?.length)
);
}),
map((data) => ({...data, orientation: null, exchanges: null})),
distinctUntilChanged(equal),
takeUntil(this.destroy$),
switchMap(() => {
this.loading = true;
this.noData = false;
this.cdRef.detectChanges();
return timer(5000);
}),
)
.subscribe(() => {
if (this.loading) {
this.loading = false;
this.noData = true;
}
this.cdRef.detectChanges();
});
this.bookState$.pipe(debounceTime(300), takeUntil(this.destroy$)).subscribe((state) => {
this.loading = !state;
this.noData = false;
this.cdRef.detectChanges();
});
this.streamUpdatesService
.onUpdates()
.pipe(takeUntil(this.destroy$))
.subscribe((update) => {
if (update.renamed.length) {
const selectedStreams = this.streams
.filter(stream => this.filters.get('streams').value.includes(stream.name)).map(stream => stream.key);
const streams = selectedStreams ? [...selectedStreams] : [];
update.renamed.forEach(({oldName, newName}) => {
const index = streams.findIndex((s) => s === oldName);
if (index > -1) {
streams.splice(index, 1, newName);
}
});
this.filters.get('streams').patchValue(streams);
this.streamsUpdated$.next();
this.cdRef.detectChanges();
}
});
}