Merge branch 'master' into mononaut/testmempoolaccept

This commit is contained in:
softsimon
2024-05-04 14:11:48 +07:00
committed by GitHub
80 changed files with 4445 additions and 783 deletions

View File

@@ -23,7 +23,7 @@ export class EnterpriseService {
private stateService: StateService,
private activatedRoute: ActivatedRoute,
) {
const subdomain = this.document.location.hostname.indexOf(this.exclusiveHostName) > -1
const subdomain = this.stateService.env.customize?.enterprise || this.document.location.hostname.indexOf(this.exclusiveHostName) > -1
&& this.document.location.hostname.split(this.exclusiveHostName)[0] || false;
if (subdomain && subdomain.match(/^[A-z0-9-_]+$/)) {
this.subdomain = subdomain;
@@ -47,16 +47,23 @@ export class EnterpriseService {
}
fetchSubdomainInfo(): void {
this.apiService.getEnterpriseInfo$(this.subdomain).subscribe((info) => {
if (this.stateService.env.customize?.branding) {
const info = this.stateService.env.customize?.branding;
this.insertMatomo(info.site_id);
this.seoService.setEnterpriseTitle(info.title);
this.seoService.setEnterpriseTitle(info.title, true);
this.info$.next(info);
},
(error) => {
if (error.status === 404) {
window.location.href = 'https://mempool.space' + window.location.pathname;
}
});
} else {
this.apiService.getEnterpriseInfo$(this.subdomain).subscribe((info) => {
this.insertMatomo(info.site_id);
this.seoService.setEnterpriseTitle(info.title);
this.info$.next(info);
},
(error) => {
if (error.status === 404) {
window.location.href = 'https://mempool.space' + window.location.pathname;
}
});
}
}
insertMatomo(siteId?: number): void {

View File

@@ -50,8 +50,12 @@ export class SeoService {
this.metaService.updateTag({ property: 'og:meta:ready', content: 'ready'});
}
setEnterpriseTitle(title: string) {
this.baseTitle = title + ' - ' + this.baseTitle;
setEnterpriseTitle(title: string, override: boolean = false) {
if (override) {
this.baseTitle = title;
} else {
this.baseTitle = title + ' - ' + this.baseTitle;
}
this.resetTitle();
}

View File

@@ -1,7 +1,7 @@
import { Inject, Injectable, PLATFORM_ID, LOCALE_ID } from '@angular/core';
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable, merge } from 'rxjs';
import { Transaction } from '../interfaces/electrs.interface';
import { HealthCheckHost, IBackendInfo, MempoolBlock, MempoolBlockDelta, MempoolInfo, Recommendedfees, ReplacedTransaction, ReplacementInfo } from '../interfaces/websocket.interface';
import { HealthCheckHost, IBackendInfo, MempoolBlock, MempoolBlockDelta, MempoolBlockUpdate, MempoolInfo, Recommendedfees, ReplacedTransaction, ReplacementInfo, isMempoolState } from '../interfaces/websocket.interface';
import { BlockExtended, CpfpInfo, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree, TransactionStripped } from '../interfaces/node-api.interface';
import { Router, NavigationStart } from '@angular/router';
import { isPlatformBrowser } from '@angular/common';
@@ -20,6 +20,24 @@ export interface MarkBlockState {
export interface ILoadingIndicators { [name: string]: number; }
export interface Customization {
theme: string;
enterprise?: string;
branding: {
name: string;
site_id?: number;
title: string;
img: string;
rounded_corner: boolean;
},
dashboard: {
widgets: {
component: string;
props: { [key: string]: any };
}[];
};
}
export interface Env {
TESTNET_ENABLED: boolean;
SIGNET_ENABLED: boolean;
@@ -50,6 +68,7 @@ export interface Env {
ADDITIONAL_CURRENCIES: boolean;
GIT_COMMIT_HASH_MEMPOOL_SPACE?: string;
PACKAGE_JSON_VERSION_MEMPOOL_SPACE?: string;
customize?: Customization;
}
const defaultEnv: Env = {
@@ -108,8 +127,7 @@ export class StateService {
bsqPrice$ = new ReplaySubject<number>(1);
mempoolInfo$ = new ReplaySubject<MempoolInfo>(1);
mempoolBlocks$ = new ReplaySubject<MempoolBlock[]>(1);
mempoolBlockTransactions$ = new Subject<TransactionStripped[]>();
mempoolBlockDelta$ = new Subject<MempoolBlockDelta>();
mempoolBlockUpdate$ = new Subject<MempoolBlockUpdate>();
liveMempoolBlockTransactions$: Observable<{ [txid: string]: TransactionStripped}>;
txConfirmed$ = new Subject<[string, BlockExtended]>();
txReplaced$ = new Subject<ReplacedTransaction>();
@@ -136,7 +154,7 @@ export class StateService {
live2Chart$ = new Subject<OptimizedMempoolStats>();
viewFiat$ = new BehaviorSubject<boolean>(false);
viewAmountMode$: BehaviorSubject<'btc' | 'sats' | 'fiat'>;
connectionState$ = new BehaviorSubject<0 | 1 | 2>(2);
isTabHidden$: Observable<boolean>;
@@ -151,7 +169,7 @@ export class StateService {
hideAudit: BehaviorSubject<boolean>;
fiatCurrency$: BehaviorSubject<string>;
rateUnits$: BehaviorSubject<string>;
showMiningInfo$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
blockDisplayMode$: BehaviorSubject<string>;
searchFocus$: Subject<boolean> = new Subject<boolean>();
menuOpen$: BehaviorSubject<boolean> = new BehaviorSubject(false);
@@ -196,25 +214,25 @@ export class StateService {
this.router.navigate(['/tracker/' + window.location.pathname.slice(4)]);
}
this.liveMempoolBlockTransactions$ = merge(
this.mempoolBlockTransactions$.pipe(map(transactions => { return { transactions }; })),
this.mempoolBlockDelta$.pipe(map(delta => { return { delta }; })),
).pipe(scan((transactions: { [txid: string]: TransactionStripped }, change: any): { [txid: string]: TransactionStripped } => {
if (change.transactions) {
const txMap = {}
this.liveMempoolBlockTransactions$ = this.mempoolBlockUpdate$.pipe(scan((transactions: { [txid: string]: TransactionStripped }, change: MempoolBlockUpdate): { [txid: string]: TransactionStripped } => {
if (isMempoolState(change)) {
const txMap = {};
change.transactions.forEach(tx => {
txMap[tx.txid] = tx;
})
});
return txMap;
} else {
change.delta.changed.forEach(tx => {
transactions[tx.txid].rate = tx.rate;
})
change.delta.removed.forEach(txid => {
change.added.forEach(tx => {
transactions[tx.txid] = tx;
});
change.removed.forEach(txid => {
delete transactions[txid];
});
change.delta.added.forEach(tx => {
transactions[tx.txid] = tx;
change.changed.forEach(tx => {
if (transactions[tx.txid]) {
transactions[tx.txid].rate = tx.rate;
transactions[tx.txid].acc = tx.acc;
}
});
return transactions;
}
@@ -259,6 +277,12 @@ export class StateService {
const rateUnitPreference = this.storageService.getValue('rate-unit-preference');
this.rateUnits$ = new BehaviorSubject<string>(rateUnitPreference || 'vb');
const blockDisplayModePreference = this.storageService.getValue('block-display-mode-preference');
this.blockDisplayMode$ = new BehaviorSubject<string>(blockDisplayModePreference || 'fees');
const viewAmountModePreference = this.storageService.getValue('view-amount-mode') as 'btc' | 'sats' | 'fiat';
this.viewAmountMode$ = new BehaviorSubject<'btc' | 'sats' | 'fiat'>(viewAmountModePreference || 'btc');
this.backend$.subscribe(backend => {
this.backend = backend;
});

View File

@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { defaultMempoolFeeColors, contrastMempoolFeeColors } from '../app.constants';
import { StorageService } from './storage.service';
import { StateService } from './state.service';
@Injectable({
providedIn: 'root'
@@ -14,8 +15,9 @@ export class ThemeService {
constructor(
private storageService: StorageService,
private stateService: StateService,
) {
const theme = this.storageService.getValue('theme-preference') || 'default';
const theme = this.storageService.getValue('theme-preference') || this.stateService.env.customize?.theme || 'default';
this.apply(theme);
}

View File

@@ -401,14 +401,16 @@ export class WebsocketService {
if (response['projected-block-transactions'].index == this.trackingMempoolBlock) {
if (response['projected-block-transactions'].blockTransactions) {
this.stateService.mempoolSequence = response['projected-block-transactions'].sequence;
this.stateService.mempoolBlockTransactions$.next(response['projected-block-transactions'].blockTransactions.map(uncompressTx));
this.stateService.mempoolBlockUpdate$.next({
transactions: response['projected-block-transactions'].blockTransactions.map(uncompressTx),
});
} else if (response['projected-block-transactions'].delta) {
if (this.stateService.mempoolSequence && response['projected-block-transactions'].sequence !== this.stateService.mempoolSequence + 1) {
this.stateService.mempoolSequence = 0;
this.startTrackMempoolBlock(this.trackingMempoolBlock, true);
} else {
this.stateService.mempoolSequence = response['projected-block-transactions'].sequence;
this.stateService.mempoolBlockDelta$.next(uncompressDeltaChange(response['projected-block-transactions'].delta));
this.stateService.mempoolBlockUpdate$.next(uncompressDeltaChange(response['projected-block-transactions'].delta));
}
}
}