Add lighting ISP preview
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<div class="box preview-box" *ngIf="(nodes$ | async) as ispNodes">
|
||||
<app-preview-title>
|
||||
<span i18n="lightning.node">lightning ISP</span>
|
||||
</app-preview-title>
|
||||
<div class="row d-flex justify-content-between full-width-row">
|
||||
<div class="title-wrapper">
|
||||
<h1 class="title">{{ isp?.name }}</h1>
|
||||
<a class="subtitle" [routerLink]="['/lightning/nodes/isp/' | relativeUrl, isp?.id]">
|
||||
ASN {{ isp?.id }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="logo-wrapper">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<table class="table table-borderless table-striped table-fixed">
|
||||
<col span="1" width="250px">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td i18n="lightning.node-count">Nodes</td>
|
||||
<td>{{ ispNodes.nodes.length }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="lightning.liquidity">Liquidity</td>
|
||||
<td>
|
||||
<app-amount *ngIf="ispNodes.sumLiquidity > 100000000; else smallnode" [satoshis]="ispNodes.sumLiquidity" [digitsInfo]="'1.2-2'" [noFiat]="false"></app-amount>
|
||||
<ng-template #smallnode>
|
||||
<app-sats [satoshis]="ispNodes.sumLiquidity" digitsInfo="1.0-2"></app-sats>
|
||||
</ng-template>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="lightning.channels">Channels</td>
|
||||
<td>{{ ispNodes.sumChannels }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="lightning.top-country">Top country</td>
|
||||
<td class="text-truncate">
|
||||
<span class="">{{ ispNodes.topCountry.country }} {{ ispNodes.topCountry.flag }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="lightning.top-node">Top node</td>
|
||||
<td class="text-truncate">
|
||||
{{ ispNodes.nodes[0].alias }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md map-col">
|
||||
<app-nodes-map [widget]="true" [nodes]="ispNodes.nodes" type="isp" [fitContainer]="true" (readyEvent)="onMapReady()"></app-nodes-map>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template [ngIf]="error">
|
||||
<div class="text-center">
|
||||
<span i18n="error.general-loading-data">Error loading data.</span>
|
||||
</div>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,31 @@
|
||||
.table {
|
||||
font-size: 32px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.map-col {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
width: 470px;
|
||||
height: 360px;
|
||||
min-width: 470px;
|
||||
min-height: 360px;
|
||||
max-height: 360px;
|
||||
padding: 0;
|
||||
background: #181b2d;
|
||||
overflow: hidden;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.full-width-row {
|
||||
padding-left: 15px;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
::ng-deep .symbol {
|
||||
font-size: 24px;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { catchError, map, switchMap, Observable, share, of } from 'rxjs';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { OpenGraphService } from 'src/app/services/opengraph.service';
|
||||
import { getFlagEmoji } from 'src/app/shared/common.utils';
|
||||
import { GeolocationData } from 'src/app/shared/components/geolocation/geolocation.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nodes-per-isp-preview',
|
||||
templateUrl: './nodes-per-isp-preview.component.html',
|
||||
styleUrls: ['./nodes-per-isp-preview.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class NodesPerISPPreview implements OnInit {
|
||||
nodes$: Observable<any>;
|
||||
isp: {name: string, id: number};
|
||||
id: string;
|
||||
error: Error;
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
private seoService: SeoService,
|
||||
private openGraphService: OpenGraphService,
|
||||
private route: ActivatedRoute,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.nodes$ = this.route.paramMap
|
||||
.pipe(
|
||||
switchMap((params: ParamMap) => {
|
||||
this.id = params.get('isp');
|
||||
this.isp = null;
|
||||
this.openGraphService.waitFor('isp-map-' + this.id);
|
||||
this.openGraphService.waitFor('isp-data-' + this.id);
|
||||
return this.apiService.getNodeForISP$(params.get('isp'));
|
||||
}),
|
||||
map(response => {
|
||||
this.isp = {
|
||||
name: response.isp,
|
||||
id: this.route.snapshot.params.isp.split(',').join(', ')
|
||||
};
|
||||
this.seoService.setTitle($localize`Lightning nodes on ISP: ${response.isp} [AS${this.route.snapshot.params.isp}]`);
|
||||
|
||||
for (const i in response.nodes) {
|
||||
response.nodes[i].geolocation = <GeolocationData>{
|
||||
country: response.nodes[i].country?.en,
|
||||
city: response.nodes[i].city?.en,
|
||||
subdivision: response.nodes[i].subdivision?.en,
|
||||
iso: response.nodes[i].iso_code,
|
||||
};
|
||||
}
|
||||
|
||||
const sumLiquidity = response.nodes.reduce((partialSum, a) => partialSum + a.capacity, 0);
|
||||
const sumChannels = response.nodes.reduce((partialSum, a) => partialSum + a.channels, 0);
|
||||
const countries = {};
|
||||
const topCountry = {
|
||||
count: 0,
|
||||
country: '',
|
||||
iso: '',
|
||||
flag: '',
|
||||
};
|
||||
for (const node of response.nodes) {
|
||||
if (!node.geolocation.iso) {
|
||||
continue;
|
||||
}
|
||||
countries[node.geolocation.iso] = countries[node.geolocation.iso] ?? 0 + 1;
|
||||
if (countries[node.geolocation.iso] > topCountry.count) {
|
||||
topCountry.count = countries[node.geolocation.iso];
|
||||
topCountry.country = node.geolocation.country;
|
||||
topCountry.iso = node.geolocation.iso;
|
||||
}
|
||||
}
|
||||
topCountry.flag = getFlagEmoji(topCountry.iso);
|
||||
|
||||
this.openGraphService.waitOver('isp-data-' + this.id);
|
||||
|
||||
return {
|
||||
nodes: response.nodes,
|
||||
sumLiquidity: sumLiquidity,
|
||||
sumChannels: sumChannels,
|
||||
topCountry: topCountry,
|
||||
};
|
||||
}),
|
||||
catchError(err => {
|
||||
this.error = err;
|
||||
this.openGraphService.fail('isp-map-' + this.id);
|
||||
this.openGraphService.fail('isp-data-' + this.id);
|
||||
return of({
|
||||
nodes: [],
|
||||
sumLiquidity: 0,
|
||||
sumChannels: 0,
|
||||
topCountry: {},
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
onMapReady() {
|
||||
this.openGraphService.waitOver('isp-map-' + this.id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user