From a1f1b09c55f762490cf848328c97cf2308a06639 Mon Sep 17 00:00:00 2001 From: natsoni Date: Wed, 26 Jun 2024 11:13:32 +0900 Subject: [PATCH 1/5] Fix loading indicator when changing page --- .../accelerations-list/accelerations-list.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts index 237b14317..e25c87bb8 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts @@ -44,6 +44,7 @@ export class AccelerationsListComponent implements OnInit, OnDestroy { this.accelerationList$ = this.pageSubject.pipe( switchMap((page) => { + this.isLoading = true; const accelerationObservable$ = this.accelerations$ || (this.pending ? this.stateService.liveAccelerations$ : this.servicesApiService.getAccelerationHistoryObserveResponse$({ page: page })); if (!this.accelerations$ && this.pending) { this.websocketService.ensureTrackAccelerations(); From fc8f8abc7ec049ce2c78f0112f4ff16555369fc5 Mon Sep 17 00:00:00 2001 From: natsoni Date: Wed, 26 Jun 2024 11:42:22 +0900 Subject: [PATCH 2/5] Add SEO title to Accelerations page --- .../accelerations-list/accelerations-list.component.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts index e25c87bb8..06887cc9c 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts @@ -4,6 +4,7 @@ import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interf import { StateService } from '../../../services/state.service'; import { WebsocketService } from '../../../services/websocket.service'; import { ServicesApiServices } from '../../../services/services-api.service'; +import { SeoService } from '../../../services/seo.service'; @Component({ selector: 'app-accelerations-list', @@ -31,12 +32,14 @@ export class AccelerationsListComponent implements OnInit, OnDestroy { private websocketService: WebsocketService, public stateService: StateService, private cd: ChangeDetectorRef, + private seoService: SeoService, ) { } ngOnInit(): void { if (!this.widget) { this.websocketService.want(['blocks']); + this.seoService.setTitle($localize`:@@02573b6980a2d611b4361a2595a4447e390058cd:Accelerations`); } this.skeletonLines = this.widget === true ? [...Array(6).keys()] : [...Array(15).keys()]; From 7b6246a0354df6289fd55162ad4fec65ea8e75d6 Mon Sep 17 00:00:00 2001 From: natsoni Date: Wed, 26 Jun 2024 14:20:49 +0900 Subject: [PATCH 3/5] Fix loading state in blocks table issue --- .../src/app/components/blocks-list/blocks-list.component.ts | 4 +++- .../recent-pegs-list/recent-pegs-list.component.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.ts b/frontend/src/app/components/blocks-list/blocks-list.component.ts index 29b23e608..4903499bc 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.ts +++ b/frontend/src/app/components/blocks-list/blocks-list.component.ts @@ -85,15 +85,16 @@ export class BlocksList implements OnInit { this.keyNavigationSubscription = this.stateService.keyNavigation$ .pipe( tap((event) => { - this.isLoading = true; const prevKey = this.dir === 'ltr' ? 'ArrowLeft' : 'ArrowRight'; const nextKey = this.dir === 'ltr' ? 'ArrowRight' : 'ArrowLeft'; if (event.key === prevKey && this.page > 1) { this.page--; + this.isLoading = true; this.cd.markForCheck(); } if (event.key === nextKey && this.page * 15 < this.blocksCount) { this.page++; + this.isLoading = true; this.cd.markForCheck(); } }), @@ -118,6 +119,7 @@ export class BlocksList implements OnInit { if (this.blocksCount === undefined) { this.blocksCount = blocks[0].height + 1; this.blocksCountInitialized$.next(true); + this.blocksCountInitialized$.complete(); } this.isLoading = false; this.lastBlockHeight = Math.max(...blocks.map(o => o.height)); diff --git a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts index b818dff78..0e2a003af 100644 --- a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts +++ b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts @@ -76,15 +76,16 @@ export class RecentPegsListComponent implements OnInit { this.keyNavigationSubscription = this.stateService.keyNavigation$ .pipe( tap((event) => { - this.isLoading = true; const prevKey = this.dir === 'ltr' ? 'ArrowLeft' : 'ArrowRight'; const nextKey = this.dir === 'ltr' ? 'ArrowRight' : 'ArrowLeft'; if (event.key === prevKey && this.page > 1) { this.page--; + this.isLoading = true; this.cd.markForCheck(); } if (event.key === nextKey && this.page < this.pegsCount / this.pageSize) { this.page++; + this.isLoading = true; this.cd.markForCheck(); } }), From 09f7dddf1469ade02653c86beb933fb73331e675 Mon Sep 17 00:00:00 2001 From: natsoni Date: Wed, 26 Jun 2024 15:09:52 +0900 Subject: [PATCH 4/5] Use url parameter instead of query parameter --- .../app/components/blocks-list/blocks-list.component.ts | 5 ++--- .../recent-pegs-list/recent-pegs-list.component.ts | 8 ++++---- frontend/src/app/liquid/liquid-master-page.module.ts | 6 +++++- frontend/src/app/master-page.module.ts | 6 +++++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.ts b/frontend/src/app/components/blocks-list/blocks-list.component.ts index 4903499bc..9bf4e9814 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.ts +++ b/frontend/src/app/components/blocks-list/blocks-list.component.ts @@ -73,12 +73,11 @@ export class BlocksList implements OnInit { this.seoService.setDescription($localize`:@@meta.description.bitcoin.blocks:See the most recent Bitcoin${seoDescriptionNetwork(this.stateService.network)} blocks along with basic stats such as block height, block reward, block size, and more.`); } - this.blocksCountInitializedSubscription = combineLatest([this.blocksCountInitialized$, this.route.queryParams]).pipe( + this.blocksCountInitializedSubscription = combineLatest([this.blocksCountInitialized$, this.route.params]).pipe( filter(([blocksCountInitialized, _]) => blocksCountInitialized), tap(([_, params]) => { this.page = +params['page'] || 1; this.page === 1 ? this.fromHeightSubject.next(undefined) : this.fromHeightSubject.next((this.blocksCount - 1) - (this.page - 1) * 15); - this.cd.markForCheck(); }) ).subscribe(); @@ -181,7 +180,7 @@ export class BlocksList implements OnInit { } pageChange(page: number): void { - this.router.navigate([], { queryParams: { page: page } }); + this.router.navigate(['blocks', page]); } trackByBlock(index: number, block: BlockExtended): number { diff --git a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts index 0e2a003af..31a52fd9d 100644 --- a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts +++ b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.ts @@ -36,7 +36,7 @@ export class RecentPegsListComponent implements OnInit { lastPegBlockUpdate: number = 0; lastPegAmount: string = ''; isLoad: boolean = true; - queryParamSubscription: Subscription; + paramSubscription: Subscription; keyNavigationSubscription: Subscription; dir: 'rtl' | 'ltr' = 'ltr'; @@ -66,7 +66,7 @@ export class RecentPegsListComponent implements OnInit { this.seoService.setTitle($localize`:@@a8b0889ea1b41888f1e247f2731cc9322198ca04:Recent Peg-In / Out's`); this.websocketService.want(['blocks']); - this.queryParamSubscription = this.route.queryParams.pipe( + this.paramSubscription = this.route.params.pipe( tap((params) => { this.page = +params['page'] || 1; this.startingIndexSubject.next((this.page - 1) * 15); @@ -173,12 +173,12 @@ export class RecentPegsListComponent implements OnInit { ngOnDestroy(): void { this.destroy$.next(1); this.destroy$.complete(); - this.queryParamSubscription?.unsubscribe(); + this.paramSubscription?.unsubscribe(); this.keyNavigationSubscription?.unsubscribe(); } pageChange(page: number): void { - this.router.navigate([], { queryParams: { page: page } }); + this.router.navigate(['audit', 'pegs', page]); } } diff --git a/frontend/src/app/liquid/liquid-master-page.module.ts b/frontend/src/app/liquid/liquid-master-page.module.ts index 5df9a5447..3375a066a 100644 --- a/frontend/src/app/liquid/liquid-master-page.module.ts +++ b/frontend/src/app/liquid/liquid-master-page.module.ts @@ -84,10 +84,14 @@ const routes: Routes = [ ] }, { - path: 'audit/pegs', + path: 'audit/pegs/:page', data: { networks: ['liquid'] }, component: RecentPegsListComponent, }, + { + path: 'audit/pegs', + redirectTo: 'audit/pegs/1' + }, { path: 'assets', data: { networks: ['liquid'] }, diff --git a/frontend/src/app/master-page.module.ts b/frontend/src/app/master-page.module.ts index 6ea8bfd93..510756cbc 100644 --- a/frontend/src/app/master-page.module.ts +++ b/frontend/src/app/master-page.module.ts @@ -45,9 +45,13 @@ const routes: Routes = [ loadChildren: () => import('./components/about/about.module').then(m => m.AboutModule), }, { - path: 'blocks', + path: 'blocks/:page', component: BlocksList, }, + { + path: 'blocks', + redirectTo: 'blocks/1', + }, { path: 'rbf', component: RbfList, From 122b4b05c4c3d1f308fdbcf1fe929dc11efb84d3 Mon Sep 17 00:00:00 2001 From: natsoni Date: Wed, 26 Jun 2024 15:37:39 +0900 Subject: [PATCH 5/5] Add pagination in URL to accelerations table --- .../accelerations-list.component.ts | 45 +++++++++++++++++-- .../src/app/graphs/graphs.routing.module.ts | 6 ++- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts index 06887cc9c..f6224c17d 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, ChangeDetectionStrategy, Input, ChangeDetectorRef, OnDestroy } from '@angular/core'; -import { BehaviorSubject, Observable, catchError, of, switchMap, tap } from 'rxjs'; +import { Component, OnInit, ChangeDetectionStrategy, Input, ChangeDetectorRef, OnDestroy, Inject, LOCALE_ID } from '@angular/core'; +import { BehaviorSubject, Observable, Subscription, catchError, of, switchMap, tap, throttleTime } from 'rxjs'; import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface'; import { StateService } from '../../../services/state.service'; import { WebsocketService } from '../../../services/websocket.service'; import { ServicesApiServices } from '../../../services/services-api.service'; import { SeoService } from '../../../services/seo.service'; +import { ActivatedRoute, Router } from '@angular/router'; @Component({ selector: 'app-accelerations-list', @@ -26,6 +27,9 @@ export class AccelerationsListComponent implements OnInit, OnDestroy { maxSize = window.innerWidth <= 767.98 ? 3 : 5; skeletonLines: number[] = []; pageSubject: BehaviorSubject = new BehaviorSubject(this.page); + keyNavigationSubscription: Subscription; + dir: 'rtl' | 'ltr' = 'ltr'; + paramSubscription: Subscription; constructor( private servicesApiService: ServicesApiServices, @@ -33,7 +37,13 @@ export class AccelerationsListComponent implements OnInit, OnDestroy { public stateService: StateService, private cd: ChangeDetectorRef, private seoService: SeoService, + private route: ActivatedRoute, + private router: Router, + @Inject(LOCALE_ID) private locale: string, ) { + if (this.locale.startsWith('ar') || this.locale.startsWith('fa') || this.locale.startsWith('he')) { + this.dir = 'rtl'; + } } ngOnInit(): void { @@ -45,6 +55,13 @@ export class AccelerationsListComponent implements OnInit, OnDestroy { this.skeletonLines = this.widget === true ? [...Array(6).keys()] : [...Array(15).keys()]; this.paginationMaxSize = window.matchMedia('(max-width: 670px)').matches ? 3 : 5; + this.paramSubscription = this.route.params.pipe( + tap(params => { + this.page = +params['page'] || 1; + this.pageSubject.next(this.page); + }) + ).subscribe(); + this.accelerationList$ = this.pageSubject.pipe( switchMap((page) => { this.isLoading = true; @@ -83,10 +100,30 @@ export class AccelerationsListComponent implements OnInit, OnDestroy { ); }) ); + + this.keyNavigationSubscription = this.stateService.keyNavigation$.pipe( + tap((event) => { + const prevKey = this.dir === 'ltr' ? 'ArrowLeft' : 'ArrowRight'; + const nextKey = this.dir === 'ltr' ? 'ArrowRight' : 'ArrowLeft'; + if (event.key === prevKey && this.page > 1) { + this.page--; + this.isLoading = true; + this.cd.markForCheck(); + } + if (event.key === nextKey && this.page * 15 < this.accelerationCount) { + this.page++; + this.isLoading = true; + this.cd.markForCheck(); + } + }), + throttleTime(1000, undefined, { leading: true, trailing: true }), + ).subscribe(() => { + this.pageChange(this.page); + }); } pageChange(page: number): void { - this.pageSubject.next(page); + this.router.navigate(['acceleration', 'list', page]); } trackByBlock(index: number, block: BlockExtended): number { @@ -95,5 +132,7 @@ export class AccelerationsListComponent implements OnInit, OnDestroy { ngOnDestroy(): void { this.websocketService.stopTrackAccelerations(); + this.paramSubscription?.unsubscribe(); + this.keyNavigationSubscription?.unsubscribe(); } } \ No newline at end of file diff --git a/frontend/src/app/graphs/graphs.routing.module.ts b/frontend/src/app/graphs/graphs.routing.module.ts index 64ccb299f..dd3535f65 100644 --- a/frontend/src/app/graphs/graphs.routing.module.ts +++ b/frontend/src/app/graphs/graphs.routing.module.ts @@ -60,10 +60,14 @@ const routes: Routes = [ ] }, { - path: 'acceleration/list', + path: 'acceleration/list/:page', data: { networks: ['bitcoin'] }, component: AccelerationsListComponent, }, + { + path: 'acceleration/list', + redirectTo: 'acceleration/list/1', + }, { path: 'mempool-block/:id', data: { networks: ['bitcoin', 'liquid'] },