Merge branch 'master' into nymkappa/bugfix/node-header-layout
This commit is contained in:
		
						commit
						d5f8ce00b7
					
				@ -522,6 +522,23 @@ class ChannelsApi {
 | 
				
			|||||||
      logger.err('$setChannelsInactive() error: ' + (e instanceof Error ? e.message : e));
 | 
					      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();
 | 
					export default new ChannelsApi();
 | 
				
			||||||
 | 
				
			|||||||
@ -63,6 +63,9 @@ class NetworkSyncService {
 | 
				
			|||||||
    let deletedSockets = 0;
 | 
					    let deletedSockets = 0;
 | 
				
			||||||
    const graphNodesPubkeys: string[] = [];
 | 
					    const graphNodesPubkeys: string[] = [];
 | 
				
			||||||
    for (const node of nodes) {
 | 
					    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);
 | 
					      await nodesApi.$saveNode(node);
 | 
				
			||||||
      graphNodesPubkeys.push(node.pub_key);
 | 
					      graphNodesPubkeys.push(node.pub_key);
 | 
				
			||||||
      ++progress;
 | 
					      ++progress;
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,13 @@
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    </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 *ngIf="!(isTypeaheading$ | async) else searchLoading" [icon]="['fas', 'search']" [fixedWidth]="true" i18n-title="search-form.search-title" title="Search"></fa-icon>
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</form>
 | 
					</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>
 | 
				
			||||||
 | 
				
			|||||||
@ -49,4 +49,10 @@ form {
 | 
				
			|||||||
  .btn {
 | 
					  .btn {
 | 
				
			||||||
    width: 100px;
 | 
					    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 { 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, zip } from 'rxjs';
 | 
					import { Observable, of, Subject, zip, BehaviorSubject } from 'rxjs';
 | 
				
			||||||
import { debounceTime, distinctUntilChanged, switchMap, filter, catchError, map } from 'rxjs/operators';
 | 
					import { debounceTime, distinctUntilChanged, switchMap, catchError, map } from 'rxjs/operators';
 | 
				
			||||||
import { ElectrsApiService } from 'src/app/services/electrs-api.service';
 | 
					import { ElectrsApiService } from 'src/app/services/electrs-api.service';
 | 
				
			||||||
import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
 | 
					import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe';
 | 
				
			||||||
import { ApiService } from 'src/app/services/api.service';
 | 
					import { ApiService } from 'src/app/services/api.service';
 | 
				
			||||||
@ -20,13 +20,14 @@ export class SearchFormComponent implements OnInit {
 | 
				
			|||||||
  network = '';
 | 
					  network = '';
 | 
				
			||||||
  assets: object = {};
 | 
					  assets: object = {};
 | 
				
			||||||
  isSearching = false;
 | 
					  isSearching = false;
 | 
				
			||||||
 | 
					  isTypeaheading$ = new BehaviorSubject<boolean>(false);
 | 
				
			||||||
  typeAhead$: Observable<any>;
 | 
					  typeAhead$: Observable<any>;
 | 
				
			||||||
  searchForm: FormGroup;
 | 
					  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})$/;
 | 
					  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}$/;
 | 
					  regexBlockhash = /^[0]{8}[a-fA-F0-9]{56}$/;
 | 
				
			||||||
  regexTransaction = /^([a-fA-F0-9]{64}):?(\d+)?$/;
 | 
					  regexTransaction = /^([a-fA-F0-9]{64})(:\d+)?$/;
 | 
				
			||||||
  regexBlockheight = /^[0-9]+$/;
 | 
					  regexBlockheight = /^[0-9]{1,9}$/;
 | 
				
			||||||
  focus$ = new Subject<string>();
 | 
					  focus$ = new Subject<string>();
 | 
				
			||||||
  click$ = new Subject<string>();
 | 
					  click$ = new Subject<string>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,7 +69,7 @@ export class SearchFormComponent implements OnInit {
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
          return text.trim();
 | 
					          return text.trim();
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        debounceTime(250),
 | 
					        debounceTime(200),
 | 
				
			||||||
        distinctUntilChanged(),
 | 
					        distinctUntilChanged(),
 | 
				
			||||||
        switchMap((text) => {
 | 
					        switchMap((text) => {
 | 
				
			||||||
          if (!text.length) {
 | 
					          if (!text.length) {
 | 
				
			||||||
@ -80,6 +81,7 @@ export class SearchFormComponent implements OnInit {
 | 
				
			|||||||
              }
 | 
					              }
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          this.isTypeaheading$.next(true);
 | 
				
			||||||
          if (!this.stateService.env.LIGHTNING) {
 | 
					          if (!this.stateService.env.LIGHTNING) {
 | 
				
			||||||
            return zip(
 | 
					            return zip(
 | 
				
			||||||
              this.electrsApiService.getAddressesByPrefix$(text).pipe(catchError(() => of([]))),
 | 
					              this.electrsApiService.getAddressesByPrefix$(text).pipe(catchError(() => of([]))),
 | 
				
			||||||
@ -95,6 +97,7 @@ export class SearchFormComponent implements OnInit {
 | 
				
			|||||||
          );
 | 
					          );
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        map((result: any[]) => {
 | 
					        map((result: any[]) => {
 | 
				
			||||||
 | 
					          this.isTypeaheading$.next(false);
 | 
				
			||||||
          if (this.network === 'bisq') {
 | 
					          if (this.network === 'bisq') {
 | 
				
			||||||
            return result[0].map((address: string) => 'B' + address);
 | 
					            return result[0].map((address: string) => 'B' + address);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@ -153,6 +156,7 @@ export class SearchFormComponent implements OnInit {
 | 
				
			|||||||
          this.navigate('/tx/', matches[0]);
 | 
					          this.navigate('/tx/', matches[0]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.searchResults.searchButtonClick();
 | 
				
			||||||
        this.isSearching = false;
 | 
					        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) {
 | 
					  handleKeyDown(event: KeyboardEvent) {
 | 
				
			||||||
    switch (event.key) {
 | 
					    switch (event.key) {
 | 
				
			||||||
      case 'ArrowDown':
 | 
					      case 'ArrowDown':
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user