Merge branch 'master' into mononaut/block-page-layouts

This commit is contained in:
wiz
2022-12-26 21:00:19 +09:00
committed by GitHub
22 changed files with 1001 additions and 188 deletions

View File

@@ -77,6 +77,8 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
cancelAnimationFrame(this.animationFrameRequest);
clearTimeout(this.animationHeartBeat);
}
this.canvas.nativeElement.removeEventListener('webglcontextlost', this.handleContextLost);
this.canvas.nativeElement.removeEventListener('webglcontextrestored', this.handleContextRestored);
}
clear(direction): void {

View File

@@ -53,13 +53,13 @@
<td i18n="block.miner">Miner</td>
<td *ngIf="stateService.env.MINING_DASHBOARD">
<a [attr.data-cy]="'block-details-miner-badge'" placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, block?.extras.pool.slug]" class="badge"
[class]="block?.extras.pool.name === 'Unknown' ? 'badge-secondary' : 'badge-primary'">
[class]="!block?.extras.pool.name || block?.extras.pool.name === 'Unknown' ? 'badge-secondary' : 'badge-primary'">
{{ block?.extras.pool.name }}
</a>
</td>
<td *ngIf="!stateService.env.MINING_DASHBOARD && stateService.env.BASE_MODULE === 'mempool'">
<span [attr.data-cy]="'block-details-miner-badge'" placement="bottom" class="badge"
[class]="block?.extras.pool.name === 'Unknown' ? 'badge-secondary' : 'badge-primary'">
[class]="!block?.extras.pool.name || block?.extras.pool.name === 'Unknown' ? 'badge-secondary' : 'badge-primary'">
{{ block?.extras.pool.name }}
</span>
</td>

View File

@@ -56,3 +56,7 @@
::ng-deep .symbol {
font-size: 24px;
}
.badge {
transition: none;
}

View File

@@ -57,8 +57,21 @@
<tr *ngIf="!auditDataMissing && indexingAvailable">
<td i18n="block.health">Block health</td>
<td>
<span *ngIf="blockAudit?.matchRate != null">{{ blockAudit.matchRate }}%</span>
<span *ngIf="blockAudit?.matchRate === null" i18n="unknown">Unknown</span>
<span
class="health-badge badge"
[class.badge-success]="blockAudit?.matchRate >= 99"
[class.badge-warning]="blockAudit?.matchRate >= 75 && blockAudit?.matchRate < 99"
[class.badge-danger]="blockAudit?.matchRate < 75"
*ngIf="blockAudit?.matchRate != null; else nullHealth"
>{{ blockAudit?.matchRate }}%</span>
<ng-template #nullHealth>
<ng-container *ngIf="!isLoadingAudit; else loadingHealth">
<span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span>
</ng-container>
</ng-template>
<ng-template #loadingHealth>
<span class="skeleton-loader" style="max-width: 60px"></span>
</ng-template>
</td>
</tr>
</ng-container>

View File

