Merge pull request #880 from mempool/simon/transaction-output-id

Add output ID to transaction info
This commit is contained in:
wiz 2021-10-20 22:32:31 +09:00 committed by GitHub
commit a9f4418e1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 15 deletions

View file

@ -25,7 +25,7 @@ export class SearchFormComponent implements OnInit {
regexAddress = /^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[a-z]{2,5}1[ac-hj-np-z02-9]{8,100}|[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100})$/;
regexBlockhash = /^[0]{8}[a-fA-F0-9]{56}$/;
regexTransaction = /^[a-fA-F0-9]{64}$/;
regexTransaction = /^([a-fA-F0-9]{64}):?(\d+)?$/;
regexBlockheight = /^[0-9]+$/;
@ViewChild('instance', {static: true}) instance: NgbTypeahead;
@ -100,22 +100,23 @@ export class SearchFormComponent implements OnInit {
} else if (this.regexBlockhash.test(searchText) || this.regexBlockheight.test(searchText)) {
this.navigate('/block/', searchText);
} else if (this.regexTransaction.test(searchText)) {
const matches = this.regexTransaction.exec(searchText);
if (this.network === 'liquid') {
if (this.assets[searchText]) {
this.navigate('/asset/', searchText);
if (this.assets[matches[1]]) {
this.navigate('/asset/', matches[1]);
}
this.electrsApiService.getAsset$(searchText)
this.electrsApiService.getAsset$(matches[1])
.subscribe(
() => { this.navigate('/asset/', searchText); },
() => { this.navigate('/asset/', matches[1]); },
() => {
this.electrsApiService.getBlock$(searchText)
this.electrsApiService.getBlock$(matches[1])
.subscribe(
(block) => { this.navigate('/block/', searchText, { state: { data: { block } } }); },
() => { this.navigate('/tx/', searchText); });
(block) => { this.navigate('/block/', matches[1], { state: { data: { block } } }); },
() => { this.navigate('/tx/', matches[0]); });
}
);
} else {
this.navigate('/tx/', searchText);
this.navigate('/tx/', matches[0]);
}
} else {
this.isSearching = false;

View file

@ -198,7 +198,7 @@
<div class="clearfix"></div>
<app-transactions-list #txList [transactions]="[tx]" [errorUnblinded]="errorUnblinded" [transactionPage]="true"></app-transactions-list>
<app-transactions-list #txList [transactions]="[tx]" [errorUnblinded]="errorUnblinded" [outputIndex]="outputIndex" [transactionPage]="true"></app-transactions-list>
<h2 class="text-left" i18n="transaction.details">Details</h2>
<div class="box">

View file

@ -44,6 +44,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
now = new Date().getTime();
timeAvg$: Observable<number>;
liquidUnblinding = new LiquidUnblinding();
outputIndex: number;
constructor(
private route: ActivatedRoute,
@ -125,7 +126,9 @@ export class TransactionComponent implements OnInit, OnDestroy {
this.subscription = this.route.paramMap
.pipe(
switchMap((params: ParamMap) => {
this.txId = params.get('id') || '';
const urlMatch = (params.get('id') || '').split(':');
this.txId = urlMatch[0];
this.outputIndex = urlMatch[1] === undefined ? null : parseInt(urlMatch[1], 10);
this.seoService.setTitle(
$localize`:@@bisq.transaction.browser-title:Transaction: ${this.txId}:INTERPOLATION:`
);

View file

@ -33,7 +33,7 @@
<fa-icon [icon]="['fas', 'arrow-alt-circle-right']" [fixedWidth]="true"></fa-icon>
</a>
<ng-template #defaultPrevout>
<a [routerLink]="['/tx/' | relativeUrl, vin.txid]" class="red">
<a [routerLink]="['/tx/' | relativeUrl, vin.txid + ':' + vin.vout]" class="red">
<fa-icon [icon]="['fas', 'arrow-alt-circle-right']" [fixedWidth]="true"></fa-icon>
</a>
</ng-template>
@ -121,8 +121,8 @@
<div class="col mobile-bottomcol">
<table class="table table-borderless smaller-text table-sm" id="table-tx-vout">
<tbody>
<ng-template ngFor let-vout let-vindex="index" [ngForOf]="tx['@voutLimit'] ?((tx.vout.length>12)?tx.vout.slice(0, 10): tx.vout.slice(0, 12)) : tx.vout" [ngForTrackBy]="trackByIndexFn">
<tr [ngClass]="assetsMinimal && assetsMinimal[vout.asset] && vout.scriptpubkey_address && tx.vin && !tx.vin[0].is_coinbase && tx._unblinded ? 'assetBox' : ''">
<ng-template ngFor let-vout let-vindex="index" [ngForOf]="tx['@voutLimit'] && !outputIndex ? ((tx.vout.length > 12) ? tx.vout.slice(0, 10) : tx.vout.slice(0, 12)) : tx.vout" [ngForTrackBy]="trackByIndexFn">
<tr [ngClass]="assetsMinimal && assetsMinimal[vout.asset] && vout.scriptpubkey_address && tx.vin && !tx.vin[0].is_coinbase && tx._unblinded || outputIndex === vindex ? 'assetBox' : ''">
<td>
<a *ngIf="vout.scriptpubkey_address; else scriptpubkey_type" [routerLink]="['/address/' | relativeUrl, vout.scriptpubkey_address]" title="{{ vout.scriptpubkey_address }}">
<span class="d-block d-lg-none">{{ vout.scriptpubkey_address | shortenString : 16 }}</span>
@ -197,7 +197,7 @@
</td>
</tr>
</ng-template>
<tr *ngIf="tx.vout.length > 12 && tx['@voutLimit']">
<tr *ngIf="tx.vout.length > 12 && tx['@voutLimit'] && !outputIndex">
<td colspan="3" class="text-center">
<button class="btn btn-sm btn-primary mt-2" (click)="tx['@voutLimit'] = false;"><span i18n="transactions-list.load-all">Load all</span> ({{ tx.vout.length - 10 }})</button>
</td>

View file

@ -22,6 +22,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
@Input() showConfirmations = false;
@Input() transactionPage = false;
@Input() errorUnblinded = false;
@Input() outputIndex: number;
@Output() loadMore = new EventEmitter();
@ -51,6 +52,14 @@ export class TransactionsListComponent implements OnInit, OnChanges {
if (!this.transactions || !this.transactions.length) {
return;
}
if (this.outputIndex) {
setTimeout(() => {
const assetBoxElements = document.getElementsByClassName('assetBox');
if (assetBoxElements && assetBoxElements[0]) {
assetBoxElements[0].scrollIntoView();
}
}, 10);
}
const observableObject = {};
this.transactions.forEach((tx, i) => {
tx['@voutLimit'] = true;