2022-05-15 14:47:55 +04:00
|
|
|
import { Component, OnInit, ChangeDetectionStrategy, EventEmitter, Output, ViewChild, HostListener } from '@angular/core';
|
2020-02-16 22:15:07 +07:00
|
|
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|
|
|
import { Router } from '@angular/router';
|
2020-05-02 12:36:35 +07:00
|
|
|
import { AssetsService } from 'src/app/services/assets.service';
|
2020-05-09 20:37:50 +07:00
|
|
|
import { StateService } from 'src/app/services/state.service';
|
2022-05-15 14:47:55 +04:00
|
|
|
import { Observable, of, Subject, merge, zip } from 'rxjs';
|
2021-05-13 03:01:47 +04:00
|
|
|
import { debounceTime, distinctUntilChanged, switchMap, filter, catchError, map } from 'rxjs/operators';
|
2020-07-24 22:37:35 +07:00
|
|
|
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
2021-12-30 02:30:46 +04:00
|
|
|
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
2022-05-15 14:47:55 +04:00
|
|
|
import { ApiService } from 'src/app/services/api.service';
|
|
|
|
import { SearchResultsComponent } from './search-results/search-results.component';
|
2020-02-16 22:15:07 +07:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-search-form',
|
|
|
|
templateUrl: './search-form.component.html',
|
|
|
|
styleUrls: ['./search-form.component.scss'],
|
2022-05-15 14:47:55 +04:00
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
2020-02-16 22:15:07 +07:00
|
|
|
})
|
|
|
|
export class SearchFormComponent implements OnInit {
|
2020-05-09 20:37:50 +07:00
|
|
|
network = '';
|
2020-05-28 01:01:35 +07:00
|
|
|
assets: object = {};
|
2020-11-22 16:03:23 +07:00
|
|
|
isSearching = false;
|
2022-05-15 14:47:55 +04:00
|
|
|
typeAhead$: Observable<any>;
|
2020-02-16 22:15:07 +07:00
|
|
|
searchForm: FormGroup;
|
|
|
|
|
2021-09-04 23:21:15 +04:00
|
|
|
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,100}|[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100})$/;
|
2021-07-06 19:55:01 +03:00
|
|
|
regexBlockhash = /^[0]{8}[a-fA-F0-9]{56}$/;
|
2021-10-19 23:24:12 +04:00
|
|
|
regexTransaction = /^([a-fA-F0-9]{64}):?(\d+)?$/;
|
2020-05-10 14:32:27 +07:00
|
|
|
regexBlockheight = /^[0-9]+$/;
|
2020-07-24 22:37:35 +07:00
|
|
|
focus$ = new Subject<string>();
|
|
|
|
click$ = new Subject<string>();
|
|
|
|
|
2022-05-15 14:47:55 +04:00
|
|
|
@Output() searchTriggered = new EventEmitter();
|
|
|
|
@ViewChild('searchResults') searchResults: SearchResultsComponent;
|
|
|
|
@HostListener('keydown', ['$event']) keydown($event) {
|
|
|
|
this.handleKeyDown($event);
|
|
|
|
}
|
2022-02-27 18:53:16 +03:00
|
|
|
|
2020-02-16 22:15:07 +07:00
|
|
|
constructor(
|
|
|
|
private formBuilder: FormBuilder,
|
|
|
|
private router: Router,
|
2020-05-02 12:36:35 +07:00
|
|
|
private assetsService: AssetsService,
|
2020-05-09 20:37:50 +07:00
|
|
|
private stateService: StateService,
|
2020-07-24 22:37:35 +07:00
|
|
|
private electrsApiService: ElectrsApiService,
|
2022-05-15 14:47:55 +04:00
|
|
|
private apiService: ApiService,
|
2021-12-30 02:30:46 +04:00
|
|
|
private relativeUrlPipe: RelativeUrlPipe,
|
2020-02-16 22:15:07 +07:00
|
|
|
) { }
|
|
|
|
|
|
|
|
ngOnInit() {
|
2020-05-09 20:37:50 +07:00
|
|
|
this.stateService.networkChanged$.subscribe((network) => this.network = network);
|
|
|
|
|
2020-02-16 22:15:07 +07:00
|
|
|
this.searchForm = this.formBuilder.group({
|
|
|
|
searchText: ['', Validators.required],
|
|
|
|
});
|
2021-05-13 03:01:47 +04:00
|
|
|
|
2021-12-27 22:54:45 +04:00
|
|
|
if (this.network === 'liquid' || this.network === 'liquidtestnet') {
|
2020-05-05 15:26:23 +07:00
|
|
|
this.assetsService.getAssetsMinimalJson$
|
|
|
|
.subscribe((assets) => {
|
|
|
|
this.assets = assets;
|
|
|
|
});
|
|
|
|
}
|
2020-02-16 22:15:07 +07:00
|
|
|
|
2022-05-15 14:47:55 +04:00
|
|
|
this.typeAhead$ = this.searchForm.get('searchText').valueChanges
|
2021-05-13 03:01:47 +04:00
|
|
|
.pipe(
|
2022-05-15 14:47:55 +04:00
|
|
|
map((text) => {
|
|
|
|
if (this.network === 'bisq' && text.match(/^(b)[^c]/i)) {
|
|
|
|
return text.substr(1);
|
|
|
|
}
|
2022-05-15 19:22:14 +04:00
|
|
|
return text.trim();
|
2022-05-15 14:47:55 +04:00
|
|
|
}),
|
2022-05-15 19:22:14 +04:00
|
|
|
debounceTime(250),
|
2022-05-15 14:47:55 +04:00
|
|
|
distinctUntilChanged(),
|
2021-05-13 03:01:47 +04:00
|
|
|
switchMap((text) => {
|
|
|
|
if (!text.length) {
|
2022-05-15 14:47:55 +04:00
|
|
|
return of([
|
|
|
|
[],
|
|
|
|
{
|
|
|
|
nodes: [],
|
|
|
|
channels: [],
|
|
|
|
}
|
|
|
|
]);
|
2021-05-13 03:01:47 +04:00
|
|
|
}
|
2022-05-15 14:47:55 +04:00
|
|
|
return zip(
|
|
|
|
this.electrsApiService.getAddressesByPrefix$(text).pipe(catchError(() => of([]))),
|
2022-05-15 19:22:14 +04:00
|
|
|
this.apiService.lightningSearch$(text).pipe(catchError(() => of({
|
|
|
|
nodes: [],
|
|
|
|
channels: [],
|
|
|
|
}))),
|
2022-05-15 14:47:55 +04:00
|
|
|
);
|
2021-05-13 03:01:47 +04:00
|
|
|
}),
|
2022-05-15 14:47:55 +04:00
|
|
|
map((result: any[]) => {
|
2021-05-13 03:01:47 +04:00
|
|
|
if (this.network === 'bisq') {
|
2022-05-15 14:47:55 +04:00
|
|
|
return result[0].map((address: string) => 'B' + address);
|
2021-05-13 03:01:47 +04:00
|
|
|
}
|
2022-05-15 14:47:55 +04:00
|
|
|
return {
|
|
|
|
addresses: result[0],
|
|
|
|
nodes: result[1].nodes,
|
|
|
|
channels: result[1].channels,
|
|
|
|
totalResults: result[0].length + result[1].nodes.length + result[1].channels.length,
|
|
|
|
};
|
2021-05-13 03:01:47 +04:00
|
|
|
})
|
|
|
|
);
|
2022-05-15 14:47:55 +04:00
|
|
|
}
|
|
|
|
handleKeyDown($event) {
|
|
|
|
this.searchResults.handleKeyDown($event);
|
|
|
|
}
|
2021-05-13 03:01:47 +04:00
|
|
|
|
2020-07-25 17:52:41 +07:00
|
|
|
itemSelected() {
|
|
|
|
setTimeout(() => this.search());
|
|
|
|
}
|
|
|
|
|
2022-05-15 14:47:55 +04:00
|
|
|
selectedResult(result: any) {
|
|
|
|
if (typeof result === 'string') {
|
2022-05-26 18:23:57 +04:00
|
|
|
this.search();
|
2022-05-15 14:47:55 +04:00
|
|
|
} else if (result.alias) {
|
|
|
|
this.navigate('/lightning/node/', result.public_key);
|
|
|
|
} else if (result.short_id) {
|
|
|
|
this.navigate('/lightning/channel/', result.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-16 22:15:07 +07:00
|
|
|
search() {
|
2021-09-02 00:57:43 +09:00
|
|
|
const searchText = this.searchForm.value.searchText.trim();
|
2020-02-16 22:15:07 +07:00
|
|
|
if (searchText) {
|
2020-11-22 16:03:23 +07:00
|
|
|
this.isSearching = true;
|
2020-02-16 22:15:07 +07:00
|
|
|
if (this.regexAddress.test(searchText)) {
|
2021-07-06 19:55:01 +03:00
|
|
|
this.navigate('/address/', searchText);
|
|
|
|
} else if (this.regexBlockhash.test(searchText) || this.regexBlockheight.test(searchText)) {
|
2020-11-22 16:03:23 +07:00
|
|
|
this.navigate('/block/', searchText);
|
2020-02-19 23:50:23 +07:00
|
|
|
} else if (this.regexTransaction.test(searchText)) {
|
2021-10-19 23:24:12 +04:00
|
|
|
const matches = this.regexTransaction.exec(searchText);
|
2021-12-27 22:54:45 +04:00
|
|
|
if (this.network === 'liquid' || this.network === 'liquidtestnet') {
|
2021-10-19 23:24:12 +04:00
|
|
|
if (this.assets[matches[1]]) {
|
2022-02-06 18:06:51 +04:00
|
|
|
this.navigate('/assets/asset/', matches[1]);
|
2020-11-22 16:03:23 +07:00
|
|
|
}
|
2021-10-19 23:24:12 +04:00
|
|
|
this.electrsApiService.getAsset$(matches[1])
|
2020-11-22 16:03:23 +07:00
|
|
|
.subscribe(
|
2022-02-06 18:06:51 +04:00
|
|
|
() => { this.navigate('/assets/asset/', matches[1]); },
|
2021-09-25 14:37:54 +04:00
|
|
|
() => {
|
2021-10-19 23:24:12 +04:00
|
|
|
this.electrsApiService.getBlock$(matches[1])
|
2021-09-25 14:37:54 +04:00
|
|
|
.subscribe(
|
2021-10-19 23:24:12 +04:00
|
|
|
(block) => { this.navigate('/block/', matches[1], { state: { data: { block } } }); },
|
|
|
|
() => { this.navigate('/tx/', matches[0]); });
|
2021-09-25 14:37:54 +04:00
|
|
|
}
|
2020-11-22 16:03:23 +07:00
|
|
|
);
|
2020-05-02 12:36:35 +07:00
|
|
|
} else {
|
2021-10-19 23:24:12 +04:00
|
|
|
this.navigate('/tx/', matches[0]);
|
2020-05-02 12:36:35 +07:00
|
|
|
}
|
2020-02-19 23:50:23 +07:00
|
|
|
} else {
|
2020-11-22 16:03:23 +07:00
|
|
|
this.isSearching = false;
|
2020-02-16 22:15:07 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-22 16:03:23 +07:00
|
|
|
|
2021-09-25 14:37:54 +04:00
|
|
|
navigate(url: string, searchText: string, extras?: any) {
|
2021-12-30 02:30:46 +04:00
|
|
|
this.router.navigate([this.relativeUrlPipe.transform(url), searchText], extras);
|
2020-11-22 16:03:23 +07:00
|
|
|
this.searchTriggered.emit();
|
|
|
|
this.searchForm.setValue({
|
|
|
|
searchText: '',
|
|
|
|
});
|
|
|
|
this.isSearching = false;
|
|
|
|
}
|
2020-02-16 22:15:07 +07:00
|
|
|
}
|