Merge pull request #4913 from mempool/mononaut/simple-acceleration-mode

Simplified acceleration mode for mobile
This commit is contained in:
wiz 2024-04-08 17:06:20 +09:00 committed by GitHub
commit 47cc74a351
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 255 additions and 98 deletions

View File

@ -65,24 +65,26 @@
</div> </div>
</div> </div>
<br> <br>
<h5 i18n="accelerator.pay-how-much">How much more are you willing to pay?</h5> @if (paymentType !== 'cashapp') {
<div class="row"> <h5 i18n="accelerator.pay-how-much">How much more are you willing to pay?</h5>
<div class="col"> <div class="row">
<small class="form-text text-muted mb-2" i18n="accelerator.transaction-fee-description">Choose the maximum extra transaction fee you're willing to pay to get into the next block.</small> <div class="col">
<div class="form-group"> <small class="form-text text-muted mb-2" i18n="accelerator.transaction-fee-description">Choose the maximum extra transaction fee you're willing to pay to get into the next block.</small>
<div class="fee-card"> <div class="form-group">
<div class="d-flex mb-0"> <div class="fee-card">
<ng-container *ngFor="let option of maxRateOptions"> <div class="d-flex mb-0">
<button type="button" class="btn btn-primary flex-grow-1 btn-border btn-sm feerate" [class]="{active: selectFeeRateIndex === option.index}" (click)="setUserBid(option)"> <ng-container *ngFor="let option of maxRateOptions">
<span class="fee">{{ option.fee + estimate.mempoolBaseFee + estimate.vsizeFee | number }} <span class="symbol" i18n="shared.sats">sats</span></span> <button type="button" class="btn btn-primary flex-grow-1 btn-border btn-sm feerate" [class]="{active: selectFeeRateIndex === option.index}" (click)="setUserBid(option)">
<span class="rate">~<app-fee-rate [fee]="option.rate" rounding="1.0-0"></app-fee-rate></span> <span class="fee">{{ option.fee + estimate.mempoolBaseFee + estimate.vsizeFee | number }} <span class="symbol" i18n="shared.sats">sats</span></span>
</button> <span class="rate">~<app-fee-rate [fee]="option.rate" rounding="1.0-0"></app-fee-rate></span>
</ng-container> </button>
</ng-container>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> }
<h5>Acceleration summary</h5> <h5>Acceleration summary</h5>
<div class="row mb-3"> <div class="row mb-3">
@ -90,27 +92,51 @@
<table class="table table-borderless table-border table-dark table-accelerator"> <table class="table table-borderless table-border table-dark table-accelerator">
<tbody> <tbody>
<!-- ESTIMATED FEE --> <!-- ESTIMATED FEE -->
<ng-container> @if (paymentType === 'cashapp') {
<tr class="group-first"> <ng-container>
<td class="item" i18n="accelerator.next-block-rate">Next block market rate</td> <tr class="group-first">
<td class="amt" style="font-size: 16px"> <td class="item" i18n="accelerator.boost-rate">Boost rate</td>
{{ estimate.targetFeeRate | number : '1.0-0' }} <td class="amt" style="font-size: 16px">
</td> {{ maxRateOptions[selectFeeRateIndex].rate | number : '1.0-0' }}
<td class="units"><span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td> </td>
</tr> <td class="units"><span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
<tr class="info"> </tr>
<td class="info"> <tr class="info">
<i><small i18n="accelerator.estimated-extra-fee-required">Estimated extra fee required</small></i> <td class="info">
</td> <i><small i18n="accelerator.estimated-extra-fee-required">Boost fee</small></i>
<td class="amt"> </td>
{{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }} <td class="amt">
</td> {{ maxRateOptions[selectFeeRateIndex].fee | number }}
<td class="units"> </td>
<span class="symbol" i18n="shared.sats">sats</span> <td class="units">
<span class="fiat ml-1"><app-fiat [value]="math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee)"></app-fiat></span> <span class="symbol" i18n="shared.sats">sats</span>
</td> <span class="fiat ml-1"><app-fiat [value]="maxRateOptions[selectFeeRateIndex].fee"></app-fiat></span>
</tr> </td>
</ng-container> </tr>
</ng-container>
} @else {
<ng-container>
<tr class="group-first">
<td class="item" i18n="accelerator.next-block-rate">Next block market rate</td>
<td class="amt" style="font-size: 16px">
{{ estimate.targetFeeRate | number : '1.0-0' }}
</td>
<td class="units"><span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
</tr>
<tr class="info">
<td class="info">
<i><small i18n="accelerator.estimated-extra-fee-required">Estimated extra fee required</small></i>
</td>
<td class="amt">
{{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }}
</td>
<td class="units">
<span class="symbol" i18n="shared.sats">sats</span>
<span class="fiat ml-1"><app-fiat [value]="math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee)"></app-fiat></span>
</td>
</tr>
</ng-container>
}
<!-- MEMPOOL BASE FEE --> <!-- MEMPOOL BASE FEE -->
<tr> <tr>
@ -141,53 +167,76 @@
</td> </td>
</tr> </tr>
<!-- NEXT BLOCK ESTIMATE -->
<ng-container> @if (paymentType === 'cashapp') {
<tr class="group-first" style="border-top: 1px dashed grey; border-collapse: collapse;"> <!-- FIXED COST -->
<td class="item"> <ng-container>
<b style="background-color: #5E35B1" class="p-1 pl-0" i18n="accelerator.estimated-cost">Estimated acceleration cost</b> <tr class="group-first group-last" style="border-top: 1px solid lightgrey; border-collapse: collapse;">
</td> <td class="item">
<td class="amt"> <b style="background-color: #105fb0;" class="p-1 pl-0" i18n="accelerator.total-cost">Total cost</b>
<span style="background-color: #5E35B1" class="p-1 pl-0"> </td>
{{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }} <td class="amt">
</span> <span style="background-color: #105fb0" class="p-1 pl-0">
</td> {{ maxCost | number }}
<td class="units"> </span>
<span class="symbol" i18n="shared.sats">sats</span> </td>
<span class="fiat ml-1"><app-fiat [value]="estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee"></app-fiat></span> <td class="units">
</td> <span class="symbol" i18n="shared.sats">sats</span>
</tr> <span class="fiat ml-1">
<tr class="info group-last" style="border-bottom: 1px solid lightgrey"> <app-fiat [value]="maxCost" [colorClass]="'green-color'"></app-fiat>
<td class="info" colspan=3> </span>
<i><small><ng-container *ngTemplateOutlet="acceleratedTo; context: {$implicit: estimate.targetFeeRate }"></ng-container></small></i> </td>
</td> </tr>
</tr> </ng-container>
</ng-container> } @else {
<!-- NEXT BLOCK ESTIMATE -->
<ng-container>
<tr class="group-first" style="border-top: 1px dashed grey; border-collapse: collapse;">
<td class="item">
<b style="background-color: #5E35B1" class="p-1 pl-0" i18n="accelerator.estimated-cost">Estimated acceleration cost</b>
</td>
<td class="amt">
<span style="background-color: #5E35B1" class="p-1 pl-0">
{{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }}
</span>
</td>
<td class="units">
<span class="symbol" i18n="shared.sats">sats</span>
<span class="fiat ml-1"><app-fiat [value]="estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee"></app-fiat></span>
</td>
</tr>
<tr class="info group-last" style="border-bottom: 1px solid lightgrey">
<td class="info" colspan=3>
<i><small><ng-container *ngTemplateOutlet="acceleratedTo; context: {$implicit: estimate.targetFeeRate }"></ng-container></small></i>
</td>
</tr>
</ng-container>
<!-- MAX COST --> <!-- MAX COST -->
<ng-container> <ng-container>
<tr class="group-first"> <tr class="group-first">
<td class="item"> <td class="item">
<b style="background-color: #105fb0;" class="p-1 pl-0" i18n="accelerator.maximum-cost">Maximum acceleration cost</b> <b style="background-color: #105fb0;" class="p-1 pl-0" i18n="accelerator.maximum-cost">Maximum acceleration cost</b>
</td> </td>
<td class="amt"> <td class="amt">
<span style="background-color: #105fb0" class="p-1 pl-0"> <span style="background-color: #105fb0" class="p-1 pl-0">
{{ maxCost | number }} {{ maxCost | number }}
</span> </span>
</td> </td>
<td class="units"> <td class="units">
<span class="symbol" i18n="shared.sats">sats</span> <span class="symbol" i18n="shared.sats">sats</span>
<span class="fiat ml-1"> <span class="fiat ml-1">
<app-fiat [value]="maxCost" [colorClass]="estimate.userBalance < maxCost ? 'red-color' : 'green-color'"></app-fiat> <app-fiat [value]="maxCost" [colorClass]="estimate.userBalance < maxCost ? 'red-color' : 'green-color'"></app-fiat>
</span> </span>
</td> </td>
</tr> </tr>
<tr class="info group-last"> <tr class="info group-last">
<td class="info" colspan=3> <td class="info" colspan=3>
<i><small><ng-container *ngTemplateOutlet="acceleratedTo; context: {$implicit: (estimate.txSummary.effectiveFee + userBid) / estimate.txSummary.effectiveVsize }"></ng-container></small></i> <i><small><ng-container *ngTemplateOutlet="acceleratedTo; context: {$implicit: (estimate.txSummary.effectiveFee + userBid) / estimate.txSummary.effectiveVsize }"></ng-container></small></i>
</td> </td>
</tr> </tr>
</ng-container> </ng-container>
}
<!-- USER BALANCE --> <!-- USER BALANCE -->
<ng-container *ngIf="isLoggedIn() && estimate.userBalance < maxCost"> <ng-container *ngIf="isLoggedIn() && estimate.userBalance < maxCost">
@ -237,14 +286,17 @@
</div> </div>
</div> </div>
<div class="row d-flex justify-content-end align-items-center mr-1" style="height: 48px" *ngIf="!hideCashApp && paymentType === 'cashapp'"> @if (!hideCashApp && paymentType === 'cashapp') {
<div [style]="showSpinner ? 'opacity: 0' : 'opacity: 1'" class="p-2">Accelerate with</div> <div #cashappCTA class="cashapp-placeholder {{ stickyCTA }}"></div>
<div id="cash-app-pay" style="max-width: 320px" [style]="showSpinner ? 'opacity: 0' : 'opacity: 1'"></div> <div class="d-flex justify-content-center align-items-center cashapp-cta {{ stickyCTA }}" (click)="submitCashappPay()">
<div *ngIf="showSpinner" class="d-flex align-items-center"> <div [style]="showSpinner ? 'opacity: 0' : 'opacity: 1'" class="p-2">Accelerate for <app-fiat [value]="maxCost" [colorClass]="estimate.userBalance < maxCost ? 'red-color' : 'green-color'"></app-fiat> with</div>
<span class="mr-2">Loading</span> <div id="cash-app-pay" style="max-width: 320px" [style]="showSpinner ? 'opacity: 0' : 'opacity: 1'"></div>
<div class="spinner-border text-light" style="width: 25px; height: 25px"></div> <div *ngIf="showSpinner" class="d-flex align-items-center">
<span class="mr-2">Loading</span>
<div class="spinner-border text-light" style="width: 25px; height: 25px"></div>
</div>
</div> </div>
</div> }
</div> </div>
</ng-container> </ng-container>

