Merge pull request #793 from SonicWizard/ionic

Update CurrencyProvider with USD. Enable denomination changes on all the things.
This commit is contained in:
Justin Langston 2017-08-12 08:57:53 -04:00 committed by GitHub
commit 5e1e80a858
16 changed files with 118 additions and 51 deletions

View File

@ -8,6 +8,7 @@ import { InsightApp } from './app.component';
import { PagesModule, BlocksPage, BroadcastTxPage, NodeStatusPage, VerifyMessagePage } from '../pages'; import { PagesModule, BlocksPage, BroadcastTxPage, NodeStatusPage, VerifyMessagePage } from '../pages';
import { BlocksService, StorageService } from '../services'; import { BlocksService, StorageService } from '../services';
import { ApiProvider } from '../providers/api/api'; import { ApiProvider } from '../providers/api/api';
import { CurrencyProvider } from '../providers/currency/currency';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -33,7 +34,8 @@ import { ApiProvider } from '../providers/api/api';
StorageService, StorageService,
BlocksService, BlocksService,
{provide: ErrorHandler, useClass: IonicErrorHandler}, {provide: ErrorHandler, useClass: IonicErrorHandler},
ApiProvider ApiProvider,
CurrencyProvider
] ]
}) })

View File

@ -15,6 +15,16 @@
white-space: nowrap; white-space: nowrap;
} }
.summary ion-label {
color: #333;
font-weight: bold;
}
.summary ion-item {
color: #999;
font-size: 1.4rem;
}
// Shared Sass variables, which can be used to adjust Ionic's // Shared Sass variables, which can be used to adjust Ionic's
// default Sass variables, belong in "theme/variables.scss". // default Sass variables, belong in "theme/variables.scss".
// //

View File

@ -4,6 +4,9 @@
</button> </button>
<ion-title>{{title}}</ion-title> <ion-title>{{title}}</ion-title>
<ion-buttons end> <ion-buttons end>
<button ion-button (click)="changeCurrency()">
<ion-icon name="logo-bitcoin" *ngIf="currency.currencySymbol !== 'USD'"></ion-icon><ion-icon name="logo-usd" *ngIf="currency.currencySymbol === 'USD'"></ion-icon>&nbsp;{{ currency.currencySymbol }}
</button>
<button ion-button icon-only> <button ion-button icon-only>
<ion-icon name="search"></ion-icon> <ion-icon name="search"></ion-icon>
</button> </button>

View File

