Merge branch 'master' into mononaut/wallets-404

This commit is contained in:
wiz 2025-04-11 14:10:13 +09:00 committed by GitHub
commit ae9aa0b0d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 78 additions and 16 deletions

View File

@ -219,7 +219,12 @@
<table class="job-table table table-xs table-borderless table-fixed table-data">
<thead>
<tr>
<th class="data-title clip text-center coinbase" i18n="latest-blocks.coinbasetag">Coinbase tag</th>
<th class="data-title clip text-center coinbase" i18n="latest-blocks.coinbasetag">
<a class="title-link" [routerLink]="['/tx/preview' | relativeUrl]" [fragment]="'offline=true&hex=' + job.coinbase">
Coinbase tag <span>&nbsp;</span>
<fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: text-top; font-size: 13px; color: var(--title-fg)"></fa-icon>
</a>
</th>
<th class="data-title clip text-center clean" i18n="next-block.clean">Clean</th>
<th class="data-title clip text-center prevhash" i18n="next-block.prevhash">Prevhash</th>
<th class="data-title clip text-center job-received" i18n="next-block.job-received">Job Received</th>

View File

@ -45,7 +45,9 @@
<app-amount [satoshis]="row.job.reward"></app-amount>
</td>
<td class="height">
{{ row.job.height }}
<a [routerLink]="['/tx/preview' | relativeUrl]" [fragment]="'offline=true&hex=' + row.job.coinbase">
{{ row.job.height }}
</a>
</td>
</tr>
}

View File

@ -19,7 +19,11 @@
@if (transaction && !error && !isLoading) {
<div class="title-block">
<h1 i18n="shared.preview-transaction|Preview Transaction">Preview Transaction</h1>
@if (isCoinbase) {
<h1 i18n="shared.preview-coinbase|Preview Coinbase">Preview Coinbase</h1>
} @else {
<h1 i18n="shared.preview-transaction|Preview Transaction">Preview Transaction</h1>
}
<span class="tx-link">
<span class="txid">
@ -39,19 +43,21 @@
<div class="clearfix"></div>
<div class="alert alert-mempool" style="align-items: center;">
<span>
<fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon>
<ng-container *ngIf="!successBroadcast" i18n="transaction.local-tx|This transaction is stored locally in your browser.">
This transaction is stored locally in your browser. Broadcast it to add it to the mempool.
</ng-container>
<ng-container *ngIf="successBroadcast" i18n="transaction.redirecting|Redirecting to transaction page...">
Redirecting to transaction page...
</ng-container>
</span>
<button *ngIf="!successBroadcast" [disabled]="isLoadingBroadcast" type="button" class="btn btn-sm btn-primary btn-broadcast" i18n="transaction.broadcast|Broadcast" (click)="postTx()">Broadcast</button>
<button *ngIf="successBroadcast" type="button" class="btn btn-sm btn-success no-cursor btn-broadcast" i18n="transaction.broadcasted|Broadcasted">Broadcasted</button>
</div>
@if (!isCoinbase) {
<div class="alert alert-mempool" style="align-items: center;">
<span>
<fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon>
<ng-container *ngIf="!successBroadcast" i18n="transaction.local-tx|This transaction is stored locally in your browser.">
This transaction is stored locally in your browser. Broadcast it to add it to the mempool.
</ng-container>
<ng-container *ngIf="successBroadcast" i18n="transaction.redirecting|Redirecting to transaction page...">
Redirecting to transaction page...
</ng-container>
</span>
<button *ngIf="!successBroadcast" [disabled]="isLoadingBroadcast" type="button" class="btn btn-sm btn-primary btn-broadcast" i18n="transaction.broadcast|Broadcast" (click)="postTx()">Broadcast</button>
<button *ngIf="successBroadcast" type="button" class="btn btn-sm btn-success no-cursor btn-broadcast" i18n="transaction.broadcasted|Broadcasted">Broadcasted</button>
</div>
}
@if (!hasPrevouts) {
<div class="alert alert-mempool">

View File

@ -36,7 +36,9 @@ export class TransactionRawComponent implements OnInit, OnDestroy {
isLoadingBroadcast: boolean;
errorBroadcast: string;
successBroadcast: boolean;
isCoinbase: boolean;
broadcastSubscription: Subscription;
fragmentSubscription: Subscription;
isMobile: boolean;
@ViewChild('graphContainer')
@ -77,6 +79,23 @@ export class TransactionRawComponent implements OnInit, OnDestroy {
this.pushTxForm = this.formBuilder.group({
txRaw: ['', Validators.required],
});
this.fragmentSubscription = this.route.fragment.subscribe((fragment) => {
if (fragment) {
const params = new URLSearchParams(fragment);
const hex = params.get('hex');
if (hex) {
this.pushTxForm.get('txRaw').setValue(hex);
}
const offline = params.get('offline');
if (offline) {
this.offlineMode = offline === 'true';
}
if (this.pushTxForm.get('txRaw').value) {
this.decodeTransaction();
}
}
});
}
async decodeTransaction(): Promise<void> {
@ -184,6 +203,14 @@ export class TransactionRawComponent implements OnInit, OnDestroy {
this.transaction = tx;
this.rawHexTransaction = hex;
this.isCoinbase = this.transaction.vin[0].is_coinbase;
// Update URL fragment with hex data
this.router.navigate([], {
fragment: this.getCurrentFragments(),
replaceUrl: true
});
this.transaction.flags = getTransactionFlags(this.transaction, this.cpfpInfo, null, null, this.stateService.network);
this.filters = this.transaction.flags ? toFilters(this.transaction.flags).filter(f => f.txPage) : [];
if (this.transaction.sigops >= 0) {
@ -264,6 +291,11 @@ export class TransactionRawComponent implements OnInit, OnDestroy {
resetForm() {
this.resetState();
this.pushTxForm.get('txRaw').setValue('');
this.offlineMode = false;
this.router.navigate([], {
fragment: '',
replaceUrl: true
});
}
@HostListener('window:resize', ['$event'])
@ -306,8 +338,24 @@ export class TransactionRawComponent implements OnInit, OnDestroy {
this.graphHeight = Math.min(360, this.maxInOut * 80);
}
getCurrentFragments() {
// build a fragment param string from current state
const params = new URLSearchParams();
if (this.offlineMode) {
params.set('offline', 'true');
}
if (this.rawHexTransaction) {
params.set('hex', this.rawHexTransaction);
}
return params.toString();
}
onOfflineModeChange(e): void {
this.offlineMode = !e.target.checked;
this.router.navigate([], {
fragment: this.getCurrentFragments(),
replaceUrl: true
});
}
ngOnDestroy(): void {
@ -315,6 +363,7 @@ export class TransactionRawComponent implements OnInit, OnDestroy {
this.flowPrefSubscription?.unsubscribe();
this.stateService.markBlock$.next({});
this.broadcastSubscription?.unsubscribe();
this.fragmentSubscription?.unsubscribe();
}
}