mirror of
https://github.com/mempool/mempool.git
synced 2025-02-22 14:22:44 +01:00
Merge branch 'master' into nymkappa/bugfix/node-header-layout
This commit is contained in:
commit
d5f8ce00b7
6 changed files with 50 additions and 7 deletions
|
@ -522,6 +522,23 @@ class ChannelsApi {
|
|||
logger.err('$setChannelsInactive() error: ' + (e instanceof Error ? e.message : e));
|
||||
}
|
||||
}
|
||||
|
||||
public async $getLatestChannelUpdateForNode(publicKey: string): Promise<number> {
|
||||
try {
|
||||
const query = `
|
||||
SELECT MAX(UNIX_TIMESTAMP(updated_at)) as updated_at
|
||||
FROM channels
|
||||
WHERE node1_public_key = ?
|
||||
`;
|
||||
const [rows]: any[] = await DB.query(query, [publicKey]);
|
||||
if (rows.length > 0) {
|
||||
return rows[0].updated_at;
|
||||
}
|
||||
} catch (e) {
|
||||
logger.err(`Can't getLatestChannelUpdateForNode for ${publicKey}. Reason ${e instanceof Error ? e.message : e}`);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export default new ChannelsApi();
|
||||
|
|
|
@ -63,6 +63,9 @@ class NetworkSyncService {
|
|||
let deletedSockets = 0;
|
||||
const graphNodesPubkeys: string[] = [];
|
||||
for (const node of nodes) {
|
||||
const latestUpdated = await channelsApi.$getLatestChannelUpdateForNode(node.pub_key);
|
||||
node.last_update = Math.max(node.last_update, latestUpdated);
|
||||
|
||||
await nodesApi.$saveNode(node);
|
||||
graphNodesPubkeys.push(node.pub_key);
|
||||
++progress;
|
||||
|
|
|
@ -7,7 +7,13 @@
|
|||
|
||||
</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 *ngIf="!(isTypeaheading$ | async) else searchLoading" [icon]="['fas', 'search']" [fixedWidth]="true" i18n-title="search-form.search-title" title="Search"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ng-template #searchLoading>
|
||||
<div class="spinner-border spinner-border-sm text-light" role="status" aria-hidden="true" (click)="searchForm.valid && search()"></div>
|
||||
</ng-template>
|
||||
|
|
|
@ -50,3 +50,9 @@ form {
|
|||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.spinner-border {
|
||||
vertical-align: text-top;
|
||||
margin-top: 1px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|||
import { Router } from '@angular/router';
|
||||
import { AssetsService } from 'src/app/services/assets.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { Observable, of, Subject, merge, zip } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, switchMap, filter, catchError, map } from 'rxjs/operators';
|
||||
import { Observable, of, Subject, zip, BehaviorSubject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, switchMap, catchError, map } from 'rxjs/operators';
|
||||
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
|
||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
|
@ -20,13 +20,14 @@ export class SearchFormComponent implements OnInit {
|
|||
network = '';
|
||||
assets: object = {};
|
||||
isSearching = false;
|
||||
isTypeaheading$ = new BehaviorSubject<boolean>(false);
|
||||
typeAhead$: Observable<any>;
|
||||
searchForm: FormGroup;
|
||||
|
||||
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})$/;
|
||||
regexBlockhash = /^[0]{8}[a-fA-F0-9]{56}$/;
|
||||
regexTransaction = /^([a-fA-F0-9]{64}):?(\d+)?$/;
|
||||
regexBlockheight = /^[0-9]+$/;
|
||||
regexTransaction = /^([a-fA-F0-9]{64})(:\d+)?$/;
|
||||
regexBlockheight = /^[0-9]{1,9}$/;
|
||||
focus$ = new Subject<string>();
|
||||
click$ = new Subject<string>();
|
||||
|
||||
|
@ -68,7 +69,7 @@ export class SearchFormComponent implements OnInit {
|
|||
}
|
||||
return text.trim();
|
||||
}),
|
||||
debounceTime(250),
|
||||
debounceTime(200),
|
||||
distinctUntilChanged(),
|
||||
switchMap((text) => {
|
||||
if (!text.length) {
|
||||
|
@ -80,6 +81,7 @@ export class SearchFormComponent implements OnInit {
|
|||
}
|
||||
]);
|
||||
}
|
||||
this.isTypeaheading$.next(true);
|
||||
if (!this.stateService.env.LIGHTNING) {
|
||||
return zip(
|
||||
this.electrsApiService.getAddressesByPrefix$(text).pipe(catchError(() => of([]))),
|
||||
|
@ -95,6 +97,7 @@ export class SearchFormComponent implements OnInit {
|
|||
);
|
||||
}),
|
||||
map((result: any[]) => {
|
||||
this.isTypeaheading$.next(false);
|
||||
if (this.network === 'bisq') {
|
||||
return result[0].map((address: string) => 'B' + address);
|
||||
}
|
||||
|
@ -153,6 +156,7 @@ export class SearchFormComponent implements OnInit {
|
|||
this.navigate('/tx/', matches[0]);
|
||||
}
|
||||
} else {
|
||||
this.searchResults.searchButtonClick();
|
||||
this.isSearching = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,13 @@ export class SearchResultsComponent implements OnChanges {
|
|||
}
|
||||
}
|
||||
|
||||
searchButtonClick() {
|
||||
if (this.resultsFlattened[this.activeIdx]) {
|
||||
this.selectedResult.emit(this.resultsFlattened[this.activeIdx]);
|
||||
this.results = null;
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyDown(event: KeyboardEvent) {
|
||||
switch (event.key) {
|
||||
case 'ArrowDown':
|
||||
|
|
Loading…
Add table
Reference in a new issue