@@ -43,6 +43,7 @@ export class BlockComponent implements OnInit, OnDestroy {
strippedTransactions: TransactionStripped[];
overviewTransitionDirection: string;
isLoadingOverview = true;
isLoadingAudit = true;
error: any;
blockSubsidy: number;
fees: number;
@@ -297,13 +298,18 @@ export class BlockComponent implements OnInit, OnDestroy {
this.auditSubscription = block$.pipe(
startWith(null),
pairwise(),
switchMap(([prevBlock, block]) => this.apiService.getBlockAudit$(block.id)
.pipe(
catchError((err) => {
this.overviewError = err;
return of([]);
})
)
switchMap(([prevBlock, block]) => {
this.isLoadingAudit = true;
this.blockAudit = null;
return this.apiService.getBlockAudit$(block.id)
.pipe(
catchError((err) => {
this.overviewError = err;
this.isLoadingAudit = false;
return of([]);
})
);
}
),
filter((response) => response != null),
map((response) => {
@@ -375,12 +381,14 @@ export class BlockComponent implements OnInit, OnDestroy {
console.log(err);
this.error = err;
this.isLoadingOverview = false;
this.isLoadingAudit = false;
return of(null);
}),
).subscribe((blockAudit) => {
this.blockAudit = blockAudit;
this.setupBlockGraphs();
this.isLoadingOverview = false;
this.isLoadingAudit = false;
});
}

View File

@@ -14,7 +14,7 @@
i18n-ngbTooltip="mining.pool-name" ngbTooltip="Pool" placement="bottom" #miningpool [disableTooltip]="!isEllipsisActive(miningpool)">Pool</th>
<th class="timestamp" i18n="latest-blocks.timestamp" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'">Timestamp</th>
<th class="mined" i18n="latest-blocks.mined" *ngIf="!widget" [class]="indexingAvailable ? '' : 'legacy'">Mined</th>
<th *ngIf="indexingAvailable" class="health text-left" i18n="latest-blocks.health" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"
<th *ngIf="indexingAvailable" class="health text-right" i18n="latest-blocks.health" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"
i18n-ngbTooltip="latest-blocks.health" ngbTooltip="Health" placement="bottom" #health [disableTooltip]="!isEllipsisActive(health)">Health</th>
<th *ngIf="indexingAvailable" class="reward text-right" i18n="latest-blocks.reward" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}"
i18n-ngbTooltip="latest-blocks.reward" ngbTooltip="Reward" placement="bottom" #reward [disableTooltip]="!isEllipsisActive(reward)">Reward</th>
@@ -46,16 +46,22 @@
<app-time-since [time]="block.timestamp" [fastRender]="true"></app-time-since>
</td>
<td *ngIf="indexingAvailable" class="health text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}">
<a class="clear-link" [routerLink]="auditScores[block.id] != null ? ['/block/' | relativeUrl, block.id] : null">
<div class="progress progress-health">
<div class="progress-bar progress-bar-health" role="progressbar"
[ngStyle]="{'width': (100 - (auditScores[block.id] || 0)) + '%' }"></div>
<div class="progress-text">
<span *ngIf="auditScores[block.id] != null;">{{ auditScores[block.id] }}%</span>
<span *ngIf="auditScores[block.id] == null">~</span>
</div>
</div>
</a>
<a
class="health-badge badge"
[class.badge-success]="auditScores[block.id] >= 99"
[class.badge-warning]="auditScores[block.id] >= 75 && auditScores[block.id] < 99"
[class.badge-danger]="auditScores[block.id] < 75"
[routerLink]="auditScores[block.id] != null ? ['/block/' | relativeUrl, block.id] : null"
*ngIf="auditScores[block.id] != null; else nullHealth"
>{{ auditScores[block.id] }}%</a>
<ng-template #nullHealth>
<ng-container *ngIf="!loadingScores; else loadingHealth">
<span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span>
</ng-container>
</ng-template>
<ng-template #loadingHealth>
<span class="skeleton-loader" style="max-width: 60px"></span>
</ng-template>
</td>
<td *ngIf="indexingAvailable" class="reward text-right" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}">
<app-amount [satoshis]="block.extras.reward" [noFiat]="true" digitsInfo="1.2-2"></app-amount>

View File

@@ -23,6 +23,7 @@ export class BlocksList implements OnInit, OnDestroy {
indexingAvailable = false;
isLoading = true;
loadingScores = true;
fromBlockHeight = undefined;
paginationMaxSize: number;
page = 1;
@@ -113,6 +114,7 @@ export class BlocksList implements OnInit, OnDestroy {
if (this.indexingAvailable) {
this.auditScoreSubscription = this.fromHeightSubject.pipe(
switchMap((fromBlockHeight) => {
this.loadingScores = true;
return this.apiService.getBlockAuditScores$(this.page === 1 ? undefined : fromBlockHeight)
.pipe(
catchError(() => {
@@ -124,6 +126,7 @@ export class BlocksList implements OnInit, OnDestroy {
Object.values(scores).forEach(score => {
this.auditScores[score.hash] = score?.matchRate != null ? score.matchRate : null;
});
this.loadingScores = false;
});
this.latestScoreSubscription = this.stateService.blocks$.pipe(

View File

@@ -91,6 +91,9 @@ export class TransactionsListComponent implements OnInit, OnChanges {
filter(() => this.stateService.env.LIGHTNING),
switchMap((txIds) => this.apiService.getChannelByTxIds$(txIds)),
tap((channels) => {
if (!this.transactions) {
return;
}
const transactions = this.transactions.filter((tx) => !tx._channels);
channels.forEach((channel, i) => {
transactions[i]._channels = channel;

View File

@@ -88,7 +88,7 @@
<stop offset="100%" stop-color="transparent" />
</linearGradient>
</defs>
<path [attr.d]="middle.path" class="line middle" [style]="middle.style"/>
<path *ngIf="hasLine" [attr.d]="middle.path" class="line middle" [style]="middle.style"/>
<ng-container *ngFor="let input of inputs; let i = index">
<path *ngIf="connectors && !inputData[i].coinbase && !inputData[i].pegin"
[attr.d]="input.connectorPath"
@@ -106,7 +106,7 @@
(pointerout)="onBlur($event, 'input', i);"
(click)="onClick($event, 'input', inputData[i].index);"
/>
<path
<path *ngIf="!input.zeroValue"
[attr.d]="input.path"
class="line {{input.class}}"
[class.highlight]="inputIndex != null && inputData[i].index === inputIndex"
@@ -116,6 +116,16 @@
(pointerout)="onBlur($event, 'input', i);"
(click)="onClick($event, 'input', inputData[i].index);"
/>
<path *ngIf="input.zeroValue"
[attr.d]="input.path"
class="line {{input.class}} zerovalue"
[class.highlight]="inputIndex != null && inputData[i].index === inputIndex"
[class.zerovalue]="input.zeroValue"
[style]="input.style"
(pointerover)="onHover($event, 'input', i);"
(pointerout)="onBlur($event, 'input', i);"
(click)="onClick($event, 'input', inputData[i].index);"
/>
</ng-container>
<ng-container *ngFor="let output of outputs; let i = index">
<path *ngIf="connectors && outspends[outputData[i].index]?.spent"

View File

@@ -68,6 +68,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
outspends: Outspend[] = [];
zeroValueWidth = 60;
zeroValueThickness = 20;
hasLine: boolean;
outspendsSubscription: Subscription;
refreshOutspends$: ReplaySubject<string> = new ReplaySubject();
@@ -162,7 +163,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
let truncatedInputs = this.tx.vin.map((v, i) => {
return {
type: 'input',
value: v?.prevout?.value,
value: v?.prevout?.value || (v?.is_coinbase && !totalValue ? 0 : undefined),
txid: v.txid,
vout: v.vout,
address: v?.prevout?.scriptpubkey_address || v?.prevout?.scriptpubkey_type?.toUpperCase(),
@@ -198,6 +199,9 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
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)
&& this.outputs.reduce((line, put) => line || !put.zeroValue, false);
}
calcTotalValue(tx: Transaction): number {
@@ -278,6 +282,9 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
lineParams.forEach((line, i) => {
if (xputs[i].value === 0) {
line.outerY = lastOuter + (this.zeroValueThickness / 2);
if (xputs.length === 1) {
line.outerY = (this.height / 2);
}
lastOuter += this.zeroValueThickness + spacing;
return;
}

View File

@@ -118,7 +118,7 @@ export class NodesNetworksChartComponent implements OnInit {
color: 'grey',
fontSize: 15
},
text: $localize`Indexing in progess`,
text: $localize`Indexing in progress`,
left: 'center',
top: 'center',
};

View File

@@ -109,7 +109,7 @@ export class LightningStatisticsChartComponent implements OnInit {
color: 'grey',
fontSize: 15
},
text: $localize`Indexing in progess`,
text: $localize`Indexing in progress`,
left: 'center',
top: 'center'
};