Merge branch 'master' into nymkappa/unify-blocks-apis
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Component, OnInit, OnDestroy, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { Price } from 'src/app/services/price.service';
|
||||
import { Price } from '../../services/price.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-amount',
|
||||
|
||||
@@ -5,7 +5,7 @@ import BlockScene from './block-scene';
|
||||
import TxSprite from './tx-sprite';
|
||||
import TxView from './tx-view';
|
||||
import { Position } from './sprite-types';
|
||||
import { Price } from 'src/app/services/price.service';
|
||||
import { Price } from '../../services/price.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-overview-graph',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Component, ElementRef, ViewChild, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { TransactionStripped } from '../../interfaces/websocket.interface';
|
||||
import { Position } from '../../components/block-overview-graph/sprite-types.js';
|
||||
import { Price } from 'src/app/services/price.service';
|
||||
import { Price } from '../../services/price.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-overview-tooltip',
|
||||
|
||||
@@ -13,7 +13,7 @@ import { BlockAudit, BlockExtended, TransactionStripped } from '../../interfaces
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
||||
import { detectWebGL } from '../../shared/graphs.utils';
|
||||
import { PriceService, Price } from 'src/app/services/price.service';
|
||||
import { PriceService, Price } from '../../services/price.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block',
|
||||
|
||||
@@ -267,6 +267,7 @@ export class StartComponent implements OnInit, OnDestroy {
|
||||
|
||||
resetScroll(): void {
|
||||
this.scrollToBlock(this.chainTip);
|
||||
this.blockchainContainer.nativeElement.scrollLeft = 0;
|
||||
}
|
||||
|
||||
getPageIndexOf(height: number): number {
|
||||
|
||||
@@ -22,7 +22,7 @@ import { SeoService } from '../../services/seo.service';
|
||||
import { BlockExtended, CpfpInfo } from '../../interfaces/node-api.interface';
|
||||
import { LiquidUnblinding } from './liquid-ublinding';
|
||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||
import { Price, PriceService } from 'src/app/services/price.service';
|
||||
import { Price, PriceService } from '../../services/price.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-transaction',
|
||||
|
||||
@@ -9,7 +9,7 @@ import { AssetsService } from '../../services/assets.service';
|
||||
import { filter, map, tap, switchMap, shareReplay } from 'rxjs/operators';
|
||||
import { BlockExtended } from '../../interfaces/node-api.interface';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { PriceService } from 'src/app/services/price.service';
|
||||
import { PriceService } from '../../services/price.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-transactions-list',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, ElementRef, ViewChild, Input, OnChanges, OnInit } from '@angular/core';
|
||||
import { tap } from 'rxjs';
|
||||
import { Price, PriceService } from 'src/app/services/price.service';
|
||||
import { Price, PriceService } from '../../services/price.service';
|
||||
|
||||
interface Xput {
|
||||
type: 'input' | 'output' | 'fee';
|
||||
|
||||
@@ -199,8 +199,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
||||
this.outputs = this.initLines('out', voutWithFee, totalValue, this.maxStrands);
|
||||
|
||||
this.middle = {
|
||||
path: `M ${(this.width / 2) - this.midWidth} ${(this.height / 2) + 0.25} L ${(this.width / 2) + this.midWidth} ${(this.height / 2) + 0.25}`,
|
||||
style: `stroke-width: ${this.combinedWeight + 0.5}; stroke: ${this.gradient[1]}`
|
||||
path: `M ${(this.width / 2) - this.midWidth} ${(this.height / 2) + 0.5} L ${(this.width / 2) + this.midWidth} ${(this.height / 2) + 0.5}`,
|
||||
style: `stroke-width: ${this.combinedWeight + 1}; stroke: ${this.gradient[1]}`
|
||||
};
|
||||
|
||||
this.hasLine = this.inputs.reduce((line, put) => line || !put.zeroValue, false)
|
||||
@@ -257,7 +257,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
||||
const lineParams = weights.map((w, i) => {
|
||||
return {
|
||||
weight: w,
|
||||
thickness: xputs[i].value === 0 ? this.zeroValueThickness : Math.min(this.combinedWeight + 0.5, Math.max(this.minWeight - 1, w) + 1),
|
||||
thickness: xputs[i].value === 0 ? this.zeroValueThickness : Math.max(this.minWeight - 1, w) + 1,
|
||||
offset: 0,
|
||||
innerY: 0,
|
||||
outerY: 0,
|
||||
@@ -269,7 +269,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
||||
|
||||
// bounds of the middle segment
|
||||
const innerTop = (this.height / 2) - (this.combinedWeight / 2);
|
||||
const innerBottom = innerTop + this.combinedWeight + 0.5;
|
||||
const innerBottom = innerTop + this.combinedWeight;
|
||||
// tracks the visual bottom of the endpoints of the previous line
|
||||
let lastOuter = 0;
|
||||
let lastInner = innerTop;
|
||||
@@ -294,7 +294,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
||||
|
||||
// set the vertical position of the (center of the) outer side of the line
|
||||
line.outerY = lastOuter + (line.thickness / 2);
|
||||
line.innerY = Math.min(innerBottom - (line.thickness / 2), Math.max(innerTop + (line.thickness / 2), lastInner + (line.weight / 2)));
|
||||
line.innerY = Math.min(innerBottom + (line.thickness / 2), Math.max(innerTop + (line.thickness / 2), lastInner + (line.weight / 2)));
|
||||
|
||||
// special case to center single input/outputs
|
||||
if (xputs.length === 1) {
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Top nodes per capacity -->
|
||||
<div class="col">
|
||||
<div class="col" style="max-height: 410px">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<a class="title-link" href="" [routerLink]="['/lightning/nodes/rankings/liquidity' | relativeUrl]">
|
||||
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Top nodes per channels -->
|
||||
<div class="col">
|
||||
<div class="col" style="max-height: 410px">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<a class="title-link" href="" [routerLink]="['/lightning/nodes/rankings/connectivity' | relativeUrl]">
|
||||
|
||||
@@ -1,71 +1,56 @@
|
||||
<div [class]="!widget ? 'container-xl full-height' : ''">
|
||||
<h1 *ngIf="!widget" class="float-left">
|
||||
<span i18n="lightning.top-100-liquidity">Top 100 nodes liquidity ranking</span>
|
||||
</h1>
|
||||
|
||||
<div [class]="widget ? 'widget' : 'full'">
|
||||
<table class="table table-borderless table-fixed">
|
||||
|
||||
<div class="container-xl" style="min-height: 335px" [ngClass]="{'widget': widget, 'full-height': !widget}">
|
||||
<h1 *ngIf="!widget" class="float-left" i18n="lightning.liquidity-ranking">Liquidity Ranking</h1>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div style="min-height: 295px">
|
||||
<table class="table table-borderless">
|
||||
<thead>
|
||||
<th class="rank"></th>
|
||||
<th class="alias text-left" i18n="nodes.alias">Alias</th>
|
||||
<th class="capacity text-right" i18n="node.liquidity">Liquidity</th>
|
||||
<th *ngIf="!widget" class="channels text-right" i18n="lightning.channels">Channels</th>
|
||||
<th *ngIf="!widget" class="timestamp-first text-left" i18n="transaction.first-seen|Transaction first seen">First seen</th>
|
||||
<th *ngIf="!widget" class="timestamp-update text-left" i18n="lightning.last_update">Last update</th>
|
||||
<th *ngIf="!widget" class="location text-right" i18n="lightning.location">Location</th>
|
||||
<th class="text-left" i18n="nodes.alias">Alias</th>
|
||||
<th class="liquidity text-right" i18n="node.liquidity">Liquidity</th>
|
||||
<th class="d-table-cell fiat text-right" [class]="{'widget': widget}">{{ currency$ | async }}</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell channels text-right" i18n="lightning.channels">Channels</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell timestamp text-right" i18n="transaction.first-seen|Transaction first seen">First seen</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell timestamp text-right" i18n="lightning.last_update">Last update</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell text-right" i18n="lightning.location">Location</th>
|
||||
</thead>
|
||||
<tbody *ngIf="topNodesPerCapacity$ | async as nodes; else skeleton">
|
||||
<tr *ngFor="let node of nodes; let i = index;">
|
||||
<td class="rank text-left">
|
||||
{{ i + 1 }}
|
||||
<tbody *ngIf="topNodesPerCapacity$ | async as nodes">
|
||||
<tr *ngFor="let node of nodes;">
|
||||
<td class="pool text-left">
|
||||
<div class="tooltip-custom d-block w-100">
|
||||
<a class="link d-block w-100" [routerLink]="['/lightning/node' | relativeUrl, node.publicKey]">
|
||||
<span class="pool-name w-100">{{ node.alias }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="alias text-left">
|
||||
<a [routerLink]="['/lightning/node' | relativeUrl, node.publicKey]">{{ node.alias }}</a>
|
||||
</td>
|
||||
<td class="capacity text-right">
|
||||
<td class="text-right">
|
||||
<app-amount [satoshis]="node.capacity" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="channels text-right">
|
||||
<td class="d-table-cell fiat text-right" [ngClass]="{'widget': widget}">
|
||||
<app-fiat [value]="node.capacity"></app-fiat>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="d-none d-md-table-cell text-right">
|
||||
{{ node.channels | number }}
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-first text-left">
|
||||
<td *ngIf="!widget" class="d-none d-md-table-cell text-right">
|
||||
<app-timestamp [customFormat]="'yyyy-MM-dd'" [unixTime]="node.firstSeen" [hideTimeSince]="true"></app-timestamp>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-update text-left">
|
||||
<td *ngIf="!widget" class="d-none d-md-table-cell text-right">
|
||||
<app-timestamp [customFormat]="'yyyy-MM-dd'" [unixTime]="node.updatedAt" [hideTimeSince]="true"></app-timestamp>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="location text-right text-truncate">
|
||||
<td *ngIf="!widget" class="d-none d-md-table-cell text-right text-truncate">
|
||||
<app-geolocation [data]="node.geolocation" [type]="'list-isp'"></app-geolocation>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<ng-template #skeleton>
|
||||
<tbody>
|
||||
<tr *ngFor="let item of skeletonRows">
|
||||
<td class="rank text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td class="alias text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td class="capacity text-right">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="channels text-right">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-first text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-update text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="location text-right text-truncate">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</ng-template>
|
||||
</table>
|
||||
|
||||
<ng-template [ngIf]="!widget">
|
||||
<div class="clearfix"></div>
|
||||
<br>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,91 +1,52 @@
|
||||
.container-xl {
|
||||
max-width: 1400px;
|
||||
padding-bottom: 100px;
|
||||
@media (min-width: 960px) {
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
}
|
||||
}
|
||||
.container-xl.widget {
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.table td, .table th {
|
||||
padding: 0.5rem;
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.7rem !important;
|
||||
}
|
||||
|
||||
.full .rank {
|
||||
width: 5%;
|
||||
}
|
||||
.widget .rank {
|
||||
@media (min-width: 960px) {
|
||||
width: 13%;
|
||||
}
|
||||
@media (max-width: 960px) {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
.clear-link {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.full .alias {
|
||||
width: 20%;
|
||||
.pool {
|
||||
width: 15%;
|
||||
@media (max-width: 575px) {
|
||||
width: 75%;
|
||||
}
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 350px;
|
||||
@media (max-width: 960px) {
|
||||
width: 40%;
|
||||
max-width: 500px;
|
||||
}
|
||||
white-space: nowrap;
|
||||
max-width: 160px;
|
||||
}
|
||||
.widget .alias {
|
||||
width: 60%;
|
||||
overflow: hidden;
|
||||
.pool-name {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 350px;
|
||||
@media (max-width: 960px) {
|
||||
max-width: 175px;
|
||||
}
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.full .capacity {
|
||||
.liquidity {
|
||||
width: 10%;
|
||||
@media (max-width: 960px) {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
.widget .capacity {
|
||||
width: 32%;
|
||||
@media (max-width: 960px) {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
@media (max-width: 575px) {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.full .channels {
|
||||
.fiat {
|
||||
width: 15%;
|
||||
padding-right: 50px;
|
||||
@media (max-width: 960px) {
|
||||
display: none;
|
||||
@media (min-width: 768px) and (max-width: 991px) {
|
||||
display: none !important;
|
||||
}
|
||||
@media (max-width: 575px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.full .timestamp-first {
|
||||
width: 10%;
|
||||
@media (max-width: 960px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.full .timestamp-update {
|
||||
width: 10%;
|
||||
@media (max-width: 960px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.full .location {
|
||||
width: 15%;
|
||||
@media (max-width: 960px) {
|
||||
width: 30%;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { map, Observable } from 'rxjs';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { INodesRanking, ITopNodesPerCapacity } from '../../../interfaces/node-api.interface';
|
||||
import { SeoService } from '../../../services/seo.service';
|
||||
import { isMobile } from '../../../shared/common.utils';
|
||||
import { GeolocationData } from '../../../shared/components/geolocation/geolocation.component';
|
||||
import { LightningApiService } from '../../lightning-api.service';
|
||||
|
||||
@@ -18,18 +18,22 @@ export class TopNodesPerCapacity implements OnInit {
|
||||
|
||||
topNodesPerCapacity$: Observable<ITopNodesPerCapacity[]>;
|
||||
skeletonRows: number[] = [];
|
||||
currency$: Observable<string>;
|
||||
|
||||
constructor(
|
||||
private apiService: LightningApiService,
|
||||
private seoService: SeoService
|
||||
private seoService: SeoService,
|
||||
private stateService: StateService,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.currency$ = this.stateService.fiatCurrency$;
|
||||
|
||||
if (!this.widget) {
|
||||
this.seoService.setTitle($localize`:@@2d9883d230a47fbbb2ec969e32a186597ea27405:Liquidity Ranking`);
|
||||
}
|
||||
|
||||
for (let i = 1; i <= (this.widget ? (isMobile() ? 8 : 7) : 100); ++i) {
|
||||
for (let i = 1; i <= (this.widget ? 6 : 100); ++i) {
|
||||
this.skeletonRows.push(i);
|
||||
}
|
||||
|
||||
@@ -50,7 +54,7 @@ export class TopNodesPerCapacity implements OnInit {
|
||||
} else {
|
||||
this.topNodesPerCapacity$ = this.nodes$.pipe(
|
||||
map((ranking) => {
|
||||
return ranking.topByCapacity.slice(0, isMobile() ? 8 : 7);
|
||||
return ranking.topByCapacity.slice(0, 6);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,71 +1,56 @@
|
||||
<div [class]="!widget ? 'container-xl full-height' : ''">
|
||||
<h1 *ngIf="!widget" class="float-left">
|
||||
<span i18n="lightning.top-100-connectivity">Top 100 nodes connectivity ranking</span>
|
||||
</h1>
|
||||
|
||||
<div [class]="widget ? 'widget' : 'full'">
|
||||
|
||||
<div class="container-xl" style="min-height: 335px" [ngClass]="{'widget': widget, 'full-height': !widget}">
|
||||
<h1 *ngIf="!widget" class="float-left" i18n="lightning.liquidity-ranking">Liquidity Ranking</h1>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div style="min-height: 295px">
|
||||
<table class="table table-borderless">
|
||||
<thead>
|
||||
<th class="rank"></th>
|
||||
<th class="alias text-left" i18n="nodes.alias">Alias</th>
|
||||
<th class="channels text-right" i18n="node.channels">Channels</th>
|
||||
<th *ngIf="!widget" class="capacity text-right" i18n="lightning.liquidity">Liquidity</th>
|
||||
<th *ngIf="!widget" class="timestamp-first text-left" i18n="transaction.first-seen|Transaction first seen">First seen</th>
|
||||
<th *ngIf="!widget" class="timestamp-update text-left" i18n="lightning.last_update">Last update</th>
|
||||
<th *ngIf="!widget" class="location text-right" i18n="lightning.location">Location</th>
|
||||
<th class="pool text-left" i18n="nodes.alias" [ngClass]="{'widget': widget}">Alias</th>
|
||||
<th class="liquidity text-right" i18n="node.channels">Channels</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell channels text-right" i18n="lightning.channels">Capacity</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell text-right" i18n="node.liquidity">{{ currency$ | async }}</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell timestamp text-right" i18n="transaction.first-seen|Transaction first seen">First seen</th>
|
||||
<th *ngIf="!widget" class="d-none d-md-table-cell timestamp text-right" i18n="lightning.last_update">Last update</th>
|
||||
<th class="geolocation d-table-cell text-right" i18n="lightning.location">Location</th>
|
||||
</thead>
|
||||
<tbody *ngIf="topNodesPerChannels$ | async as nodes; else skeleton">
|
||||
<tr *ngFor="let node of nodes; let i = index;">
|
||||
<td class="rank text-left">
|
||||
{{ i + 1 }}
|
||||
<tbody *ngIf="topNodesPerChannels$ | async as nodes">
|
||||
<tr *ngFor="let node of nodes;">
|
||||
<td class="pool text-left">
|
||||
<div class="tooltip-custom d-block w-100">
|
||||
<a class="link d-block w-100" [routerLink]="['/lightning/node' | relativeUrl, node.publicKey]">
|
||||
<span class="pool-name w-100">{{ node.alias }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="alias text-left">
|
||||
<a [routerLink]="['/lightning/node' | relativeUrl, node.publicKey]">{{ node.alias }}</a>
|
||||
<td class="text-right">
|
||||
{{ node.channels ? (node.channels | number) : '~' }}
|
||||
</td>
|
||||
<td class="channels text-right">
|
||||
{{ node.channels | number }}
|
||||
</td>
|
||||
<td *ngIf="!widget" class="capacity text-right">
|
||||
<td *ngIf="!widget" class="d-none d-md-table-cell capacity text-right">
|
||||
<app-amount [satoshis]="node.capacity" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-first text-left">
|
||||
<td *ngIf="!widget" class="fiat d-none d-md-table-cell text-right">
|
||||
<app-fiat [value]="node.capacity"></app-fiat>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="d-none d-md-table-cell text-right">
|
||||
<app-timestamp [customFormat]="'yyyy-MM-dd'" [unixTime]="node.firstSeen" [hideTimeSince]="true"></app-timestamp>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-update text-left">
|
||||
<td *ngIf="!widget" class="d-none d-md-table-cell text-right">
|
||||
<app-timestamp [customFormat]="'yyyy-MM-dd'" [unixTime]="node.updatedAt" [hideTimeSince]="true"></app-timestamp>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="location text-right text-truncate">
|
||||
<td class="geolocation d-table-cell text-right text-truncate">
|
||||
<app-geolocation [data]="node.geolocation" [type]="'list-isp'"></app-geolocation>
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</tbody>
|
||||
<ng-template #skeleton>
|
||||
<tbody>
|
||||
<tr *ngFor="let item of skeletonRows">
|
||||
<td class="rank text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td class="alias text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td class="channels text-right">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="capacity text-right">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-first text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="timestamp-update text-left">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
<td *ngIf="!widget" class="location text-right text-truncate">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</ng-template>
|
||||
</table>
|
||||
|
||||
<ng-template [ngIf]="!widget">
|
||||
<div class="clearfix"></div>
|
||||
<br>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,91 +1,54 @@
|
||||
.container-xl {
|
||||
max-width: 1400px;
|
||||
padding-bottom: 100px;
|
||||
@media (min-width: 960px) {
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
}
|
||||
}
|
||||
.container-xl.widget {
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.table td, .table th {
|
||||
padding: 0.5rem;
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.7rem !important;
|
||||
}
|
||||
|
||||
.full .rank {
|
||||
width: 5%;
|
||||
}
|
||||
.widget .rank {
|
||||
@media (min-width: 960px) {
|
||||
width: 13%;
|
||||
}
|
||||
@media (max-width: 960px) {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
.clear-link {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.full .alias {
|
||||
width: 20%;
|
||||
.pool {
|
||||
width: 15%;
|
||||
@media (max-width: 576px) {
|
||||
width: 75%;
|
||||
}
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 350px;
|
||||
@media (max-width: 960px) {
|
||||
width: 40%;
|
||||
max-width: 500px;
|
||||
}
|
||||
white-space: nowrap;
|
||||
max-width: 160px;
|
||||
}
|
||||
.widget .alias {
|
||||
width: 60%;
|
||||
overflow: hidden;
|
||||
.pool-name {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 350px;
|
||||
@media (max-width: 960px) {
|
||||
max-width: 175px;
|
||||
}
|
||||
overflow: hidden;
|
||||
}
|
||||
.pool.widget {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.full .capacity {
|
||||
.liquidity {
|
||||
width: 10%;
|
||||
@media (max-width: 960px) {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
.widget .capacity {
|
||||
width: 32%;
|
||||
@media (max-width: 960px) {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
@media (max-width: 576px) {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.full .channels {
|
||||
width: 15%;
|
||||
padding-right: 50px;
|
||||
@media (max-width: 960px) {
|
||||
display: none;
|
||||
.geolocation {
|
||||
@media (min-width: 768px) and (max-width: 991px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.full .timestamp-first {
|
||||
width: 10%;
|
||||
@media (max-width: 960px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.full .timestamp-update {
|
||||
width: 10%;
|
||||
@media (max-width: 960px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.full .location {
|
||||
width: 15%;
|
||||
@media (max-width: 960px) {
|
||||
width: 30%;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
display: none;
|
||||
@media (max-width: 575px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { map, Observable } from 'rxjs';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { INodesRanking, ITopNodesPerChannels } from '../../../interfaces/node-api.interface';
|
||||
import { isMobile } from '../../../shared/common.utils';
|
||||
import { GeolocationData } from '../../../shared/components/geolocation/geolocation.component';
|
||||
import { LightningApiService } from '../../lightning-api.service';
|
||||
|
||||
@@ -17,13 +17,17 @@ export class TopNodesPerChannels implements OnInit {
|
||||
|
||||
topNodesPerChannels$: Observable<ITopNodesPerChannels[]>;
|
||||
skeletonRows: number[] = [];
|
||||
currency$: Observable<string>;
|
||||
|
||||
constructor(
|
||||
private apiService: LightningApiService,
|
||||
private stateService: StateService,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
for (let i = 1; i <= (this.widget ? (isMobile() ? 8 : 7) : 100); ++i) {
|
||||
this.currency$ = this.stateService.fiatCurrency$;
|
||||
|
||||
for (let i = 1; i <= (this.widget ? 6 : 100); ++i) {
|
||||
this.skeletonRows.push(i);
|
||||
}
|
||||
|
||||
@@ -44,7 +48,15 @@ export class TopNodesPerChannels implements OnInit {
|
||||
} else {
|
||||
this.topNodesPerChannels$ = this.nodes$.pipe(
|
||||
map((ranking) => {
|
||||
return ranking.topByChannels.slice(0, isMobile() ? 8 : 7);
|
||||
for (const i in ranking.topByChannels) {
|
||||
ranking.topByChannels[i].geolocation = <GeolocationData>{
|
||||
country: ranking.topByChannels[i].country?.en,
|
||||
city: ranking.topByChannels[i].city?.en,
|
||||
subdivision: ranking.topByChannels[i].subdivision?.en,
|
||||
iso: ranking.topByChannels[i].iso_code,
|
||||
};
|
||||
}
|
||||
return ranking.topByChannels.slice(0, 6);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ export class CacheService {
|
||||
|
||||
txCache: { [txid: string]: Transaction } = {};
|
||||
|
||||
network: string;
|
||||
blockCache: { [height: number]: BlockExtended } = {};
|
||||
blockLoading: { [height: number]: boolean } = {};
|
||||
copiesInBlockQueue: { [height: number]: number } = {};
|
||||
@@ -33,6 +34,10 @@ export class CacheService {
|
||||
this.stateService.chainTip$.subscribe((height) => {
|
||||
this.tip = height;
|
||||
});
|
||||
this.stateService.networkChanged$.subscribe((network) => {
|
||||
this.network = network;
|
||||
this.resetBlockCache();
|
||||
});
|
||||
}
|
||||
|
||||
setTxCache(transactions) {
|
||||
@@ -68,15 +73,17 @@ export class CacheService {
|
||||
} catch (e) {
|
||||
console.log("failed to load blocks: ", e.message);
|
||||
}
|
||||
for (let i = 0; i < chunkSize; i++) {
|
||||
delete this.blockLoading[maxHeight - i];
|
||||
}
|
||||
if (result && result.length) {
|
||||
result.forEach(block => {
|
||||
this.addBlockToCache(block);
|
||||
this.loadedBlocks$.next(block);
|
||||
if (this.blockLoading[block.height]) {
|
||||
this.addBlockToCache(block);
|
||||
this.loadedBlocks$.next(block);
|
||||
}
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < chunkSize; i++) {
|
||||
delete this.blockLoading[maxHeight - i];
|
||||
}
|
||||
this.clearBlocks();
|
||||
} else {
|
||||
this.bumpBlockPriority(height);
|
||||
@@ -104,6 +111,14 @@ export class CacheService {
|
||||
}
|
||||
}
|
||||
|
||||
// remove all blocks from the cache
|
||||
resetBlockCache() {
|
||||
this.blockCache = {};
|
||||
this.blockLoading = {};
|
||||
this.copiesInBlockQueue = {};
|
||||
this.blockPriorities = [];
|
||||
}
|
||||
|
||||
getCachedBlock(height) {
|
||||
return this.blockCache[height];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user