View File

@ -109,4 +109,53 @@
.item { .item {
white-space: initial; white-space: initial;
}
.cashapp-cta {
width: 100%;
height: 54px;
background: #653b9c;
position: relative;
bottom: initial;
top: initial;
border-radius: 3px;
font-size: 14px;
line-height: 16px;
text-align: center;
padding: 4px 6px;
cursor: pointer;
box-shadow: 0px 0px 15px 0px #000;
&.sticky-top {
position: fixed;
width: calc(100vw - 30px - 1.5rem);
margin: auto;
z-index: 50;
left: 0;
right: 0;
top: 102px;
@media (min-width: 573px) {
top: 62px;
}
}
&.sticky-bottom {
position: fixed;
width: calc(100vw - 30px - 1.5rem);
margin: auto;
z-index: 50;
left: 0;
right: 0;
bottom: 50px;
@media (min-width: 430px) {
bottom: 56px;
}
}
}
.cashapp-placeholder {
height: 54px;
&.non-stick {
height: 0px;
}
} }

View File

@ -1,4 +1,4 @@
import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef } from '@angular/core'; import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core';
import { Subscription, catchError, of, tap } from 'rxjs'; import { Subscription, catchError, of, tap } from 'rxjs';
import { StorageService } from '../../services/storage.service'; import { StorageService } from '../../services/storage.service';
import { Transaction } from '../../interfaces/electrs.interface'; import { Transaction } from '../../interfaces/electrs.interface';
@ -43,6 +43,9 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
@Input() tx: Transaction | undefined; @Input() tx: Transaction | undefined;
@Input() scrollEvent: boolean; @Input() scrollEvent: boolean;
@ViewChild('cashappCTA')
cashappCTA: ElementRef;
math = Math; math = Math;
error = ''; error = '';
showSuccess = false; showSuccess = false;
@ -59,6 +62,7 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
selectFeeRateIndex = 1; selectFeeRateIndex = 1;
isMobile: boolean = window.innerWidth <= 767.98; isMobile: boolean = window.innerWidth <= 767.98;
user: any = undefined; user: any = undefined;
stickyCTA: string = 'non-stick';
maxRateOptions: RateOption[] = []; maxRateOptions: RateOption[] = [];
@ -66,6 +70,7 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
paymentType: 'bitcoin' | 'cashapp' = 'bitcoin'; paymentType: 'bitcoin' | 'cashapp' = 'bitcoin';
cashAppSubscription: Subscription; cashAppSubscription: Subscription;
conversionsSubscription: Subscription; conversionsSubscription: Subscription;
cashappSubmit: any;
payments: any; payments: any;
showSpinner = false; showSpinner = false;
square: any; square: any;
@ -96,14 +101,14 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
ngOnInit() { ngOnInit() {
if (this.stateService.ref === 'https://cash.app/') { if (this.stateService.ref === 'https://cash.app/') {
this.paymentType = 'cashapp'; this.paymentType = 'cashapp';
this.stateService.ref = '';
} else { } else {
this.paymentType = 'bitcoin'; this.paymentType = 'bitcoin';
} }
this.onScroll();
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
if (changes.scrollEvent) { if (changes.scrollEvent && this.paymentType !== 'cashapp') {
this.scrollToPreview('acceleratePreviewAnchor', 'start'); this.scrollToPreview('acceleratePreviewAnchor', 'start');
} }
} }
@ -173,10 +178,11 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
this.maxCost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee; this.maxCost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee;
if (!this.error) { if (!this.error) {
this.scrollToPreview('acceleratePreviewAnchor', 'start');
if (this.paymentType === 'cashapp') { if (this.paymentType === 'cashapp') {
this.setupSquare(); this.setupSquare();
} } else {
this.scrollToPreview('acceleratePreviewAnchor', 'start');
}
} }
} }
}), }),
@ -310,13 +316,15 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
label: 'Total', label: 'Total',
pending: true, pending: true,
productUrl: `https://mempool.space/tx/${this.tx.txid}`, productUrl: `https://mempool.space/tx/${this.tx.txid}`,
} },
button: { shape: 'semiround', size: 'small', theme: 'light'}
}); });
this.cashAppPay = await this.payments.cashAppPay(paymentRequest, { this.cashAppPay = await this.payments.cashAppPay(paymentRequest, {
redirectURL: `https://mempool.space/tx/${this.tx.txid}`, redirectURL: `https://mempool.space/tx/${this.tx.txid}`,
referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`, referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`,
button: { shape: 'semiround', size: 'small', theme: 'light'}
}); });
await this.cashAppPay.attach('#cash-app-pay'); const renderPromise = this.cashAppPay.CashAppPayInstance.render('#cash-app-pay', { button: { theme: 'light', size: 'small', shape: 'semiround' }, manage: false });
this.showSpinner = false; this.showSpinner = false;
const that = this; const that = this;
@ -351,6 +359,8 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
}); });
} }
}); });
this.cashappSubmit = await renderPromise;
} }
); );
} }
@ -367,4 +377,28 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
g.type='text/javascript'; g.src=statsUrl; s.parentNode.insertBefore(g, s); g.type='text/javascript'; g.src=statsUrl; s.parentNode.insertBefore(g, s);
})(); })();
} }
submitCashappPay(): void {
if (this.cashappSubmit) {
this.cashappSubmit?.begin();
}
}
@HostListener('window:scroll', ['$event']) // for window scroll events
onScroll() {
if (!this.cashappCTA?.nativeElement || this.paymentType !== 'cashapp' || !this.isMobile) {
return;
}
const cta = this.cashappCTA.nativeElement;
const rect = cta.getBoundingClientRect();
const topOffset = window.innerWidth <= 572 ? 102 : 62;
const bottomOffset = window.innerWidth < 430 ? 50 : 56;
if (rect.top < topOffset) {
this.stickyCTA = 'sticky-top';
} else if (rect.top > window.innerHeight - (bottomOffset + 54)) {
this.stickyCTA = 'sticky-bottom';
} else {
this.stickyCTA = 'non-stick';
}
}
} }

