2020-02-16 22:15:07 +07:00
|
|
|
import { Injectable } from '@angular/core';
|
2020-06-11 01:38:59 +07:00
|
|
|
import { ReplaySubject, BehaviorSubject, Subject, fromEvent } from 'rxjs';
|
2020-02-23 19:16:50 +07:00
|
|
|
import { Block, Transaction } from '../interfaces/electrs.interface';
|
2020-09-26 02:11:30 +07:00
|
|
|
import { MempoolBlock, MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface';
|
2020-02-17 00:26:57 +07:00
|
|
|
import { OptimizedMempoolStats } from '../interfaces/node-api.interface';
|
2020-05-09 20:37:50 +07:00
|
|
|
import { Router, NavigationStart } from '@angular/router';
|
2020-06-22 22:10:49 +07:00
|
|
|
import { env } from '../app.constants';
|
2020-06-11 01:38:59 +07:00
|
|
|
import { shareReplay, map } from 'rxjs/operators';
|
2020-02-16 22:15:07 +07:00
|
|
|
|
2020-03-22 17:44:36 +07:00
|
|
|
interface MarkBlockState {
|
|
|
|
blockHeight?: number;
|
|
|
|
mempoolBlockIndex?: number;
|
|
|
|
txFeePerVSize?: number;
|
|
|
|
}
|
|
|
|
|
2020-02-16 22:15:07 +07:00
|
|
|
@Injectable({
|
|
|
|
providedIn: 'root'
|
|
|
|
})
|
|
|
|
export class StateService {
|
2020-05-09 20:37:50 +07:00
|
|
|
network = '';
|
2020-02-16 22:15:07 +07:00
|
|
|
latestBlockHeight = 0;
|
2020-05-09 20:37:50 +07:00
|
|
|
|
|
|
|
networkChanged$ = new ReplaySubject<string>(1);
|
2020-07-21 12:47:51 +07:00
|
|
|
blocks$ = new ReplaySubject<[Block, boolean]>(env.KEEP_BLOCKS_AMOUNT);
|
2020-09-26 02:11:30 +07:00
|
|
|
transactions$ = new ReplaySubject<TransactionStripped>(6);
|
2020-02-16 22:15:07 +07:00
|
|
|
conversions$ = new ReplaySubject<any>(1);
|
2020-07-14 21:26:02 +07:00
|
|
|
bsqPrice$ = new ReplaySubject<number>(1);
|
2020-08-12 13:33:58 +07:00
|
|
|
mempoolInfo$ = new ReplaySubject<MempoolInfo>(1);
|
2020-07-24 14:11:49 +07:00
|
|
|
mempoolBlocks$ = new ReplaySubject<MempoolBlock[]>(1);
|
2020-06-08 18:55:53 +07:00
|
|
|
txReplaced$ = new Subject<Transaction>();
|
2020-02-23 19:16:50 +07:00
|
|
|
mempoolTransactions$ = new Subject<Transaction>();
|
|
|
|
blockTransactions$ = new Subject<Transaction>();
|
2020-07-22 19:21:40 +07:00
|
|
|
isLoadingWebSocket$ = new ReplaySubject<boolean>(1);
|
2020-08-12 13:33:58 +07:00
|
|
|
vbytesPerSecond$ = new ReplaySubject<number>(1);
|
2020-09-21 19:41:12 +07:00
|
|
|
lastDifficultyAdjustment$ = new ReplaySubject<number>(1);
|
2020-08-12 13:33:58 +07:00
|
|
|
gitCommit$ = new ReplaySubject<string>(1);
|
2020-10-07 20:15:42 +07:00
|
|
|
donationConfirmed$ = new Subject();
|
2020-02-23 19:16:50 +07:00
|
|
|
|
2020-02-17 00:26:57 +07:00
|
|
|
live2Chart$ = new Subject<OptimizedMempoolStats>();
|
2020-02-16 22:15:07 +07:00
|
|
|
|
|
|
|
viewFiat$ = new BehaviorSubject<boolean>(false);
|
2020-03-09 17:53:54 +07:00
|
|
|
connectionState$ = new BehaviorSubject<0 | 1 | 2>(2);
|
2020-06-11 01:38:59 +07:00
|
|
|
isTabHidden$ = fromEvent(document, 'visibilitychange').pipe(map((event) => this.isHidden()), shareReplay());
|
2020-03-22 17:44:36 +07:00
|
|
|
|
2020-05-20 17:00:50 +07:00
|
|
|
markBlock$ = new ReplaySubject<MarkBlockState>();
|
2020-05-13 13:03:57 +07:00
|
|
|
keyNavigation$ = new Subject<KeyboardEvent>();
|
2020-05-09 20:37:50 +07:00
|
|
|
|
|
|
|
constructor(
|
|
|
|
private router: Router,
|
|
|
|
) {
|
2020-05-10 12:31:57 +07:00
|
|
|
this.setNetworkBasedonUrl(window.location.pathname);
|
|
|
|
|
2020-05-09 20:37:50 +07:00
|
|
|
this.router.events.subscribe((event) => {
|
|
|
|
if (event instanceof NavigationStart) {
|
2020-05-10 12:31:57 +07:00
|
|
|
this.setNetworkBasedonUrl(event.url);
|
2020-05-09 20:37:50 +07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2020-05-10 12:31:57 +07:00
|
|
|
|
|
|
|
setNetworkBasedonUrl(url: string) {
|
2020-08-07 13:11:55 +07:00
|
|
|
switch (url.split(/\/|\?|#/)[1]) {
|
2020-05-10 12:31:57 +07:00
|
|
|
case 'liquid':
|
|
|
|
if (this.network !== 'liquid') {
|
|
|
|
this.network = 'liquid';
|
|
|
|
this.networkChanged$.next('liquid');
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case 'testnet':
|
|
|
|
if (this.network !== 'testnet') {
|
|
|
|
this.network = 'testnet';
|
|
|
|
this.networkChanged$.next('testnet');
|
|
|
|
}
|
|
|
|
return;
|
2020-07-03 23:45:19 +07:00
|
|
|
case 'bisq':
|
|
|
|
if (this.network !== 'bisq') {
|
|
|
|
this.network = 'bisq';
|
|
|
|
this.networkChanged$.next('bisq');
|
|
|
|
}
|
|
|
|
return;
|
2020-05-10 12:31:57 +07:00
|
|
|
default:
|
|
|
|
if (this.network !== '') {
|
|
|
|
this.network = '';
|
|
|
|
this.networkChanged$.next('');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-06-11 01:38:59 +07:00
|
|
|
|
|
|
|
getHiddenProp(){
|
|
|
|
const prefixes = ['webkit', 'moz', 'ms', 'o'];
|
|
|
|
if ('hidden' in document) { return 'hidden'; }
|
|
|
|
for (const prefix of prefixes) {
|
|
|
|
if ((prefix + 'Hidden') in document) {
|
|
|
|
return prefix + 'Hidden';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
isHidden() {
|
|
|
|
const prop = this.getHiddenProp();
|
|
|
|
if (!prop) { return false; }
|
|
|
|
return document[prop];
|
|
|
|
}
|
2020-02-16 22:15:07 +07:00
|
|
|
}
|