Merge pull request #880 from mempool/simon/transaction-output-id
Add output ID to transaction info
This commit is contained in:
commit
a9f4418e1a
@ -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})$/;
|
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}$/;
|
regexBlockhash = /^[0]{8}[a-fA-F0-9]{56}$/;
|
||||||
regexTransaction = /^[a-fA-F0-9]{64}$/;
|
regexTransaction = /^([a-fA-F0-9]{64}):?(\d+)?$/;
|
||||||
regexBlockheight = /^[0-9]+$/;
|
regexBlockheight = /^[0-9]+$/;
|
||||||
|
|
||||||
@ViewChild('instance', {static: true}) instance: NgbTypeahead;
|
@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)) {
|
} else if (this.regexBlockhash.test(searchText) || this.regexBlockheight.test(searchText)) {
|
||||||
this.navigate('/block/', searchText);
|
this.navigate('/block/', searchText);
|
||||||
} else if (this.regexTransaction.test(searchText)) {
|
} else if (this.regexTransaction.test(searchText)) {
|
||||||
|
const matches = this.regexTransaction.exec(searchText);
|
||||||
if (this.network === 'liquid') {
|
if (this.network === 'liquid') {
|
||||||
if (this.assets[searchText]) {
|
if (this.assets[matches[1]]) {
|
||||||
this.navigate('/asset/', searchText);
|
this.navigate('/asset/', matches[1]);
|
||||||
}
|
}
|
||||||
this.electrsApiService.getAsset$(searchText)
|
this.electrsApiService.getAsset$(matches[1])
|
||||||
.subscribe(
|
.subscribe(
|
||||||
() => { this.navigate('/asset/', searchText); },
|
() => { this.navigate('/asset/', matches[1]); },
|
||||||
() => {
|
() => {
|
||||||
this.electrsApiService.getBlock$(searchText)
|
this.electrsApiService.getBlock$(matches[1])
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(block) => { this.navigate('/block/', searchText, { state: { data: { block } } }); },
|
(block) => { this.navigate('/block/', matches[1], { state: { data: { block } } }); },
|
||||||
() => { this.navigate('/tx/', searchText); });
|
() => { this.navigate('/tx/', matches[0]); });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.navigate('/tx/', searchText);
|
this.navigate('/tx/', matches[0]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.isSearching = false;
|
this.isSearching = false;
|
||||||
|
@ -198,7 +198,7 @@
|
|||||||
|
|
||||||
<div class="clearfix"></div>
|
<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>
|
<h2 class="text-left" i18n="transaction.details">Details</h2>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
@ -44,6 +44,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
|
|||||||
now = new Date().getTime();
|
now = new Date().getTime();
|
||||||
timeAvg$: Observable<number>;
|
timeAvg$: Observable<number>;
|
||||||
liquidUnblinding = new LiquidUnblinding();
|
liquidUnblinding = new LiquidUnblinding();
|
||||||
|
outputIndex: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
@ -125,7 +126,9 @@ export class TransactionComponent implements OnInit, OnDestroy {
|
|||||||
this.subscription = this.route.paramMap
|
this.subscription = this.route.paramMap
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap((params: ParamMap) => {
|
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(
|
this.seoService.setTitle(
|
||||||
$localize`:@@bisq.transaction.browser-title:Transaction: ${this.txId}:INTERPOLATION:`
|
$localize`:@@bisq.transaction.browser-title:Transaction: ${this.txId}:INTERPOLATION:`
|
||||||
);
|
);
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
<fa-icon [icon]="['fas', 'arrow-alt-circle-right']" [fixedWidth]="true"></fa-icon>
|
<fa-icon [icon]="['fas', 'arrow-alt-circle-right']" [fixedWidth]="true"></fa-icon>
|
||||||
</a>
|
</a>
|
||||||
<ng-template #defaultPrevout>
|
<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>
|
<fa-icon [icon]="['fas', 'arrow-alt-circle-right']" [fixedWidth]="true"></fa-icon>
|
||||||
</a>
|
</a>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@ -121,8 +121,8 @@
|
|||||||
<div class="col mobile-bottomcol">
|
<div class="col mobile-bottomcol">
|
||||||
<table class="table table-borderless smaller-text table-sm" id="table-tx-vout">
|
<table class="table table-borderless smaller-text table-sm" id="table-tx-vout">
|
||||||
<tbody>
|
<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">
|
<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 ? 'assetBox' : ''">
|
<tr [ngClass]="assetsMinimal && assetsMinimal[vout.asset] && vout.scriptpubkey_address && tx.vin && !tx.vin[0].is_coinbase && tx._unblinded || outputIndex === vindex ? 'assetBox' : ''">
|
||||||
<td>
|
<td>
|
||||||
<a *ngIf="vout.scriptpubkey_address; else scriptpubkey_type" [routerLink]="['/address/' | relativeUrl, vout.scriptpubkey_address]" title="{{ vout.scriptpubkey_address }}">
|
<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>
|
<span class="d-block d-lg-none">{{ vout.scriptpubkey_address | shortenString : 16 }}</span>
|
||||||
@ -197,7 +197,7 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</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">
|
<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>
|
<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>
|
</td>
|
||||||
|
@ -22,6 +22,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
|
|||||||
@Input() showConfirmations = false;
|
@Input() showConfirmations = false;
|
||||||
@Input() transactionPage = false;
|
@Input() transactionPage = false;
|
||||||
@Input() errorUnblinded = false;
|
@Input() errorUnblinded = false;
|
||||||
|
@Input() outputIndex: number;
|
||||||
|
|
||||||
@Output() loadMore = new EventEmitter();
|
@Output() loadMore = new EventEmitter();
|
||||||
|
|
||||||
@ -51,6 +52,14 @@ export class TransactionsListComponent implements OnInit, OnChanges {
|
|||||||
if (!this.transactions || !this.transactions.length) {
|
if (!this.transactions || !this.transactions.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this.outputIndex) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const assetBoxElements = document.getElementsByClassName('assetBox');
|
||||||
|
if (assetBoxElements && assetBoxElements[0]) {
|
||||||
|
assetBoxElements[0].scrollIntoView();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
const observableObject = {};
|
const observableObject = {};
|
||||||
this.transactions.forEach((tx, i) => {
|
this.transactions.forEach((tx, i) => {
|
||||||
tx['@voutLimit'] = true;
|
tx['@voutLimit'] = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user