Merge branch 'upstream/master' into search-bar-network-regex

This commit is contained in:
natsee
2023-12-30 19:18:49 +01:00
476 changed files with 121475 additions and 73248 deletions

View File

@@ -1,6 +1,6 @@
import { Component, OnInit, ChangeDetectionStrategy, EventEmitter, Output, ViewChild, HostListener, ElementRef } from '@angular/core';
import { Component, OnInit, ChangeDetectionStrategy, EventEmitter, Output, ViewChild, HostListener, ElementRef, Input } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { EventType, NavigationStart, Router } from '@angular/router';
import { AssetsService } from '../../services/assets.service';
import { StateService } from '../../services/state.service';
import { Observable, of, Subject, zip, BehaviorSubject, combineLatest } from 'rxjs';
@@ -18,6 +18,8 @@ import { findOtherNetworks, getRegex } from '../../shared/regex.utils';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SearchFormComponent implements OnInit {
@Input() hamburgerOpen = false;
network = '';
assets: object = {};
isSearching = false;
@@ -39,6 +41,8 @@ export class SearchFormComponent implements OnInit {
regexBlockhash = getRegex('blockhash');
regexTransaction = getRegex('transaction');
regexBlockheight = getRegex('blockheight');
regexDate = /^(?:\d{4}[-/]\d{1,2}[-/]\d{1,2}(?: \d{1,2}:\d{2})?)$/;
regexUnixTimestamp = /^\d{10}$/;
focus$ = new Subject<string>();
click$ = new Subject<string>();
@@ -49,6 +53,8 @@ export class SearchFormComponent implements OnInit {
this.handleKeyDown($event);
}
@ViewChild('searchInput') searchInput: ElementRef;
constructor(
private formBuilder: UntypedFormBuilder,
private router: Router,
@@ -57,17 +63,31 @@ export class SearchFormComponent implements OnInit {
private electrsApiService: ElectrsApiService,
private apiService: ApiService,
private relativeUrlPipe: RelativeUrlPipe,
private elementRef: ElementRef,
) { }
private elementRef: ElementRef
) {
}
ngOnInit() {
ngOnInit(): void {
this.stateService.networkChanged$.subscribe((network) => {
this.network = network;
// TODO: Eventually change network type here from string to enum of consts
this.regexAddress = getRegex('address', network as any || 'mainnet');
});
this.router.events.subscribe((e: NavigationStart) => { // Reset search focus when changing page
if (this.searchInput && e.type === EventType.NavigationStart) {
this.searchInput.nativeElement.blur();
}
});
this.stateService.searchFocus$.subscribe(() => {
if (!this.searchInput) { // Try again a bit later once the view is properly initialized
setTimeout(() => this.searchInput.nativeElement.focus(), 100);
} else if (this.searchInput) {
this.searchInput.nativeElement.focus();
}
});
this.searchForm = this.formBuilder.group({
searchText: ['', Validators.required],
});
@@ -160,7 +180,9 @@ export class SearchFormComponent implements OnInit {
const addressPrefixSearchResults = result[0];
const lightningResults = result[1];
const matchesBlockHeight = this.regexBlockheight.test(searchText);
const matchesBlockHeight = this.regexBlockheight.test(searchText) && parseInt(searchText) <= this.stateService.latestBlockHeight;
const matchesDateTime = this.regexDate.test(searchText) && new Date(searchText).toString() !== 'Invalid Date';
const matchesUnixTimestamp = this.regexUnixTimestamp.test(searchText);
const matchesTxId = this.regexTransaction.test(searchText) && !this.regexBlockhash.test(searchText);
const matchesBlockHash = this.regexBlockhash.test(searchText);
const matchesAddress = !matchesTxId && this.regexAddress.test(searchText);
@@ -169,10 +191,16 @@ export class SearchFormComponent implements OnInit {
searchText = 'B' + searchText;
}
if (matchesDateTime && searchText.indexOf('/') !== -1) {
searchText = searchText.replace(/\//g, '-');
}
return {
searchText: searchText,
hashQuickMatch: +(matchesBlockHeight || matchesBlockHash || matchesTxId || matchesAddress),
hashQuickMatch: +(matchesBlockHeight || matchesBlockHash || matchesTxId || matchesAddress || matchesUnixTimestamp || matchesDateTime),
blockHeight: matchesBlockHeight,
dateTime: matchesDateTime,
unixTimestamp: matchesUnixTimestamp,
txId: matchesTxId,
blockHash: matchesBlockHash,
address: matchesAddress,
@@ -195,7 +223,7 @@ export class SearchFormComponent implements OnInit {
selectedResult(result: any): void {
if (typeof result === 'string') {
this.search(result);
} else if (typeof result === 'number') {
} else if (typeof result === 'number' && result <= this.stateService.latestBlockHeight) {
this.navigate('/block/', result.toString());
} else if (result.alias) {
this.navigate('/lightning/node/', result.public_key);
@@ -215,8 +243,10 @@ export class SearchFormComponent implements OnInit {
} else if (otherNetworks.length > 0) {
// Change the network to the first match
this.navigate('/address/', searchText, undefined, otherNetworks[0]);
} else if (this.regexBlockhash.test(searchText) || this.regexBlockheight.test(searchText)) {
} else if (this.regexBlockhash.test(searchText)) {
this.navigate('/block/', searchText);
} else if (this.regexBlockheight.test(searchText)) {
parseInt(searchText) <= this.stateService.latestBlockHeight ? this.navigate('/block/', searchText) : this.isSearching = false;
} else if (this.regexTransaction.test(searchText)) {
const matches = this.regexTransaction.exec(searchText);
if (this.network === 'liquid' || this.network === 'liquidtestnet') {
@@ -236,6 +266,13 @@ export class SearchFormComponent implements OnInit {
} else {
this.navigate('/tx/', matches[0]);
}
} else if (this.regexDate.test(searchText) || this.regexUnixTimestamp.test(searchText)) {
let timestamp: number;
this.regexDate.test(searchText) ? timestamp = Math.floor(new Date(searchText).getTime() / 1000) : timestamp = searchText;
this.apiService.getBlockDataFromTimestamp$(timestamp).subscribe(
(data) => { this.navigate('/block/', data.hash); },
(error) => { console.log(error); this.isSearching = false; }
);
} else {
this.searchResults.searchButtonClick();
this.isSearching = false;