Allow search and navigate by block height.

fixes #41
This commit is contained in:
softsimon 2020-05-10 14:32:27 +07:00
parent 756caf2c53
commit 9b4e5194c1
No known key found for this signature in database
GPG key ID: 488D7DCFB5A430D7
3 changed files with 29 additions and 3 deletions

View file

@ -1,5 +1,6 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router'; import { Location } from '@angular/common';
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { ElectrsApiService } from '../../services/electrs-api.service'; import { ElectrsApiService } from '../../services/electrs-api.service';
import { switchMap, tap, debounceTime, catchError } from 'rxjs/operators'; import { switchMap, tap, debounceTime, catchError } from 'rxjs/operators';
import { Block, Transaction, Vout } from '../../interfaces/electrs.interface'; import { Block, Transaction, Vout } from '../../interfaces/electrs.interface';
@ -27,6 +28,8 @@ export class BlockComponent implements OnInit, OnDestroy {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private location: Location,
private router: Router,
private electrsApiService: ElectrsApiService, private electrsApiService: ElectrsApiService,
private stateService: StateService, private stateService: StateService,
private seoService: SeoService, private seoService: SeoService,
@ -38,6 +41,7 @@ export class BlockComponent implements OnInit, OnDestroy {
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
const blockHash: string = params.get('id') || ''; const blockHash: string = params.get('id') || '';
this.block = undefined; this.block = undefined;
let isBlockHeight = false;
this.error = undefined; this.error = undefined;
this.fees = undefined; this.fees = undefined;
@ -45,7 +49,11 @@ export class BlockComponent implements OnInit, OnDestroy {
this.blockHeight = history.state.data.blockHeight; this.blockHeight = history.state.data.blockHeight;
} }
this.blockHash = blockHash; if (/^[0-9]+$/.test(blockHash)) {
isBlockHeight = true;
} else {
this.blockHash = blockHash;
}
document.body.scrollTo(0, 0); document.body.scrollTo(0, 0);
if (history.state.data && history.state.data.block) { if (history.state.data && history.state.data.block) {
@ -53,6 +61,19 @@ export class BlockComponent implements OnInit, OnDestroy {
return of(history.state.data.block); return of(history.state.data.block);
} else { } else {
this.isLoadingBlock = true; this.isLoadingBlock = true;
if (isBlockHeight) {
return this.electrsApiService.getBlockHashFromHeight$(parseInt(blockHash, 10))
.pipe(
switchMap((hash) => {
this.blockHash = hash;
this.location.replaceState(
this.router.createUrlTree([(this.network ? '/' + this.network : '') + '/block/', hash]).toString()
);
return this.electrsApiService.getBlock$(hash);
})
);
}
return this.electrsApiService.getBlock$(blockHash); return this.electrsApiService.getBlock$(blockHash);
} }
}), }),

View file

@ -20,6 +20,7 @@ export class SearchFormComponent implements OnInit {
regexAddress = /^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[a-z]{2,5}1[ac-hj-np-z02-9]{8,87})$/; regexAddress = /^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[a-z]{2,5}1[ac-hj-np-z02-9]{8,87})$/;
regexBlockhash = /^[0]{8}[a-fA-F0-9]{56}$/; regexBlockhash = /^[0]{8}[a-fA-F0-9]{56}$/;
regexTransaction = /^[a-fA-F0-9]{64}$/; regexTransaction = /^[a-fA-F0-9]{64}$/;
regexBlockheight = /^[0-9]+$/;
constructor( constructor(
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
@ -48,7 +49,7 @@ export class SearchFormComponent implements OnInit {
if (this.regexAddress.test(searchText)) { if (this.regexAddress.test(searchText)) {
this.router.navigate([(this.network ? '/' + this.network : '') + '/address/', searchText]); this.router.navigate([(this.network ? '/' + this.network : '') + '/address/', searchText]);
this.searchTriggered.emit(); this.searchTriggered.emit();
} else if (this.regexBlockhash.test(searchText)) { } else if (this.regexBlockhash.test(searchText) || this.regexBlockheight.test(searchText)) {
this.router.navigate([(this.network ? '/' + this.network : '') + '/block/', searchText]); this.router.navigate([(this.network ? '/' + this.network : '') + '/block/', searchText]);
this.searchTriggered.emit(); this.searchTriggered.emit();
} else if (this.regexTransaction.test(searchText)) { } else if (this.regexTransaction.test(searchText)) {

View file

@ -50,6 +50,10 @@ export class ElectrsApiService {
return this.httpClient.get<Transaction[]>(this.apiBaseUrl + '/block/' + hash + '/txs/' + index); return this.httpClient.get<Transaction[]>(this.apiBaseUrl + '/block/' + hash + '/txs/' + index);
} }
getBlockHashFromHeight$(height: number): Observable<string> {
return this.httpClient.get(this.apiBaseUrl + '/block-height/' + height, {responseType: 'text'});
}
getAddress$(address: string): Observable<Address> { getAddress$(address: string): Observable<Address> {
return this.httpClient.get<Address>(this.apiBaseUrl + '/address/' + address); return this.httpClient.get<Address>(this.apiBaseUrl + '/address/' + address);
} }