Commit 74d1abc2 authored by dev0tion's avatar dev0tion

Show confirmations

parent aedf0226
export class TransactionInfo {
constructor(transactionType: string, transactionId: string, transactionAmount: number, transactionAddress: any, transactionFee: number, transactionConfirmedInBlock: number, transactionTimestamp: number) {
this.transactionType = transactionType;
this.transactionId = transactionId;
this.transactionAmount = transactionAmount;
this.transactionAddress = transactionAddress;
this.transactionFee = transactionFee;
this.transactionConfirmedInBlock = transactionConfirmedInBlock;
this.transactionTimestamp = transactionTimestamp;
}
public transactionType: string;
public transactionId: string;
public transactionAmount: number;
public transactionAddress: string;
public transactionFee: number;
public transactionConfirmedInBlock?: number;
public transactionTimestamp: number;
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<h5>Active balance</h5> <h5>Active balance</h5>
<p class="lead"> <p class="lead">
<!--<strong><span class="h2">29</span>.76500293</strong>--> <!--<strong><span class="h2">29</span>.76500293</strong>-->
<strong>{{confirmedBalance | coinNotation }}</strong> <strong>{{ confirmedBalance | coinNotation }}</strong>
<!--<small class="text-uppercase">btc</small>--> <!--<small class="text-uppercase">btc</small>-->
</p> </p>
</div> </div>
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
<div class="col-xs-12 col-md-4 text-left"> <div class="col-xs-12 col-md-4 text-left">
<h5>Unconfirmed balance</h5> <h5>Unconfirmed balance</h5>
<p class="lead"> <p class="lead">
<strong>{{unconfirmedBalance | coinNotation }}</strong> <strong>{{ unconfirmedBalance | coinNotation }}</strong>
</p> </p>
</div> </div>
<!-- /col--> <!-- /col-->
...@@ -46,14 +46,21 @@ ...@@ -46,14 +46,21 @@
<!-- TRANSACTIONS --> <!-- TRANSACTIONS -->
<section id="transaction" class="container"> <section id="transaction" class="container">
<h5>Latest Transactions</h5> <h5>Latest Transactions</h5>
<div *ngIf="transactions; else noTransactions"> <div *ngIf="transactionArray; else noTransactions">
<div *ngFor="let transaction of transactions; let i=index"> <div *ngFor="let transaction of transactionArray; let i=index">
<div class="card" *ngIf="i<3" (click)="openTransactionDetailDialog(transaction)"> <div class="card" *ngIf="i<3" (click)="openTransactionDetailDialog(transaction)">
<div class="card-block text-nowrap"> <div class="card-block text-nowrap">
<ul class="list-inline row"> <ul class="list-inline row">
<li class="list-inline-item hidden-xs-down col-3 text-uppercase align-bottom">{{ transaction.type }}</li> <li class="list-inline-item hidden-xs-down col-3 text-uppercase align-bottom">{{ transaction.transactionType }}</li>
<li class="list-inline-item col-4 amount text-left align-baseline"><!--<span class="text-success">+</span>--> {{ transaction.amount | coinNotation }} <!--<small class="text-uppercase">btc</small> <span class="badge badge-danger text-capitalize">unconfirmed</span>--></li> <li class="list-inline-item col-4 amount text-left align-baseline">
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.timestamp * 1000 | date:'medium' }}</li> <span *ngIf="transaction.transactionType == 'received'" class="text-success">+</span>
<span *ngIf="transaction.transactionType == 'sent'" class="text-danger">-</span>
{{ transaction.transactionAmount | coinNotation }}
<!--<small class="text-uppercase">btc</small>-->
<span *ngIf="transaction.transactionConfirmedInBlock" class="badge badge-success text-capitalize">Confirmed</span>
<span *ngIf="!transaction.transactionConfirmedInBlock" class="badge badge-warning text-capitalize">Pending</span>
</li>
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.transactionTimestamp * 1000 | date:'medium' }}</li>
</ul> </ul>
</div> </div>
</div> </div>
......
...@@ -4,6 +4,7 @@ import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; ...@@ -4,6 +4,7 @@ import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ApiService } from '../../shared/services/api.service'; import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service'; import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info'; import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
import { SendComponent } from '../send/send.component'; import { SendComponent } from '../send/send.component';
import { ReceiveComponent } from '../receive/receive.component'; import { ReceiveComponent } from '../receive/receive.component';
...@@ -23,7 +24,7 @@ export class DashboardComponent implements OnInit { ...@@ -23,7 +24,7 @@ export class DashboardComponent implements OnInit {
public confirmedBalance: number; public confirmedBalance: number;
public unconfirmedBalance: number; public unconfirmedBalance: number;
public transactions: any; public transactionArray: TransactionInfo[];
private walletBalanceSubscription: Subscription; private walletBalanceSubscription: Subscription;
private walletHistorySubscription: Subscription; private walletHistorySubscription: Subscription;
...@@ -43,13 +44,13 @@ export class DashboardComponent implements OnInit { ...@@ -43,13 +44,13 @@ export class DashboardComponent implements OnInit {
const modalRef = this.modalService.open(ReceiveComponent); const modalRef = this.modalService.open(ReceiveComponent);
}; };
public openTransactionDetailDialog(transaction: any) { public openTransactionDetailDialog(transaction: TransactionInfo) {
const modalRef = this.modalService.open(TransactionDetailsComponent); const modalRef = this.modalService.open(TransactionDetailsComponent);
modalRef.componentInstance.transaction = transaction; modalRef.componentInstance.transaction = transaction;
} }
private getWalletBalance() { private getWalletBalance() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType()) let walletInfo = new WalletInfo(this.globalService.getWalletName());
this.walletBalanceSubscription = this.apiService.getWalletBalance(walletInfo) this.walletBalanceSubscription = this.apiService.getWalletBalance(walletInfo)
.subscribe( .subscribe(
response => { response => {
...@@ -81,14 +82,17 @@ export class DashboardComponent implements OnInit { ...@@ -81,14 +82,17 @@ export class DashboardComponent implements OnInit {
; ;
}; };
// todo: add history in seperate service to make it reusable
private getHistory() { private getHistory() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType()) let walletInfo = new WalletInfo(this.globalService.getWalletName());
let historyResponse;
this.walletHistorySubscription = this.apiService.getWalletHistory(walletInfo) this.walletHistorySubscription = this.apiService.getWalletHistory(walletInfo)
.subscribe( .subscribe(
response => { response => {
if (response.status >= 200 && response.status < 400) { if (response.status >= 200 && response.status < 400) {
if (response.json().transactionsHistory.length > 0) { if (response.json().transactionsHistory.length > 0) {
this.transactions = response.json().transactionsHistory; historyResponse = response.json().transactionsHistory;
this.getTransactionInfo(historyResponse);
} }
} }
}, },
...@@ -114,6 +118,33 @@ export class DashboardComponent implements OnInit { ...@@ -114,6 +118,33 @@ export class DashboardComponent implements OnInit {
; ;
}; };
private getTransactionInfo(transactions: any) {
this.transactionArray = [];
for (let transaction of transactions) {
let transactionType;
if (transaction.type === "send") {
transactionType = "sent";
} else if (transaction.type === "received") {
transactionType = "received";
}
let transactionId = transaction.id;
let transactionAmount = transaction.amount;
let transactionAddress;
if (transaction.payments[0]) {
transactionAddress = transaction.payments[0].destinationAddress;
} else if (transaction.toAddress) {
transactionAddress = transaction.toAddress;
}
let transactionFee = transaction.fee;
let transactionConfirmedInBlock = transaction.confirmedInBlock;
let transactionTimestamp = transaction.timestamp;
let transactionConfirmed;
this.transactionArray.push(new TransactionInfo(transactionType, transactionId, transactionAmount, transactionAddress, transactionFee, transactionConfirmedInBlock, transactionTimestamp));
}
}
private cancelSubscriptions() { private cancelSubscriptions() {
if (this.walletBalanceSubscription) { if (this.walletBalanceSubscription) {
this.walletBalanceSubscription.unsubscribe(); this.walletBalanceSubscription.unsubscribe();
......
...@@ -26,9 +26,16 @@ ...@@ -26,9 +26,16 @@
<div class="card" (click)="openTransactionDetailDialog(transaction)"> <div class="card" (click)="openTransactionDetailDialog(transaction)">
<div class="card-block text-nowrap"> <div class="card-block text-nowrap">
<ul class="list-inline row"> <ul class="list-inline row">
<li class="list-inline-item hidden-xs-down col text-uppercase align-bottom">{{ transaction.type }}</li> <li class="list-inline-item hidden-xs-down col-3 text-uppercase align-bottom">{{ transaction.transactionType }}</li>
<li class="list-inline-item col-4 amount text-left align-baseline"><!--<span class="text-success">+</span>--> {{ transaction.amount | coinNotation }} <!--<small class="text-uppercase">btc</small> <span class="badge badge-danger text-capitalize">unconfirmed</span>--></li> <li class="list-inline-item col-4 amount text-left align-baseline">
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.timestamp * 1000 | date:'medium' }}</li> <span *ngIf="transaction.transactionType == 'received'" class="text-success">+</span>
<span *ngIf="transaction.transactionType == 'sent'" class="text-danger">-</span>
{{ transaction.transactionAmount | coinNotation }}
<!--<small class="text-uppercase">btc</small>-->
<span *ngIf="transaction.transactionConfirmedInBlock" class="badge badge-success text-capitalize">Confirmed</span>
<span *ngIf="!transaction.transactionConfirmedInBlock" class="badge badge-warning text-capitalize">Pending</span>
</li>
<li class="list-inline-item col text-right align-baseline transactionDate">{{ transaction.transactionTimestamp * 1000 | date:'medium' }}</li>
</ul> </ul>
</div> </div>
</div> </div>
......
...@@ -5,6 +5,7 @@ import { ApiService } from '../../shared/services/api.service'; ...@@ -5,6 +5,7 @@ import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service'; import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info'; import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { Subscription } from 'rxjs/Subscription'; import { Subscription } from 'rxjs/Subscription';
...@@ -20,7 +21,7 @@ import { TransactionDetailsComponent } from '../transaction-details/transaction- ...@@ -20,7 +21,7 @@ import { TransactionDetailsComponent } from '../transaction-details/transaction-
export class HistoryComponent { export class HistoryComponent {
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal) {} constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal) {}
public transactions: any; public transactions: TransactionInfo[];
private errorMessage: string; private errorMessage: string;
private walletHistorySubscription: Subscription; private walletHistorySubscription: Subscription;
...@@ -37,14 +38,17 @@ export class HistoryComponent { ...@@ -37,14 +38,17 @@ export class HistoryComponent {
modalRef.componentInstance.transaction = transaction; modalRef.componentInstance.transaction = transaction;
} }
// todo: add history in seperate service to make it reusable
private getHistory() { private getHistory() {
let walletInfo = new WalletInfo(this.globalService.getWalletName(), this.globalService.getCoinType()) let walletInfo = new WalletInfo(this.globalService.getWalletName())
let historyResponse;
this.walletHistorySubscription = this.apiService.getWalletHistory(walletInfo) this.walletHistorySubscription = this.apiService.getWalletHistory(walletInfo)
.subscribe( .subscribe(
response => { response => {
if (response.status >= 200 && response.status < 400) { if (response.status >= 200 && response.status < 400) {
if (response.json().transactionsHistory.length > 0) { if (response.json().transactionsHistory.length > 0) {
this.transactions = response.json().transactionsHistory; historyResponse = response.json().transactionsHistory;
this.getTransactionInfo(historyResponse);
} }
} }
}, },
...@@ -70,6 +74,33 @@ export class HistoryComponent { ...@@ -70,6 +74,33 @@ export class HistoryComponent {
; ;
}; };
private getTransactionInfo(transactions: any) {
this.transactions = [];
for (let transaction of transactions) {
let transactionType;
if (transaction.type === "send") {
transactionType = "sent";
} else if (transaction.type === "received") {
transactionType = "received";
}
let transactionId = transaction.id;
let transactionAmount = transaction.amount;
let transactionAddress;
if (transaction.payments[0]) {
transactionAddress = transaction.payments[0].destinationAddress;
} else if (transaction.toAddress) {
transactionAddress = transaction.toAddress;
}
let transactionFee = transaction.fee;
let transactionConfirmedInBlock = transaction.confirmedInBlock;
let transactionTimestamp = transaction.timestamp;
let transactionConfirmed;
this.transactions.push(new TransactionInfo(transactionType, transactionId, transactionAmount, transactionAddress, transactionFee, transactionConfirmedInBlock, transactionTimestamp));
}
}
private cancelSubscriptions() { private cancelSubscriptions() {
if(this.walletHistorySubscription) { if(this.walletHistorySubscription) {
this.walletHistorySubscription.unsubscribe(); this.walletHistorySubscription.unsubscribe();
......
...@@ -8,28 +8,34 @@ ...@@ -8,28 +8,34 @@
<h5 class="modal-title text-uppercase" id="modalDetail">Transaction Details</h5> <h5 class="modal-title text-uppercase" id="modalDetail">Transaction Details</h5>
<ul class="list-inline row"> <ul class="list-inline row">
<li class="list-inline-item col blockLabel">Type</li> <li class="list-inline-item col blockLabel">Type</li>
<li class="list-inline-item col-9 blockText text-capitalize">{{ transaction.type }}</li> <li class="list-inline-item col-9 blockText text-capitalize">{{ transaction.transactionType }}</li>
</ul> </ul>
<ul class="list-inline row"> <ul class="list-inline row">
<li class="list-inline-item col blockLabel">Amount</li> <li class="list-inline-item col blockLabel">Amount</li>
<li class="list-inline-item col-9 blockText text-success">{{transaction.amount | coinNotation }}</li> <li *ngIf="transaction.transactionType == 'received'" class="list-inline-item col-9 blockText text-success">{{ transaction.transactionAmount | coinNotation }}</li>
<li *ngIf="transaction.transactionType == 'sent'" class="list-inline-item col-9 blockText text-danger">-{{ transaction.transactionAmount | coinNotation }}</li>
</ul> </ul>
<!--<ul class="list-inline row">
<li class="list-inline-item col blockLabel">From</li>
<li class="list-inline-item col-9 blockText"><code>n4kVJQarwwdmsXDdgNnJHgBSpZ8MhSkNBx</code></li>
</ul>-->
<ul class="list-inline row"> <ul class="list-inline row">
<li class="list-inline-item col blockLabel">Date</li> <li *ngIf="transaction.transactionType == 'received'" class="list-inline-item col blockLabel">From</li>
<li class="list-inline-item col-9 blockText">{{ transaction.timestamp * 1000 | date:'medium' }}</li> <li *ngIf="transaction.transactionType == 'sent'" class="list-inline-item col blockLabel">To</li>
<li class="list-inline-item col-9 blockText"><code>{{ transaction.transactionAddress }}</code></li>
</ul> </ul>
<ul class="list-inline row"> <ul class="list-inline row">
<li class="list-inline-item col blockLabel">Date</li>
<li class="list-inline-item col-9 blockText">{{ transaction.transactionTimestamp * 1000 | date:'medium' }}</li>
</ul>
<ul *ngIf="transaction.transactionConfirmedInBlock" class="list-inline row">
<li class="list-inline-item col blockLabel">Block</li> <li class="list-inline-item col blockLabel">Block</li>
<li class="list-inline-item col-9 blockText">#{{ transaction.confirmedInBlock }}</li> <li class="list-inline-item col-9 blockText">#{{ transaction.transactionConfirmedInBlock }}</li>
</ul>
<ul class="list-inline row">
<li class="list-inline-item col blockLabel">Confirmations</li>
<li class="list-inline-item col-9 blockText">{{ confirmations }}</li>
</ul> </ul>
<ul class="list-inline row"> <ul class="list-inline row">
<li class="list-inline-item col blockLabel mb-3">Transaction ID</li> <li class="list-inline-item col blockLabel mb-3">Transaction ID</li>
<li class="list-inline-item col-10 blockID"><code>{{ transaction.id }}</code></li> <li class="list-inline-item col-10 blockID"><code>{{ transaction.transactionId }}</code></li>
<span class="float-right"><a ngxClipboard [cbContent]="transaction.id" (click)="onCopiedClick()">copy</a></span> <span class="float-right"><a ngxClipboard [cbContent]="transaction.transactionId" (click)="onCopiedClick()">copy</a></span>
<div class="col-12"> <div class="col-12">
<span class="badge badge-success list-inline-item col" *ngIf="copied">The transaction ID has been copied to your clipboard.</span> <span class="badge badge-success list-inline-item col" *ngIf="copied">The transaction ID has been copied to your clipboard.</span>
</div> </div>
......
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { Subscription } from 'rxjs/Subscription';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { TransactionInfo } from '../../shared/classes/transaction-info';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
@Component({ @Component({
selector: 'transaction-details', selector: 'transaction-details',
templateUrl: './transaction-details.component.html', templateUrl: './transaction-details.component.html',
styleUrls: ['./transaction-details.component.css'] styleUrls: ['./transaction-details.component.css']
}) })
export class TransactionDetailsComponent implements OnInit { export class TransactionDetailsComponent implements OnInit, OnDestroy {
@Input() transaction; @Input() transaction: TransactionInfo;
constructor(public activeModal: NgbActiveModal) {} constructor(private apiService: ApiService, private globalService: GlobalService, public activeModal: NgbActiveModal) {}
public copied: boolean = false; public copied: boolean = false;
private generalWalletInfoSubscription: Subscription;
private lastBlockSyncedHeight: number;
private confirmations: number;
ngOnInit() { ngOnInit() {
this.startSubscriptions();
}
ngOnDestroy() {
this.cancelSubscriptions();
} }
public onCopiedClick() { public onCopiedClick() {
this.copied = true; this.copied = true;
} }
private getGeneralWalletInfo() {
let walletInfo = new WalletInfo(this.globalService.getWalletName())
this.generalWalletInfoSubscription = this.apiService.getGeneralInfo(walletInfo)
.subscribe(
response => {
if (response.status >= 200 && response.status < 400) {
let generalWalletInfoResponse = response.json();
this.lastBlockSyncedHeight = generalWalletInfoResponse.lastBlockSyncedHeight;
this.getConfirmations(this.transaction);
}
},
error => {
console.log(error);
if (error.status === 0) {
alert("Something went wrong while connecting to the API. Please restart the application.");
} else if (error.status >= 400) {
if (!error.json().errors[0]) {
console.log(error);
}
else {
if (error.json().errors[0].description) {
alert(error.json().errors[0].description);
} else {
this.cancelSubscriptions();
this.startSubscriptions();
}
}
}
}
)
;
};
private getConfirmations(transaction: TransactionInfo) {
if (transaction.transactionConfirmedInBlock) {
this.confirmations = this.lastBlockSyncedHeight - Number(transaction.transactionConfirmedInBlock) + 1;
} else {
this.confirmations = 0;
}
}
private cancelSubscriptions() {
if(this.generalWalletInfoSubscription) {
this.generalWalletInfoSubscription.unsubscribe();
}
};
private startSubscriptions() {
this.getGeneralWalletInfo();
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment