mirror of
https://github.com/mempool/mempool.git
synced 2024-11-20 10:21:52 +01:00
Merge pull request #517 from mempool/simon/bisq-address-prefix-search
Handle the 'B' prefix in the search bar autocomplete on /bisq
This commit is contained in:
commit
3ffa60db1f
@ -1,7 +1,7 @@
|
|||||||
<form [formGroup]="searchForm" (submit)="searchForm.valid && search()" novalidate>
|
<form [formGroup]="searchForm" (submit)="searchForm.valid && search()" novalidate>
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="search-box-container mr-2">
|
<div class="search-box-container mr-2">
|
||||||
<input #instance="ngbTypeahead" [ngbTypeahead]="typeaheadSearch" (selectItem)="itemSelected()" (focus)="focus$.next($any($event).target.value)" (click)="click$.next($any($event).target.value)" formControlName="searchText" type="text" class="form-control" i18n-placeholder="search-form.searchbar-placeholder" placeholder="TXID, block height, hash or address">
|
<input #instance="ngbTypeahead" [ngbTypeahead]="typeaheadSearchFn" (selectItem)="itemSelected()" (focus)="focus$.next($any($event).target.value)" (click)="click$.next($any($event).target.value)" formControlName="searchText" type="text" class="form-control" i18n-placeholder="search-form.searchbar-placeholder" placeholder="TXID, block height, hash or address">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button [disabled]="isSearching" type="submit" class="btn btn-block btn-primary"><fa-icon [icon]="['fas', 'search']" [fixedWidth]="true" i18n-title="search-form.search-title" title="Search"></fa-icon></button>
|
<button [disabled]="isSearching" type="submit" class="btn btn-block btn-primary"><fa-icon [icon]="['fas', 'search']" [fixedWidth]="true" i18n-title="search-form.search-title" title="Search"></fa-icon></button>
|
||||||
|
@ -4,7 +4,7 @@ import { Router } from '@angular/router';
|
|||||||
import { AssetsService } from 'src/app/services/assets.service';
|
import { AssetsService } from 'src/app/services/assets.service';
|
||||||
import { StateService } from 'src/app/services/state.service';
|
import { StateService } from 'src/app/services/state.service';
|
||||||
import { Observable, of, Subject, merge } from 'rxjs';
|
import { Observable, of, Subject, merge } from 'rxjs';
|
||||||
import { debounceTime, distinctUntilChanged, switchMap, filter, catchError } from 'rxjs/operators';
|
import { debounceTime, distinctUntilChanged, switchMap, filter, catchError, map } from 'rxjs/operators';
|
||||||
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
||||||
import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
@ -18,11 +18,12 @@ export class SearchFormComponent implements OnInit {
|
|||||||
network = '';
|
network = '';
|
||||||
assets: object = {};
|
assets: object = {};
|
||||||
isSearching = false;
|
isSearching = false;
|
||||||
|
typeaheadSearchFn: ((text: Observable<string>) => Observable<readonly any[]>);
|
||||||
|
|
||||||
searchForm: FormGroup;
|
searchForm: FormGroup;
|
||||||
@Output() searchTriggered = new EventEmitter();
|
@Output() searchTriggered = new EventEmitter();
|
||||||
|
|
||||||
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}|[bB]?[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]+$/;
|
regexBlockheight = /^[0-9]+$/;
|
||||||
@ -31,21 +32,6 @@ export class SearchFormComponent implements OnInit {
|
|||||||
focus$ = new Subject<string>();
|
focus$ = new Subject<string>();
|
||||||
click$ = new Subject<string>();
|
click$ = new Subject<string>();
|
||||||
|
|
||||||
typeaheadSearch = (text$: Observable<string>) => {
|
|
||||||
const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged());
|
|
||||||
const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.instance.isPopupOpen()));
|
|
||||||
const inputFocus$ = this.focus$;
|
|
||||||
|
|
||||||
return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$)
|
|
||||||
.pipe(
|
|
||||||
switchMap((text) => {
|
|
||||||
if (!text.length) { return of([]); }
|
|
||||||
return this.electrsApiService.getAddressesByPrefix$(text)
|
|
||||||
.pipe(catchError(() => of([])));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
@ -55,11 +41,13 @@ export class SearchFormComponent implements OnInit {
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.typeaheadSearchFn = this.typeaheadSearch;
|
||||||
this.stateService.networkChanged$.subscribe((network) => this.network = network);
|
this.stateService.networkChanged$.subscribe((network) => this.network = network);
|
||||||
|
|
||||||
this.searchForm = this.formBuilder.group({
|
this.searchForm = this.formBuilder.group({
|
||||||
searchText: ['', Validators.required],
|
searchText: ['', Validators.required],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.network === 'liquid') {
|
if (this.network === 'liquid') {
|
||||||
this.assetsService.getAssetsMinimalJson$
|
this.assetsService.getAssetsMinimalJson$
|
||||||
.subscribe((assets) => {
|
.subscribe((assets) => {
|
||||||
@ -68,6 +56,37 @@ export class SearchFormComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typeaheadSearch = (text$: Observable<string>) => {
|
||||||
|
const debouncedText$ = text$.pipe(
|
||||||
|
map((text) => {
|
||||||
|
if (this.network === 'bisq' && text.match(/^(b)[^c]/i)) {
|
||||||
|
return text.substr(1);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}),
|
||||||
|
debounceTime(200),
|
||||||
|
distinctUntilChanged()
|
||||||
|
);
|
||||||
|
const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.instance.isPopupOpen()));
|
||||||
|
const inputFocus$ = this.focus$;
|
||||||
|
|
||||||
|
return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$)
|
||||||
|
.pipe(
|
||||||
|
switchMap((text) => {
|
||||||
|
if (!text.length) {
|
||||||
|
return of([]);
|
||||||
|
}
|
||||||
|
return this.electrsApiService.getAddressesByPrefix$(text).pipe(catchError(() => of([])));
|
||||||
|
}),
|
||||||
|
map((result: string[]) => {
|
||||||
|
if (this.network === 'bisq') {
|
||||||
|
return result.map((address: string) => 'B' + address);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
itemSelected() {
|
itemSelected() {
|
||||||
setTimeout(() => this.search());
|
setTimeout(() => this.search());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user