View File

@ -80,7 +80,9 @@
<div class="title float-left"> <div class="title float-left">
<h2 i18n="transaction.accelerate|Accelerate button label">Accelerate</h2> <h2 i18n="transaction.accelerate|Accelerate button label">Accelerate</h2>
</div> </div>
<button type="button" class="btn btn-outline-info accelerator-toggle btn-sm float-right" (click)="showAccelerationSummary = false" i18n="hide-accelerator">Hide accelerator</button> @if (!(isMobile && paymentType === 'cashapp')) {
<button type="button" class="btn btn-outline-info accelerator-toggle btn-sm float-right" (click)="showAccelerationSummary = false" i18n="hide-accelerator">Hide accelerator</button>
}
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="box"> <div class="box">
@ -530,7 +532,7 @@
} @else if (this.mempoolPosition.block >= 7) { } @else if (this.mempoolPosition.block >= 7) {
<span [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'etaDeepMempool d-flex justify-content-end align-items-center' : ''"> <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> <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) { @if (!(isMobile && paymentType === 'cashapp') && !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> <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> </span>
@ -539,7 +541,7 @@
} @else { } @else {
<span class="eta justify-content-end" [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'd-flex align-items-center' : ''"> <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> <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) { @if (!(isMobile && paymentType === 'cashapp') && !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> <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> </span>

View File

@ -311,6 +311,13 @@
} }
} }
.accelerateFullSize {
width: 100%;
height: 100%;
padding: 0.5rem 0.25rem;
background-color: #653b9c;
}
.goggles-icon { .goggles-icon {
display: block; display: block;
width: 2.2em; width: 2.2em;

View File

@ -117,6 +117,8 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
flowEnabled: boolean; flowEnabled: boolean;
tooltipPosition: { x: number, y: number }; tooltipPosition: { x: number, y: number };
isMobile: boolean; isMobile: boolean;
paymentType: 'bitcoin' | 'cashapp' = 'bitcoin';
firstLoad = true;
featuresEnabled: boolean; featuresEnabled: boolean;
segwitEnabled: boolean; segwitEnabled: boolean;
@ -154,6 +156,11 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
ngOnInit() { ngOnInit() {
this.acceleratorAvailable = this.stateService.env.OFFICIAL_MEMPOOL_SPACE && this.stateService.env.ACCELERATOR && this.stateService.network === ''; this.acceleratorAvailable = this.stateService.env.OFFICIAL_MEMPOOL_SPACE && this.stateService.env.ACCELERATOR && this.stateService.network === '';
if (this.acceleratorAvailable && this.stateService.ref === 'https://cash.app/') {
this.showAccelerationSummary = true;
this.paymentType = 'cashapp';
}
this.enterpriseService.page(); this.enterpriseService.page();
this.websocketService.want(['blocks', 'mempool-blocks']); this.websocketService.want(['blocks', 'mempool-blocks']);
@ -720,6 +727,11 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
} }
resetTransaction() { resetTransaction() {
if (!this.firstLoad) {
this.stateService.ref = '';
} else {
this.firstLoad = false;
}
this.error = undefined; this.error = undefined;
this.tx = null; this.tx = null;
this.setFeatures(); this.setFeatures();
@ -814,6 +826,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
} }
ngOnDestroy() { ngOnDestroy() {
this.stateService.ref = '';
this.subscription.unsubscribe(); this.subscription.unsubscribe();
this.fetchCpfpSubscription.unsubscribe(); this.fetchCpfpSubscription.unsubscribe();
this.fetchRbfSubscription.unsubscribe(); this.fetchRbfSubscription.unsubscribe();