@ -4,10 +4,10 @@ import { HeadNavComponent } from './head-nav';
@NgModule({ @NgModule({
declarations: [ declarations: [
HeadNavComponent, HeadNavComponent
], ],
imports: [ imports: [
IonicModule, IonicModule
], ],
exports: [ exports: [
HeadNavComponent HeadNavComponent

View File

@ -3,6 +3,8 @@ import { Input } from '@angular/core';
import { NavController } from 'ionic-angular'; import { NavController } from 'ionic-angular';
import { Http } from '@angular/http'; import { Http } from '@angular/http';
import { ApiProvider } from '../../providers/api/api'; import { ApiProvider } from '../../providers/api/api';
import { CurrencyProvider } from '../../providers/currency/currency';
import { ActionSheetController } from 'ionic-angular';
/** /**
* Generated class for the HeadNavComponent component. * Generated class for the HeadNavComponent component.
@ -21,19 +23,14 @@ export class HeadNavComponent {
public q: string; public q: string;
public badQuery: boolean = false; public badQuery: boolean = false;
constructor(private navCtrl: NavController, private http: Http, private api: ApiProvider) { constructor(private navCtrl: NavController, private http: Http, private api: ApiProvider, public currency: CurrencyProvider, public actionSheetCtrl: ActionSheetController) {
}
private resetSearch(): void {
this.q = '';
this.loading = false;
} }
public search(): void { public search(): void {
let apiPrefix: string = this.api.apiPrefix; let apiPrefix: string = this.api.apiPrefix;
this.http.get(apiPrefix + 'block/' + this.q).subscribe( this.http.get(apiPrefix + 'block/' + this.q).subscribe(
function (data: any) { function (data: any): void {
this.resetSearch(); this.resetSearch();
console.log('block', data); console.log('block', data);
let parsedData: any = JSON.parse(data._body); let parsedData: any = JSON.parse(data._body);
@ -43,7 +40,7 @@ export class HeadNavComponent {
}.bind(this), }.bind(this),
() => { () => {
this.http.get(apiPrefix + 'tx/' + this.q).subscribe( this.http.get(apiPrefix + 'tx/' + this.q).subscribe(
function (data: any) { function (data: any): void {
this.resetSearch(); this.resetSearch();
console.log('tx', data); console.log('tx', data);
let parsedData: any = JSON.parse(data._body); let parsedData: any = JSON.parse(data._body);
@ -53,7 +50,7 @@ export class HeadNavComponent {
}.bind(this), }.bind(this),
() => { () => {
this.http.get(apiPrefix + 'addr/' + this.q).subscribe( this.http.get(apiPrefix + 'addr/' + this.q).subscribe(
function (data: any) { function (data: any): void {
this.resetSearch(); this.resetSearch();
console.log('addr', data); console.log('addr', data);
let parsedData: any = JSON.parse(data._body); let parsedData: any = JSON.parse(data._body);
@ -96,6 +93,47 @@ export class HeadNavComponent {
2000 2000
); );
}; };
private resetSearch(): void {
this.q = '';
this.loading = false;
}
/* tslint:enable:no-unused-variable */ /* tslint:enable:no-unused-variable */
public changeCurrency(): void {
let actionSheet: any = this.actionSheetCtrl.create({
title: 'Change Denomination',
buttons: [
{
text: 'USD',
handler: () => {
this.currency.setCurrency('USD');
}
},
{
text: 'BTC',
handler: () => {
this.currency.setCurrency('BTC');
}
},
{
text: 'mBTC',
handler: () => {
this.currency.setCurrency('mBTC');
}
},
{
text: 'bits',
handler: () => {
this.currency.setCurrency('bits');
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
actionSheet.present();
}
} }

View File

@ -29,9 +29,9 @@
<ion-list [hidden]="tx.isCoinBase"> <ion-list [hidden]="tx.isCoinBase">
<ion-item *ngFor="let vin of tx.vin"> <ion-item *ngFor="let vin of tx.vin">
<div> <div>
<p><a (click)="goToAddress(vin.addr)">{{ vin.addr }}</a> <span item-end>{{ vin.value + ' BTC' }}</span></p> <p><a (click)="goToAddress(vin.addr)">{{ vin.addr }}</a> <span item-end>{{ currency.getConversion(vin.value) }}</span></p>
<div [hidden]="!expanded"> <div [hidden]="!expanded">
<p><b>Confirmations</b> {{vin.confirmations}}</p> <p *ngIf="vin.confirmations"><b>Confirmations</b> {{vin.confirmations}}</p>
<p><b>scriptSig</b></p> <p><b>scriptSig</b></p>
<div *ngIf="vin.scriptSig"> <div *ngIf="vin.scriptSig">
<div *ngFor="let item of vin.scriptSig.asm | split:' '" class="ellipsis"> <div *ngFor="let item of vin.scriptSig.asm | split:' '" class="ellipsis">
@ -44,10 +44,10 @@
</ion-list> </ion-list>
</ion-col> </ion-col>
<ion-col col-2 text-center> <ion-col col-1 text-center>
<ion-icon name="arrow-forward"></ion-icon> <ion-icon name="arrow-forward"></ion-icon>
</ion-col> </ion-col>
<ion-col col-5> <ion-col col-6>
<ion-list> <ion-list>
<ion-item *ngFor="let vout of tx.vout"> <ion-item *ngFor="let vout of tx.vout">
<div> <div>
@ -62,7 +62,7 @@
</div> </div>
<div item-end> <div item-end>
{{ vout.value + ' BTC' }} {{ currency.getConversion(vout.value) }}
<span [hidden]="!vout.spentTxId">(S)</span> <span [hidden]="!vout.spentTxId">(S)</span>
<span [hidden]="vout.spentTxId">(U)</span> <span [hidden]="vout.spentTxId">(U)</span>
</div> </div>
@ -73,11 +73,11 @@
<ion-row> <ion-row>
<ion-col col-6> <ion-col col-6>
<span [hidden]="tx.isCoinBase">Fee {{ tx.fees + ' BTC' }}</span> <span [hidden]="tx.isCoinBase">Fee {{ currency.getConversion(tx.fees) }}</span>
</ion-col> </ion-col>
<ion-col col-6 text-right> <ion-col col-6 text-right>
{{ tx.confirmations }} Confirmations {{ tx.confirmations }} Confirmations
<span class="">{{ tx.valueOut + ' BTC' }}</span> <span class="">{{ currency.getConversion(tx.valueOut) }}</span>
</ion-col> </ion-col>
</ion-row> </ion-row>
</ion-grid> </ion-grid>

View File

@ -1,6 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Input } from '@angular/core'; import { Input } from '@angular/core';
import { NavController } from 'ionic-angular'; import { NavController } from 'ionic-angular';
import { CurrencyProvider } from '../../providers/currency/currency';
/** /**
* Generated class for the TransactionComponent component. * Generated class for the TransactionComponent component.
@ -17,7 +18,7 @@ export class TransactionComponent {
public expanded: boolean = false; public expanded: boolean = false;
@Input() public tx: any = {}; @Input() public tx: any = {};
constructor(private navCtrl: NavController) { constructor(private navCtrl: NavController, public currency: CurrencyProvider) {
} }
public getAddress(vout: any): string { public getAddress(vout: any): string {

View File

@ -5,27 +5,27 @@
<ion-content padding> <ion-content padding>
<h1>Address</h1> <h1>Address</h1>
<p class="ellipsis"><b>Address</b> {{ address.addrStr }}</p> <p class="ellipsis"><b>Address</b> {{ address.addrStr }}</p>
<p>{{ address.balance }} BTC</p> <p>{{ currency.getConversion(address.balance) }}</p>
<h2>Summary</h2> <h2>Summary</h2>
<ion-list> <ion-list class="summary">
<ion-item> <ion-item>
Total Received Total Received
<span item-end> <span item-end>
{{ address.totalReceived }} BTC {{ currency.getConversion(address.totalReceived) }}
</span> </span>
</ion-item> </ion-item>
<ion-item> <ion-item>
Total Sent Total Sent
<span item-end> <span item-end>
{{ address.totalSent }} BTC {{ currency.getConversion(address.totalSent) }}
</span> </span>
</ion-item> </ion-item>
<ion-item> <ion-item>
Final Balance Final Balance
<span item-end> <span item-end>
{{ address.balance }} BTC {{ currency.getConversion(address.balance) }}
</span> </span>
</ion-item> </ion-item>
<ion-item> <ion-item>

View File

@ -2,6 +2,7 @@ import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular'; import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Http } from '@angular/http'; import { Http } from '@angular/http';
import { ApiProvider } from '../../providers/api/api'; import { ApiProvider } from '../../providers/api/api';
import { CurrencyProvider } from '../../providers/currency/currency';
/** /**
* Generated class for the AddressPage page. * Generated class for the AddressPage page.
@ -23,7 +24,7 @@ export class AddressPage {
private addrStr: string; private addrStr: string;
public address: any = {}; public address: any = {};
constructor(public navCtrl: NavController, public navParams: NavParams, private http: Http, private api: ApiProvider) { constructor(public navCtrl: NavController, public navParams: NavParams, private http: Http, private api: ApiProvider, public currency: CurrencyProvider) {
this.addrStr = navParams.get('addrStr'); this.addrStr = navParams.get('addrStr');
} }

View File

@ -8,9 +8,9 @@
<h2>Summary</h2> <h2>Summary</h2>
<ion-list *ngIf="!loading"> <ion-list *ngIf="!loading" class="summary">
<ion-item> <ion-item>
Number of Transactions Number of Transactions
<span item-end> <span item-end>
{{ block.tx.length }} {{ block.tx.length }}
</span> </span>
@ -24,7 +24,7 @@
<ion-item> <ion-item>
Block Reward Block Reward
<span item-end> <span item-end>
{{ block.reward + ' BTC' }} {{ currency.getConversion(block.reward) }}
</span> </span>
</ion-item> </ion-item>
<ion-item> <ion-item>

View File

@ -2,6 +2,7 @@ import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular'; import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Http } from '@angular/http'; import { Http } from '@angular/http';
import { ApiProvider } from '../../providers/api/api'; import { ApiProvider } from '../../providers/api/api';
import { CurrencyProvider } from '../../providers/currency/currency';
/** /**
* Generated class for the BlockDetailPage page. * Generated class for the BlockDetailPage page.
@ -25,9 +26,11 @@ export class BlockDetailPage {
tx: [] tx: []
}; };
constructor(public navCtrl: NavController, private http: Http, public navParams: NavParams, private api: ApiProvider) { constructor(public navCtrl: NavController, private http: Http, public navParams: NavParams, private api: ApiProvider, public currency: CurrencyProvider) {
this.blockHash = navParams.get('blockHash'); this.blockHash = navParams.get('blockHash');
}
public ionViewDidLoad(): void {
this.http.get(this.api.apiPrefix + 'block/' + this.blockHash).subscribe( this.http.get(this.api.apiPrefix + 'block/' + this.blockHash).subscribe(
(data) => { (data) => {
this.block = JSON.parse(data['_body']); this.block = JSON.parse(data['_body']);
@ -40,10 +43,6 @@ export class BlockDetailPage {
); );
} }
public ionViewWillLeave(): void {
this.loading = true;
}
public goToPreviousBlock(): void { public goToPreviousBlock(): void {
this.navCtrl.push('block-detail', { this.navCtrl.push('block-detail', {
'blockHash': this.block.previousblockhash 'blockHash': this.block.previousblockhash

View File

@ -8,7 +8,7 @@
<h2>Summary</h2> <h2>Summary</h2>
<ion-list> <ion-list class="summary">
<ion-item> <ion-item>
Size Size
<span item-end> <span item-end>

View File

@ -15,7 +15,6 @@ export class SplitPipe implements PipeTransform {
*/ */
public transform(value: string, delimiter: string): Array<string> { public transform(value: string, delimiter: string): Array<string> {
let array: Array<string> = value.split(delimiter); let array: Array<string> = value.split(delimiter);
console.log('split is', array);
return array; return array;
} }
} }

View File

@ -2,9 +2,10 @@
import { TestBed, ComponentFixture, inject } from '@angular/core/testing'; import { TestBed, ComponentFixture, inject } from '@angular/core/testing';
import { HttpModule } from '@angular/http'; import { HttpModule } from '@angular/http';
import { CurrencyProvider } from './currency'; import { CurrencyProvider } from './currency';
import { ApiProvider } from '../api/api';
describe('CurrencyProvider', () => { describe('CurrencyProvider', () => {
let currency; let currency: CurrencyProvider;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@ -12,6 +13,7 @@ describe('CurrencyProvider', () => {
HttpModule HttpModule
], ],
providers: [ providers: [
ApiProvider,
CurrencyProvider CurrencyProvider
] ]
}); });
@ -47,7 +49,7 @@ describe('CurrencyProvider', () => {
}); });
it('rounds float using specified number of decimal places', () => { it('rounds float using specified number of decimal places', () => {
let aFloat = 4.32943; let aFloat: number = 4.32943;
expect(currency.roundFloat(aFloat, 2)).toBe(4.33); expect(currency.roundFloat(aFloat, 2)).toBe(4.33);
expect(currency.roundFloat(aFloat, 3)).toBe(4.329); expect(currency.roundFloat(aFloat, 3)).toBe(4.329);
@ -66,7 +68,7 @@ describe('CurrencyProvider', () => {
}); });
it('gets proper conversion after changing currency', () => { it('gets proper conversion after changing currency', () => {
let aFloat = 12345.09876543; let aFloat: number = 12345.09876543;
expect(currency.getConversion(aFloat)).toBe('12345.09876543 BTC'); expect(currency.getConversion(aFloat)).toBe('12345.09876543 BTC');
currency.setCurrency('mBTC'); currency.setCurrency('mBTC');

View File

@ -1,5 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http } from '@angular/http'; import { Http } from '@angular/http';
import { ApiProvider } from '../../providers/api/api';
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/map';
/* /*
@ -11,16 +12,18 @@ import 'rxjs/add/operator/map';
@Injectable() @Injectable()
export class CurrencyProvider { export class CurrencyProvider {
private defaultCurrency: string; public defaultCurrency: string;
private currencySymbol: string; public currencySymbol: string;
private factor: number = 1; public factor: number = 1;
private bitstamp: number;
private loading: boolean;
constructor(public http: Http) { constructor(public http: Http, private api: ApiProvider) {
this.defaultCurrency = 'BTC'; this.defaultCurrency = 'BTC';
this.currencySymbol = this.defaultCurrency; this.currencySymbol = this.defaultCurrency;
} }
private roundFloat(aFloat: number, decimalPlaces: number): number { public roundFloat(aFloat: number, decimalPlaces: number): number {
return Math.round(aFloat * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces); return Math.round(aFloat * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
} }
@ -50,12 +53,17 @@ export class CurrencyProvider {
localStorage.setItem('insight-currency', currency); localStorage.setItem('insight-currency', currency);
if (currency === 'USD') { if (currency === 'USD') {
// TODO Replace this with call this.http.get(this.api.apiPrefix + 'currency').subscribe(
/* (data) => {
Currency.get({}, function(res) { let currencyParsed: any = JSON.parse(data['_body']);
$rootScope.currency.factor = $rootScope.currency.bitstamp = res.data.bitstamp; this.factor = this.bitstamp = currencyParsed.data.bitstamp;
}); this.loading = false;
*/ },
(err) => {
console.log('err is', err);
this.loading = false;
}
);
} else if (currency === 'mBTC') { } else if (currency === 'mBTC') {
this.factor = 1000; this.factor = 1000;
} else if (currency === 'bits') { } else if (currency === 'bits') {

View File

@ -17,7 +17,9 @@ import { ConfigMock, PlatformMock } from './mocks';
import { BlocksServiceMock } from './services/mocks'; import { BlocksServiceMock } from './services/mocks';
import { BlocksService } from './services'; import { BlocksService } from './services';
import { ApiProvider } from './providers/api/api'; import { ApiProvider } from './providers/api/api';
import { CurrencyProvider } from './providers/currency/currency';
import { HeadNavComponentModule } from './components/head-nav/head-nav.module'; import { HeadNavComponentModule } from './components/head-nav/head-nav.module';
import { ActionSheetController } from 'ionic-angular';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any; declare var __karma__: any;
@ -63,7 +65,9 @@ export class TestUtils {
{provide: Platform, useClass: PlatformMock}, {provide: Platform, useClass: PlatformMock},
{provide: Config, useClass: ConfigMock}, {provide: Config, useClass: ConfigMock},
{provide: BlocksService, useClass: BlocksServiceMock}, {provide: BlocksService, useClass: BlocksServiceMock},
ApiProvider ApiProvider,
CurrencyProvider,
ActionSheetController
], ],
imports: [ imports: [
FormsModule, FormsModule,