diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts index 0d758100c..7d9adabc4 100644 --- a/backend/src/api/websocket-handler.ts +++ b/backend/src/api/websocket-handler.ts @@ -96,6 +96,14 @@ class WebsocketHandler { client['track-donation'] = parsedMessage['track-donation']; } + if (parsedMessage['track-bisq-market']) { + if (/^[a-z]{3}_[a-z]{3}$/.test(parsedMessage['track-bisq-market'])) { + client['track-bisq-market'] = parsedMessage['track-bisq-market']; + } else { + client['track-bisq-market'] = null; + } + } + if (Object.keys(response).length) { client.send(JSON.stringify(response)); } diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index f0237cd10..0bc077df8 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -122,6 +122,7 @@ export interface WebsocketResponse { 'track-tx': string; 'track-address': string; 'watch-mempool': boolean; + 'track-bisq-market': string; } export interface VbytesPerSecond { diff --git a/frontend/src/app/bisq/bisq-address/bisq-address.component.ts b/frontend/src/app/bisq/bisq-address/bisq-address.component.ts index aded75d8e..75225d9de 100644 --- a/frontend/src/app/bisq/bisq-address/bisq-address.component.ts +++ b/frontend/src/app/bisq/bisq-address/bisq-address.component.ts @@ -5,6 +5,7 @@ import { ParamMap, ActivatedRoute } from '@angular/router'; import { Subscription, of } from 'rxjs'; import { BisqTransaction } from '../bisq.interfaces'; import { BisqApiService } from '../bisq-api.service'; +import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ selector: 'app-bisq-address', @@ -22,12 +23,15 @@ export class BisqAddressComponent implements OnInit, OnDestroy { totalSent = 0; constructor( + private websocketService: WebsocketService, private route: ActivatedRoute, private seoService: SeoService, private bisqApiService: BisqApiService, ) { } ngOnInit() { + this.websocketService.want(['blocks']); + this.mainSubscription = this.route.paramMap .pipe( switchMap((params: ParamMap) => { diff --git a/frontend/src/app/bisq/bisq-block/bisq-block.component.ts b/frontend/src/app/bisq/bisq-block/bisq-block.component.ts index d1cc3eeca..2510ee67f 100644 --- a/frontend/src/app/bisq/bisq-block/bisq-block.component.ts +++ b/frontend/src/app/bisq/bisq-block/bisq-block.component.ts @@ -8,6 +8,7 @@ import { switchMap, catchError } from 'rxjs/operators'; import { SeoService } from 'src/app/services/seo.service'; import { ElectrsApiService } from 'src/app/services/electrs-api.service'; import { HttpErrorResponse } from '@angular/common/http'; +import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ selector: 'app-bisq-block', @@ -23,6 +24,7 @@ export class BisqBlockComponent implements OnInit, OnDestroy { error: HttpErrorResponse | null; constructor( + private websocketService: WebsocketService, private bisqApiService: BisqApiService, private route: ActivatedRoute, private seoService: SeoService, @@ -32,6 +34,8 @@ export class BisqBlockComponent implements OnInit, OnDestroy { ) { } ngOnInit(): void { + this.websocketService.want(['blocks']); + this.subscription = this.route.paramMap .pipe( switchMap((params: ParamMap) => { diff --git a/frontend/src/app/bisq/bisq-blocks/bisq-blocks.component.ts b/frontend/src/app/bisq/bisq-blocks/bisq-blocks.component.ts index ee4108ae5..6ca90611e 100644 --- a/frontend/src/app/bisq/bisq-blocks/bisq-blocks.component.ts +++ b/frontend/src/app/bisq/bisq-blocks/bisq-blocks.component.ts @@ -5,6 +5,7 @@ import { Observable } from 'rxjs'; import { BisqBlock, BisqOutput, BisqTransaction } from '../bisq.interfaces'; import { SeoService } from 'src/app/services/seo.service'; import { ActivatedRoute, Router } from '@angular/router'; +import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ selector: 'app-bisq-blocks', @@ -25,6 +26,7 @@ export class BisqBlocksComponent implements OnInit { paginationMaxSize = 10; constructor( + private websocketService: WebsocketService, private bisqApiService: BisqApiService, private seoService: SeoService, private route: ActivatedRoute, @@ -32,6 +34,7 @@ export class BisqBlocksComponent implements OnInit { ) { } ngOnInit(): void { + this.websocketService.want(['blocks']); this.seoService.setTitle($localize`:@@8a7b4bd44c0ac71b2e72de0398b303257f7d2f54:Blocks`); this.itemsPerPage = Math.max(Math.round(this.contentSpace / this.fiveItemsPxSize) * 5, 10); this.loadingItems = Array(this.itemsPerPage); diff --git a/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts b/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts index 0fbe8b923..f9e19142d 100644 --- a/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts +++ b/frontend/src/app/bisq/bisq-dashboard/bisq-dashboard.component.ts @@ -1,6 +1,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { Observable, combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; +import { WebsocketService } from 'src/app/services/websocket.service'; import { BisqApiService } from '../bisq-api.service'; @Component({ @@ -13,10 +14,13 @@ export class BisqDashboardComponent implements OnInit { tickers$: Observable; constructor( + private websocketService: WebsocketService, private bisqApiService: BisqApiService, ) { } ngOnInit(): void { + this.websocketService.want(['blocks']); + this.tickers$ = combineLatest([ this.bisqApiService.getMarketsTicker$(), this.bisqApiService.getMarkets$(), diff --git a/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.html b/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.html deleted file mode 100644 index 0680b43f9..000000000 --- a/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.scss b/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.ts b/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.ts deleted file mode 100644 index bb9a37809..000000000 --- a/frontend/src/app/bisq/bisq-explorer/bisq-explorer.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { WebsocketService } from 'src/app/services/websocket.service'; - -@Component({ - selector: 'app-bisq-explorer', - templateUrl: './bisq-explorer.component.html', - styleUrls: ['./bisq-explorer.component.scss'] -}) -export class BisqExplorerComponent implements OnInit { - - constructor( - private websocketService: WebsocketService, - ) { } - - ngOnInit(): void { - this.websocketService.want(['blocks']); - } -} diff --git a/frontend/src/app/bisq/bisq-market/bisq-market.component.ts b/frontend/src/app/bisq/bisq-market/bisq-market.component.ts index 95eba7301..8fba629f6 100644 --- a/frontend/src/app/bisq/bisq-market/bisq-market.component.ts +++ b/frontend/src/app/bisq/bisq-market/bisq-market.component.ts @@ -1,8 +1,9 @@ -import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { combineLatest, merge, Observable, of } from 'rxjs'; import { filter, map, mergeAll, switchMap, tap } from 'rxjs/operators'; +import { WebsocketService } from 'src/app/services/websocket.service'; import { BisqApiService } from '../bisq-api.service'; @Component({ @@ -11,7 +12,7 @@ import { BisqApiService } from '../bisq-api.service'; styleUrls: ['./bisq-market.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class BisqMarketComponent implements OnInit { +export class BisqMarketComponent implements OnInit, OnDestroy { hlocData$: Observable; currency$: Observable; offers$: Observable; @@ -19,6 +20,7 @@ export class BisqMarketComponent implements OnInit { defaultInterval = 'half_hour'; constructor( + private websocketService: WebsocketService, private route: ActivatedRoute, private bisqApiService: BisqApiService, private formBuilder: FormBuilder, @@ -44,6 +46,7 @@ export class BisqMarketComponent implements OnInit { this.offers$ = this.route.paramMap .pipe( map(routeParams => routeParams.get('pair')), + tap((marketPair) => this.websocketService.startTrackBisqMarket(marketPair)), switchMap((marketPair) => this.bisqApiService.getMarketOffers$(marketPair)), map((offers) => { return offers[Object.keys(offers)[0]]; @@ -68,4 +71,8 @@ export class BisqMarketComponent implements OnInit { ); } + ngOnDestroy(): void { + this.websocketService.stopTrackingBisqMarket(); + } + } diff --git a/frontend/src/app/bisq/bisq-stats/bisq-stats.component.ts b/frontend/src/app/bisq/bisq-stats/bisq-stats.component.ts index 53f2051ae..11064b5fe 100644 --- a/frontend/src/app/bisq/bisq-stats/bisq-stats.component.ts +++ b/frontend/src/app/bisq/bisq-stats/bisq-stats.component.ts @@ -3,6 +3,7 @@ import { BisqApiService } from '../bisq-api.service'; import { BisqStats } from '../bisq.interfaces'; import { SeoService } from 'src/app/services/seo.service'; import { StateService } from 'src/app/services/state.service'; +import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ selector: 'app-bisq-stats', @@ -15,12 +16,15 @@ export class BisqStatsComponent implements OnInit { price: number; constructor( + private websocketService: WebsocketService, private bisqApiService: BisqApiService, private seoService: SeoService, private stateService: StateService, ) { } ngOnInit() { + this.websocketService.want(['blocks']); + this.seoService.setTitle($localize`:@@2a30a4cdb123a03facc5ab8c5b3e6d8b8dbbc3d4:BSQ statistics`); this.stateService.bsqPrice$ .subscribe((bsqPrice) => { diff --git a/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.ts b/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.ts index 2dd745762..d42b7d521 100644 --- a/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.ts +++ b/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.ts @@ -9,6 +9,7 @@ import { BisqApiService } from '../bisq-api.service'; import { SeoService } from 'src/app/services/seo.service'; import { ElectrsApiService } from 'src/app/services/electrs-api.service'; import { HttpErrorResponse } from '@angular/common/http'; +import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ selector: 'app-bisq-transaction', @@ -27,6 +28,7 @@ export class BisqTransactionComponent implements OnInit, OnDestroy { subscription: Subscription; constructor( + private websocketService: WebsocketService, private route: ActivatedRoute, private bisqApiService: BisqApiService, private electrsApiService: ElectrsApiService, @@ -36,6 +38,8 @@ export class BisqTransactionComponent implements OnInit, OnDestroy { ) { } ngOnInit(): void { + this.websocketService.want(['blocks']); + this.subscription = this.route.paramMap.pipe( switchMap((params: ParamMap) => { this.isLoading = true; diff --git a/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts b/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts index c46c8fdfa..6ced089e1 100644 --- a/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts +++ b/frontend/src/app/bisq/bisq-transactions/bisq-transactions.component.ts @@ -8,6 +8,7 @@ import { SeoService } from 'src/app/services/seo.service'; import { FormGroup, FormBuilder } from '@angular/forms'; import { Router, ActivatedRoute } from '@angular/router'; import { IMultiSelectOption, IMultiSelectSettings, IMultiSelectTexts } from 'ngx-bootrap-multiselect'; +import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ selector: 'app-bisq-transactions', @@ -65,6 +66,7 @@ export class BisqTransactionsComponent implements OnInit { 'PROOF_OF_BURN', 'PROPOSAL', 'REIMBURSEMENT_REQUEST', 'TRANSFER_BSQ', 'UNLOCK', 'VOTE_REVEAL', 'IRREGULAR']; constructor( + private websocketService: WebsocketService, private bisqApiService: BisqApiService, private seoService: SeoService, private formBuilder: FormBuilder, @@ -74,6 +76,7 @@ export class BisqTransactionsComponent implements OnInit { ) { } ngOnInit(): void { + this.websocketService.want(['blocks']); this.seoService.setTitle($localize`:@@add4cd82e3e38a3110fe67b3c7df56e9602644ee:Transactions`); this.radioGroupForm = this.formBuilder.group({ diff --git a/frontend/src/app/bisq/bisq.module.ts b/frontend/src/app/bisq/bisq.module.ts index b469b4076..6f245c639 100644 --- a/frontend/src/app/bisq/bisq.module.ts +++ b/frontend/src/app/bisq/bisq.module.ts @@ -17,7 +17,6 @@ import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontaweso import { faLeaf, faQuestion, faExclamationTriangle, faRocket, faRetweet, faFileAlt, faMoneyBill, faEye, faEyeSlash, faLock, faLockOpen, faExclamationCircle } from '@fortawesome/free-solid-svg-icons'; import { BisqBlocksComponent } from './bisq-blocks/bisq-blocks.component'; -import { BisqExplorerComponent } from './bisq-explorer/bisq-explorer.component'; import { BisqApiService } from './bisq-api.service'; import { BisqAddressComponent } from './bisq-address/bisq-address.component'; import { BisqStatsComponent } from './bisq-stats/bisq-stats.component'; @@ -33,7 +32,6 @@ import { BsqAmountComponent } from './bsq-amount/bsq-amount.component'; BisqTransactionDetailsComponent, BisqTransfersComponent, BisqBlocksComponent, - BisqExplorerComponent, BisqAddressComponent, BisqStatsComponent, BsqAmountComponent, diff --git a/frontend/src/app/bisq/bisq.routing.module.ts b/frontend/src/app/bisq/bisq.routing.module.ts index 3487ef48b..7794b61bd 100644 --- a/frontend/src/app/bisq/bisq.routing.module.ts +++ b/frontend/src/app/bisq/bisq.routing.module.ts @@ -5,7 +5,6 @@ import { BisqTransactionsComponent } from './bisq-transactions/bisq-transactions import { BisqTransactionComponent } from './bisq-transaction/bisq-transaction.component'; import { BisqBlockComponent } from './bisq-block/bisq-block.component'; import { BisqBlocksComponent } from './bisq-blocks/bisq-blocks.component'; -import { BisqExplorerComponent } from './bisq-explorer/bisq-explorer.component'; import { BisqAddressComponent } from './bisq-address/bisq-address.component'; import { BisqStatsComponent } from './bisq-stats/bisq-stats.component'; import { ApiDocsComponent } from '../components/api-docs/api-docs.component'; @@ -14,56 +13,50 @@ import { BisqMarketComponent } from './bisq-market/bisq-market.component'; const routes: Routes = [ { - path: '', - component: BisqExplorerComponent, - children: [ - { - path: '', - component: BisqDashboardComponent, - }, - { - path: 'transactions', - component: BisqTransactionsComponent - }, - { - path: 'market/:pair', - component: BisqMarketComponent, - }, - { - path: 'tx/:id', - component: BisqTransactionComponent - }, - { - path: 'blocks', - children: [], - component: BisqBlocksComponent - }, - { - path: 'block/:id', - component: BisqBlockComponent, - }, - { - path: 'address/:id', - component: BisqAddressComponent, - }, - { - path: 'stats', - component: BisqStatsComponent, - }, - { - path: 'about', - component: AboutComponent, - }, - { - path: 'api', - component: ApiDocsComponent, - }, - { - path: '**', - redirectTo: '' - } - ] - } + path: '', + component: BisqDashboardComponent, + }, + { + path: 'transactions', + component: BisqTransactionsComponent + }, + { + path: 'market/:pair', + component: BisqMarketComponent, + }, + { + path: 'tx/:id', + component: BisqTransactionComponent + }, + { + path: 'blocks', + children: [], + component: BisqBlocksComponent + }, + { + path: 'block/:id', + component: BisqBlockComponent, + }, + { + path: 'address/:id', + component: BisqAddressComponent, + }, + { + path: 'stats', + component: BisqStatsComponent, + }, + { + path: 'about', + component: AboutComponent, + }, + { + path: 'api', + component: ApiDocsComponent, + }, + { + path: '**', + redirectTo: '' + } ]; @NgModule({ diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts index 2a753b91f..f11cf7059 100644 --- a/frontend/src/app/interfaces/websocket.interface.ts +++ b/frontend/src/app/interfaces/websocket.interface.ts @@ -20,6 +20,7 @@ export interface WebsocketResponse { 'track-address'?: string; 'track-asset'?: string; 'watch-mempool'?: boolean; + 'track-bisq-market'?: string; } export interface MempoolBlock { diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts index 7c35e040d..3602a3d83 100644 --- a/frontend/src/app/services/websocket.service.ts +++ b/frontend/src/app/services/websocket.service.ts @@ -23,7 +23,7 @@ export class WebsocketService { private websocketSubject: WebSocketSubject; private goneOffline = false; - private lastWant: string[] | null = null; + private lastWant: string | null = null; private isTrackingTx = false; private latestGitCommit = ''; private onlineCheckTimeout: number; @@ -95,7 +95,7 @@ export class WebsocketService { if (this.goneOffline === true) { this.goneOffline = false; if (this.lastWant) { - this.want(this.lastWant, true); + this.want(JSON.parse(this.lastWant), true); } this.stateService.connectionState$.next(2); } @@ -150,6 +150,14 @@ export class WebsocketService { this.websocketSubject.next({ 'track-asset': 'stop' }); } + startTrackBisqMarket(market: string) { + this.websocketSubject.next({ 'track-bisq-market': market }); + } + + stopTrackingBisqMarket() { + this.websocketSubject.next({ 'track-bisq-market': 'stop' }); + } + fetchStatistics(historicalDate: string) { this.websocketSubject.next({ historicalDate }); } @@ -158,11 +166,11 @@ export class WebsocketService { if (!this.stateService.isBrowser) { return; } - if (data === this.lastWant && !force) { + if (JSON.stringify(data) === this.lastWant && !force) { return; } this.websocketSubject.next({action: 'want', data: data}); - this.lastWant = data; + this.lastWant = JSON.stringify(data); } goOffline() {