Transaction details template refactor
This commit is contained in:
parent
eee2385d0d
commit
2df476406d
@ -40,64 +40,39 @@
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<ng-template [ngIf]="!isLoadingTx && !error">
|
||||
|
||||
<ng-template [ngIf]="tx?.status?.confirmed" [ngIfElse]="unconfirmedTemplate">
|
||||
|
||||
<div class="box">
|
||||
<div class="row">
|
||||
@if (!error) {
|
||||
<div class="box">
|
||||
<div class="row">
|
||||
@if (isMobile) {
|
||||
<div class="col-sm">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td i18n="block.timestamp">Timestamp</td>
|
||||
<td>
|
||||
‎{{ tx.status.block_time * 1000 | date:'yyyy-MM-dd HH:mm' }}
|
||||
<div class="lg-inline">
|
||||
<i class="symbol">(<app-time kind="since" [time]="tx.status.block_time" [fastRender]="true"></app-time>)</i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<ng-template [ngIf]="transactionTime > 0">
|
||||
<tr>
|
||||
<td i18n="transaction.confirmed|Transaction Confirmed state">Confirmed</td>
|
||||
<td><app-time kind="span" [time]="tx.status.block_time - transactionTime" [fastRender]="true" [relative]="true"></app-time></td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet' && featuresEnabled">
|
||||
<td class="td-width" i18n="transaction.features|Transaction features">Features</td>
|
||||
<td>
|
||||
<app-tx-features [tx]="tx"></app-tx-features>
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngIf="network === '' && auditStatus">
|
||||
<td class="td-width" i18n="block.toggle-audit|Toggle Audit">Audit</td>
|
||||
<td *ngIf="pool" class="wrap-cell">
|
||||
<ng-container>
|
||||
<span *ngIf="auditStatus.coinbase; else expected" class="badge badge-primary mr-1" i18n="transactions-list.coinbase">Coinbase</span>
|
||||
<ng-template #expected><span *ngIf="auditStatus.expected; else seen" class="badge badge-success mr-1" i18n-ngbTooltip="Expected in block tooltip" ngbTooltip="This transaction was projected to be included in the block" placement="bottom" i18n="tx-features.tag.expected|Expected in Block">Expected in Block</span></ng-template>
|
||||
<ng-template #seen><span *ngIf="auditStatus.seen; else notSeen" class="badge badge-success mr-1" i18n-ngbTooltip="Seen in mempool tooltip" ngbTooltip="This transaction was seen in the mempool prior to mining" placement="bottom" i18n="tx-features.tag.seen|Seen in Mempool">Seen in Mempool</span></ng-template>
|
||||
<ng-template #notSeen><span *ngIf="!auditStatus.conflict" class="badge badge-warning mr-1" i18n-ngbTooltip="Not seen in mempool tooltip" ngbTooltip="This transaction was missing from our mempool prior to mining" placement="bottom" i18n="tx-features.tag.not-seen|Not seen in Mempool">Not seen in Mempool</span></ng-template>
|
||||
<span *ngIf="auditStatus.added" class="badge badge-warning mr-1" i18n-ngbTooltip="Added transaction tooltip" ngbTooltip="This transaction may have been added out-of-band" placement="bottom" i18n="tx-features.tag.added|Added">Added</span>
|
||||
<span *ngIf="auditStatus.prioritized" class="badge badge-warning mr-1" i18n-ngbTooltip="Prioritized transaction tooltip" ngbTooltip="This transaction may have been prioritized out-of-band" placement="bottom" i18n="tx-features.tag.prioritized|Prioritized">Prioritized</span>
|
||||
<span *ngIf="auditStatus.conflict" class="badge badge-warning mr-1" i18n-ngbTooltip="Conflict in mempool tooltip" ngbTooltip="This transaction conflicted with another version in our mempool" placement="bottom" i18n="tx-features.tag.conflict|Conflict">Conflict</span>
|
||||
</ng-container>
|
||||
</td>
|
||||
<td *ngIf="!pool">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<ng-container *ngTemplateOutlet="goggles"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="detailsLeft"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="detailsRight"></ng-container>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="col-sm">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<ng-container *ngTemplateOutlet="detailsLeft"></ng-container>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<ng-container *ngTemplateOutlet="feeTable"></ng-container>
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<ng-container *ngTemplateOutlet="detailsRight"></ng-container>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="!isLoadingTx && !error">
|
||||
|
||||
<!-- Accelerator -->
|
||||
<ng-container *ngIf="!tx?.status?.confirmed && showAccelerationSummary">
|
||||
@ -113,69 +88,6 @@
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #unconfirmedTemplate>
|
||||
|
||||
<div class="box">
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<ng-template [ngIf]="transactionTime !== 0">
|
||||
<tr *ngIf="transactionTime === -1; else firstSeenTmpl">
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
<ng-template #firstSeenTmpl>
|
||||
<tr>
|
||||
<td i18n="transaction.first-seen|Transaction first seen">First seen</td>
|
||||
<td><i><app-time kind="since" [time]="transactionTime" [fastRender]="true"></app-time></i></td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
<tr *ngIf="!replaced && !isCached">
|
||||
<td class="td-width align-items-center align-middle" i18n="transaction.eta|Transaction ETA">ETA</td>
|
||||
<td>
|
||||
<ng-template [ngIf]="this.mempoolPosition?.block == null" [ngIfElse]="estimationTmpl">
|
||||
<span class="skeleton-loader"></span>
|
||||
</ng-template>
|
||||
<ng-template #estimationTmpl>
|
||||
<ng-template [ngIf]="this.mempoolPosition.block >= 7" [ngIfElse]="belowBlockLimit">
|
||||
<span [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'etaDeepMempool d-flex justify-content-end align-items-center' : ''">
|
||||
<span i18n="transaction.eta.in-several-hours|Transaction ETA in several hours or more">In several hours (or more)</span>
|
||||
<a *ngIf="!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration" [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerateDeepMempool btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
|
||||
</span>
|
||||
</ng-template>
|
||||
<ng-template #belowBlockLimit>
|
||||
<ng-template [ngIf]="network === 'liquid' || network === 'liquidtestnet'" [ngIfElse]="timeEstimateDefault">
|
||||
<app-time kind="until" [time]="(60 * 1000 * this.mempoolPosition.block) + now" [fastRender]="false" [fixedRender]="true"></app-time>
|
||||
</ng-template>
|
||||
<ng-template #timeEstimateDefault>
|
||||
<span class="eta justify-content-end" [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'd-flex align-items-center' : ''">
|
||||
<app-time kind="until" *ngIf="(da$ | async) as da;" [time]="da.adjustedTimeAvg * (this.mempoolPosition.block + 1) + now + da.timeOffset" [fastRender]="false" [fixedRender]="true"></app-time>
|
||||
<a *ngIf="!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration" [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerate btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
|
||||
</span>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet'" id="acceleratePreviewAnchor">
|
||||
<td class="td-width" i18n="transaction.features|Transaction Features">Features</td>
|
||||
<td>
|
||||
<app-tx-features [tx]="tx"></app-tx-features>
|
||||
</td>
|
||||
</tr>
|
||||
<ng-container *ngTemplateOutlet="goggles"></ng-container>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<ng-container *ngTemplateOutlet="feeTable"></ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template [ngIf]="showCpfpDetails">
|
||||
<br>
|
||||
|
||||
@ -364,42 +276,7 @@
|
||||
</ng-template>
|
||||
|
||||
<ng-template [ngIf]="(isLoadingTx && !error) || loadingCachedTx">
|
||||
|
||||
<div class="box">
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="td-width"><span class="skeleton-loader"></span></td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="td-width"><span class="skeleton-loader"></span></td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<ng-container *ngIf="flowEnabled">
|
||||
<div class="title">
|
||||
<h2 i18n="transaction.flow|Transaction flow">Flow</h2>
|
||||
@ -525,65 +402,264 @@
|
||||
|
||||
</div>
|
||||
|
||||
<ng-template #feeTable>
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr *ngIf="isMobile && (network === 'liquid' || network === 'liquidtestnet' || !featuresEnabled || network === '')"></tr>
|
||||
<ng-template #detailsLeft>
|
||||
@if (tx?.status?.confirmed) {
|
||||
<ng-container *ngTemplateOutlet="timestampRow"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="confirmedAfterRow"></ng-container>
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="firstSeenRow"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="etaRow"></ng-container>
|
||||
}
|
||||
<ng-container *ngTemplateOutlet="featuresRow"></ng-container>
|
||||
@if (tx?.status?.confirmed) {
|
||||
<ng-container *ngTemplateOutlet="auditRow"></ng-container>
|
||||
}
|
||||
<ng-container *ngTemplateOutlet="gogglesRow"></ng-container>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #detailsRight>
|
||||
<ng-container *ngTemplateOutlet="feeRow"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="feeRateRow"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="effectiveRateRow"></ng-container>
|
||||
@if (tx?.status?.confirmed) {
|
||||
<ng-container *ngTemplateOutlet="minerRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #timestampRow>
|
||||
@if (!isLoadingTx) {
|
||||
<tr>
|
||||
<td i18n="block.timestamp">Timestamp</td>
|
||||
<td>
|
||||
‎{{ tx.status.block_time * 1000 | date:'yyyy-MM-dd HH:mm' }}
|
||||
<div class="lg-inline">
|
||||
<i class="symbol">(<app-time kind="since" [time]="tx.status.block_time" [fastRender]="true"></app-time>)</i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #confirmedAfterRow>
|
||||
@if (!isLoadingTx) {
|
||||
@if (transactionTime > 0) {
|
||||
<tr>
|
||||
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
|
||||
<td>{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span></td>
|
||||
<td i18n="transaction.confirmed|Transaction Confirmed state">Confirmed</td>
|
||||
<td><app-time kind="span" [time]="tx.status.block_time - transactionTime" [fastRender]="true" [relative]="true"></app-time></td>
|
||||
</tr>
|
||||
}
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #firstSeenRow>
|
||||
@if (!isLoadingTx && transactionTime !== -1) {
|
||||
<tr>
|
||||
<td i18n="transaction.first-seen|Transaction first seen">First seen</td>
|
||||
<td><i><app-time kind="since" [time]="transactionTime" [fastRender]="true"></app-time></i></td>
|
||||
</tr>
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #featuresRow>
|
||||
@if (network !== 'liquid' && network !== 'liquidtestnet') {
|
||||
@if (!isLoadingTx) {
|
||||
@if (featuresEnabled) {
|
||||
<tr>
|
||||
<td class="td-width" i18n="transaction.features|Transaction features">Features</td>
|
||||
<td>
|
||||
<app-tx-features [tx]="tx"></app-tx-features>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #auditRow>
|
||||
@if (network === '') {
|
||||
@if (!isLoadingTx) {
|
||||
@if (auditStatus) {
|
||||
<tr>
|
||||
<td class="td-width" i18n="block.toggle-audit|Toggle Audit">Audit</td>
|
||||
<td class="wrap-cell">
|
||||
<ng-container>
|
||||
@if (auditStatus.coinbase) {
|
||||
<span class="badge badge-primary mr-1" i18n="transactions-list.coinbase">Coinbase</span>
|
||||
} @else if (auditStatus.expected) {
|
||||
<span class="badge badge-success mr-1" i18n-ngbTooltip="Expected in block tooltip" ngbTooltip="This transaction was projected to be included in the block" placement="bottom" i18n="tx-features.tag.expected|Expected in Block">Expected in Block</span>
|
||||
} @else if (auditStatus.seen) {
|
||||
<span class="badge badge-success mr-1" i18n-ngbTooltip="Seen in mempool tooltip" ngbTooltip="This transaction was seen in the mempool prior to mining" placement="bottom" i18n="tx-features.tag.seen|Seen in Mempool">Seen in Mempool</span>
|
||||
} @else if (!auditStatus.conflict) {
|
||||
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Not seen in mempool tooltip" ngbTooltip="This transaction was missing from our mempool prior to mining" placement="bottom" i18n="tx-features.tag.not-seen|Not seen in Mempool">Not seen in Mempool</span>
|
||||
}
|
||||
@if (auditStatus.added) {
|
||||
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Added transaction tooltip" ngbTooltip="This transaction may have been added out-of-band" placement="bottom" i18n="tx-features.tag.added|Added">Added</span>
|
||||
}
|
||||
@if (auditStatus.prioritized) {
|
||||
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Prioritized transaction tooltip" ngbTooltip="This transaction may have been prioritized out-of-band" placement="bottom" i18n="tx-features.tag.prioritized|Prioritized">Prioritized</span>
|
||||
}
|
||||
@if (auditStatus.conflict) {
|
||||
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Conflict in mempool tooltip" ngbTooltip="This transaction conflicted with another version in our mempool" placement="bottom" i18n="tx-features.tag.conflict|Conflict">Conflict</span>
|
||||
}
|
||||
</ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #etaRow>
|
||||
@if (!isLoadingTx) {
|
||||
@if (!replaced && !isCached) {
|
||||
<tr>
|
||||
<td i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
|
||||
<td class="td-width align-items-center align-middle" i18n="transaction.eta|Transaction ETA">ETA</td>
|
||||
<td>
|
||||
<app-fee-rate [fee]="tx.feePerVsize"></app-fee-rate>
|
||||
<ng-template [ngIf]="tx?.status?.confirmed">
|
||||
|
||||
<app-tx-fee-rating *ngIf="tx.fee && !hasEffectiveFeeRate && !accelerationInfo" [tx]="tx"></app-tx-fee-rating>
|
||||
</ng-template>
|
||||
@if (this.mempoolPosition?.block == null) {
|
||||
<span class="skeleton-loader"></span>
|
||||
} @else if (this.mempoolPosition.block >= 7) {
|
||||
<span [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'etaDeepMempool d-flex justify-content-end align-items-center' : ''">
|
||||
<span i18n="transaction.eta.in-several-hours|Transaction ETA in several hours or more">In several hours (or more)</span>
|
||||
@if (!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) {
|
||||
<a [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerateDeepMempool btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
|
||||
}
|
||||
</span>
|
||||
} @else if (network === 'liquid' || network === 'liquidtestnet') {
|
||||
<app-time kind="until" [time]="(60 * 1000 * this.mempoolPosition.block) + now" [fastRender]="false" [fixedRender]="true"></app-time>
|
||||
} @else {
|
||||
<span class="eta justify-content-end" [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'd-flex align-items-center' : ''">
|
||||
<app-time kind="until" *ngIf="(da$ | async) as da;" [time]="da.adjustedTimeAvg * (this.mempoolPosition.block + 1) + now + da.timeOffset" [fastRender]="false" [fixedRender]="true"></app-time>
|
||||
@if (!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) {
|
||||
<a [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerate btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
|
||||
}
|
||||
</span>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngIf="(cpfpInfo && hasEffectiveFeeRate) || accelerationInfo">
|
||||
<td *ngIf="tx.acceleration || accelerationInfo" i18n="transaction.accelerated-fee-rate|Accelerated transaction fee rate">Accelerated fee rate</td>
|
||||
<td *ngIf="!(tx.acceleration || accelerationInfo)" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
||||
}
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #gogglesRow>
|
||||
@if (!isLoadingTx) {
|
||||
@if (((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) || filters.length) {
|
||||
<tr>
|
||||
<td class="td-width">
|
||||
<span class="goggles-icon"><app-svg-images name="goggles" width="100%" height="100%"></app-svg-images></span>
|
||||
</td>
|
||||
<td class="wrap-cell">
|
||||
@if ((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) {
|
||||
<span class="badge badge-accelerated mr-1" i18n="transaction.audit.accelerated">Accelerated</span>
|
||||
}
|
||||
<ng-container *ngFor="let filter of filters;">
|
||||
<span class="badge badge-primary filter-tag mr-1">{{ filter.label }}</span>
|
||||
</ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #feeRow>
|
||||
@if (!isLoadingTx) {
|
||||
<tr>
|
||||
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
|
||||
<td>{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span></td>
|
||||
</tr>
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #feeRateRow>
|
||||
@if (!isLoadingTx) {
|
||||
<tr>
|
||||
<td i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
|
||||
<td>
|
||||
<app-fee-rate [fee]="tx.feePerVsize"></app-fee-rate>
|
||||
@if (tx?.status?.confirmed && tx.fee && !hasEffectiveFeeRate && !accelerationInfo) {
|
||||
|
||||
<app-tx-fee-rating [tx]="tx"></app-tx-fee-rating>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #effectiveRateRow>
|
||||
@if (!isLoadingTx) {
|
||||
@if ((cpfpInfo && hasEffectiveFeeRate) || accelerationInfo) {
|
||||
<tr>
|
||||
@if (tx.acceleration || accelerationInfo) {
|
||||
<td i18n="transaction.accelerated-fee-rate|Accelerated transaction fee rate">Accelerated fee rate</td>
|
||||
} @else {
|
||||
<td i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
||||
}
|
||||
<td>
|
||||
<div class="effective-fee-container">
|
||||
<app-fee-rate *ngIf="accelerationInfo" [fee]="accelerationInfo.acceleratedFee" [weight]="accelerationInfo.effectiveVsize * 4"></app-fee-rate>
|
||||
<app-fee-rate *ngIf="!accelerationInfo" [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
|
||||
@if (accelerationInfo) {
|
||||
<app-fee-rate [fee]="accelerationInfo.acceleratedFee" [weight]="accelerationInfo.effectiveVsize * 4"></app-fee-rate>
|
||||
} @else {
|
||||
<app-fee-rate [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
|
||||
}
|
||||
|
||||
<ng-template [ngIf]="tx?.status?.confirmed || tx.acceleration || accelerationInfo">
|
||||
<app-tx-fee-rating *ngIf="!(tx.acceleration || accelerationInfo) && (tx.fee || tx.effectiveFeePerVsize)" class="ml-2 mr-2 effective-fee-rating" [tx]="tx"></app-tx-fee-rating>
|
||||
</ng-template>
|
||||
@if (tx?.status?.confirmed && !tx.acceleration && !accelerationInfo && tx.fee && tx.effectiveFeePerVsize) {
|
||||
<app-tx-fee-rating class="ml-2 mr-2 effective-fee-rating" [tx]="tx"></app-tx-fee-rating>
|
||||
}
|
||||
</div>
|
||||
<button *ngIf="cpfpInfo?.bestDescendant || cpfpInfo?.descendants?.length || cpfpInfo?.ancestors?.length" type="button" class="btn btn-outline-info btn-sm btn-small-height float-right" (click)="showCpfpDetails = !showCpfpDetails">CPFP <fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon></button>
|
||||
@if (hasCpfp) {
|
||||
<button type="button" class="btn btn-outline-info btn-sm btn-small-height float-right" (click)="showCpfpDetails = !showCpfpDetails">CPFP <fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon></button>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngIf="network === '' && tx?.status?.confirmed">
|
||||
<td class="td-width" i18n="block.miner">Miner</td>
|
||||
<td *ngIf="pool" class="wrap-cell">
|
||||
<a placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, pool.slug]" class="badge mr-1"
|
||||
[class]="pool.slug === 'unknown' ? 'badge-secondary' : 'badge-primary'">
|
||||
{{ pool.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td *ngIf="!pool">
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #goggles>
|
||||
<tr *ngIf="((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) || filters.length">
|
||||
<td class="td-width">
|
||||
<span class="goggles-icon"><app-svg-images name="goggles" width="100%" height="100%"></app-svg-images></span>
|
||||
</td>
|
||||
<td class="wrap-cell">
|
||||
<span *ngIf="((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration))" class="badge badge-accelerated mr-1" i18n="transaction.audit.accelerated">Accelerated</span>
|
||||
<ng-container *ngFor="let filter of filters;">
|
||||
<span class="badge badge-primary filter-tag mr-1">{{ filter.label }}</span>
|
||||
</ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
<ng-template #minerRow>
|
||||
@if (network === '') {
|
||||
@if (!isLoadingTx) {
|
||||
<tr>
|
||||
<td class="td-width" i18n="block.miner">Miner</td>
|
||||
@if (pool) {
|
||||
<td class="wrap-cell">
|
||||
<a placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, pool.slug]" class="badge mr-1"
|
||||
[class]="pool.slug === 'unknown' ? 'badge-secondary' : 'badge-primary'">
|
||||
{{ pool.name }}
|
||||
</a>
|
||||
</td>
|
||||
} @else {
|
||||
<td>
|
||||
<span class="skeleton-loader"></span>
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
} @else {
|
||||
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
|
||||
}
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<ng-template #skeletonDetailsRow>
|
||||
<tr>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
</ng-template>
|
@ -87,6 +87,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
rbfReplaces: string[];
|
||||
rbfInfo: RbfTree;
|
||||
cpfpInfo: CpfpInfo | null;
|
||||
hasCpfp: boolean = false;
|
||||
accelerationInfo: Acceleration | null = null;
|
||||
sigops: number | null;
|
||||
adjustedVsize: number | null;
|
||||
@ -491,10 +492,10 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
txFeePerVSize: tx.effectiveFeePerVsize,
|
||||
mempoolPosition: this.mempoolPosition,
|
||||
});
|
||||
this.cpfpInfo = {
|
||||
this.setCpfpInfo({
|
||||
ancestors: tx.ancestors,
|
||||
bestDescendant: tx.bestDescendant,
|
||||
};
|
||||
});
|
||||
const hasRelatives = !!(tx.ancestors?.length || tx.bestDescendant);
|
||||
this.hasEffectiveFeeRate = hasRelatives || (tx.effectiveFeePerVsize && (Math.abs(tx.effectiveFeePerVsize - tx.feePerVsize) > 0.01));
|
||||
} else {
|
||||
@ -646,6 +647,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
setCpfpInfo(cpfpInfo: CpfpInfo): void {
|
||||
if (!cpfpInfo || !this.tx) {
|
||||
this.cpfpInfo = null;
|
||||
this.hasCpfp = false;
|
||||
this.hasEffectiveFeeRate = false;
|
||||
return;
|
||||
}
|
||||
@ -675,6 +677,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.sigops = this.cpfpInfo.sigops;
|
||||
this.adjustedVsize = this.cpfpInfo.adjustedVsize;
|
||||
}
|
||||
this.hasCpfp =!!(this.cpfpInfo && (this.cpfpInfo.bestDescendant || this.cpfpInfo.descendants?.length || this.cpfpInfo.ancestors?.length));
|
||||
this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user