diff --git a/StratisCore.UI/src/app/shared/BaseUnit.ts b/StratisCore.UI/src/app/shared/BaseUnit.ts new file mode 100644 index 00000000..cadb5837 --- /dev/null +++ b/StratisCore.UI/src/app/shared/BaseUnit.ts @@ -0,0 +1,3 @@ +export class BaseUnit { + constructor(public name: string, public multiple: number, public defaultFormat: string) { } +} \ No newline at end of file diff --git a/StratisCore.UI/src/app/shared/coins/coins.component.css b/StratisCore.UI/src/app/shared/coins/coins.component.css new file mode 100644 index 00000000..e69de29b diff --git a/StratisCore.UI/src/app/shared/coins/coins.component.spec.ts b/StratisCore.UI/src/app/shared/coins/coins.component.spec.ts new file mode 100644 index 00000000..3a4b3fed --- /dev/null +++ b/StratisCore.UI/src/app/shared/coins/coins.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CoinsComponent } from './coins.component'; + +describe('CoinsComponent', () => { + let component: CoinsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CoinsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CoinsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/StratisCore.UI/src/app/shared/coins/coins.component.ts b/StratisCore.UI/src/app/shared/coins/coins.component.ts new file mode 100644 index 00000000..f187b1e9 --- /dev/null +++ b/StratisCore.UI/src/app/shared/coins/coins.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { GlobalService } from '../services/global.service'; +import { BaseUnit } from "../BaseUnit"; +import { Subject } from 'rxjs'; + +@Component({ + selector: 'coins', + template: ` + {{ (amount ? amount : 0) | coinNotation:baseUnit.multiple | number:format }} {{ this.coinUnit | prefixCoinUnit:baseUnit.name }} + ` +}) +export class CoinsComponent implements OnInit { + + @Input() + amount: number = 0; + + @Input() + showUnit: boolean = true; + + @Input() + format: string = undefined; + + baseUnit: BaseUnit; + coinUnit: string; + baseUnitSubscription: any; + + constructor(private globalService: GlobalService) { + this.baseUnitSubscription = this.globalService.baseUnit.subscribe(b => { + this.baseUnit = b; + this.format = this.format != undefined ? this.format : b.defaultFormat; + }); + + this.coinUnit = this.globalService.getCoinUnit(); + } + + ngOnInit() { + } + + ngOnDestroy() { + this.baseUnitSubscription.unsubscribe(); + } + +} diff --git a/StratisCore.UI/src/app/shared/pipes/coin-notation.pipe.ts b/StratisCore.UI/src/app/shared/pipes/coin-notation.pipe.ts index d8a93dde..ca9fba2d 100644 --- a/StratisCore.UI/src/app/shared/pipes/coin-notation.pipe.ts +++ b/StratisCore.UI/src/app/shared/pipes/coin-notation.pipe.ts @@ -8,10 +8,10 @@ export class CoinNotationPipe implements PipeTransform { private decimalLimit = 8; - transform(value: number): number { - let temp; + transform(value: number, multiple: number = 100000000): number { + let temp; if (typeof value === 'number') { - temp = value / 100000000; + temp = value / multiple; return temp.toFixed(this.decimalLimit); } } diff --git a/StratisCore.UI/src/app/shared/pipes/prefix-coin-unit.pipe.spec.ts b/StratisCore.UI/src/app/shared/pipes/prefix-coin-unit.pipe.spec.ts new file mode 100644 index 00000000..23bca749 --- /dev/null +++ b/StratisCore.UI/src/app/shared/pipes/prefix-coin-unit.pipe.spec.ts @@ -0,0 +1,8 @@ +import { PrefixCoinUnitPipe } from './prefix-coin-unit.pipe'; + +describe('PrefixCoinUnitPipe', () => { + it('create an instance', () => { + const pipe = new PrefixCoinUnitPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/StratisCore.UI/src/app/shared/pipes/prefix-coin-unit.pipe.ts b/StratisCore.UI/src/app/shared/pipes/prefix-coin-unit.pipe.ts new file mode 100644 index 00000000..7af8c960 --- /dev/null +++ b/StratisCore.UI/src/app/shared/pipes/prefix-coin-unit.pipe.ts @@ -0,0 +1,15 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'prefixCoinUnit' +}) +export class PrefixCoinUnitPipe implements PipeTransform { + + transform(value: string, baseUnit: string): any { + if (baseUnit === 'sats') { + return baseUnit; + } + + return baseUnit + value; + } +} diff --git a/StratisCore.UI/src/app/shared/services/global.service.ts b/StratisCore.UI/src/app/shared/services/global.service.ts index 19355556..82a3accd 100644 --- a/StratisCore.UI/src/app/shared/services/global.service.ts +++ b/StratisCore.UI/src/app/shared/services/global.service.ts @@ -1,5 +1,8 @@ import {Injectable} from "@angular/core"; import { ElectronService } from 'ngx-electron'; +import { BehaviorSubject, Observable } from "rxjs"; +import { take, map } from "rxjs/operators"; +import { BaseUnit } from "../BaseUnit"; @Injectable({ providedIn: 'root' @@ -10,6 +13,15 @@ export class GlobalService { this.setSidechainEnabled(); this.setTestnetEnabled(); this.setApiPort(); + + // Store by name so we can match the object and populate the settings list correctly. + let storedBaseUnitName = localStorage.getItem('baseUnit'); + + if (storedBaseUnitName) { + let baseUnit = this.baseUnits.find(b => b.name === storedBaseUnitName); + if (baseUnit) + this.baseUnit.next(baseUnit); + } } private applicationVersion: string = "1.0.0"; @@ -25,6 +37,23 @@ export class GlobalService { private coinUnit: string; private network: string; + // Base units relative to sats + private baseUnits = [ + new BaseUnit('', 100000000, '1.8-8'), // BTC = 100,000,000 sats + new BaseUnit('m', 100000, '1.5-8'), // mBTC = 100,000 sats + new BaseUnit('μ', 100, '1.2-8'), // μBTC = 100 sats + new BaseUnit('sats', 1, '1.0-0') // Defaults are in sats, no decimal places + ]; + + public baseUnit: BehaviorSubject = new BehaviorSubject(this.baseUnits[0]); + + public formattedBaseUnit: Observable = this.baseUnit.pipe(map(baseUnit => { + if (baseUnit.name === 'sats') { + return baseUnit.name; + } + + return baseUnit.name + this.coinUnit; + })); getApplicationVersion() { return this.applicationVersion; @@ -105,4 +134,13 @@ export class GlobalService { setCoinUnit(coinUnit: string) { this.coinUnit = coinUnit; } + + setBaseUnit(baseUnit: BaseUnit) { + localStorage.setItem('baseUnit', baseUnit.name); + this.baseUnit.next(baseUnit); + } + + getBaseUnits() { + return this.baseUnits; + } } diff --git a/StratisCore.UI/src/app/shared/shared.module.ts b/StratisCore.UI/src/app/shared/shared.module.ts index a53cca50..862a0ebc 100644 --- a/StratisCore.UI/src/app/shared/shared.module.ts +++ b/StratisCore.UI/src/app/shared/shared.module.ts @@ -10,11 +10,13 @@ import { NgxPaginationModule } from 'ngx-pagination'; import { ClipboardModule } from 'ngx-clipboard'; import { ReactiveFormsModule, FormsModule } from '@angular/forms'; import { GenericModalComponent } from './components/generic-modal/generic-modal.component'; +import { CoinsComponent } from './coins/coins.component'; +import { PrefixCoinUnitPipe } from './pipes/prefix-coin-unit.pipe'; @NgModule({ imports: [ CommonModule ], - declarations: [ CoinNotationPipe, AutoFocusDirective, PasswordValidationDirective, GenericModalComponent ], - exports: [ CommonModule, ReactiveFormsModule, FormsModule, NgbModule, NgxElectronModule, NgxQRCodeModule, NgxPaginationModule, ClipboardModule, GenericModalComponent, CoinNotationPipe, AutoFocusDirective, PasswordValidationDirective ], + declarations: [ CoinNotationPipe, AutoFocusDirective, PasswordValidationDirective, GenericModalComponent, CoinsComponent, PrefixCoinUnitPipe ], + exports: [ CommonModule, ReactiveFormsModule, FormsModule, NgbModule, NgxElectronModule, NgxQRCodeModule, NgxPaginationModule, ClipboardModule, GenericModalComponent, CoinNotationPipe, AutoFocusDirective, PasswordValidationDirective, CoinsComponent, PrefixCoinUnitPipe ], entryComponents: [ GenericModalComponent ] }) diff --git a/StratisCore.UI/src/app/wallet/advanced/advanced.component.html b/StratisCore.UI/src/app/wallet/advanced/advanced.component.html index ae380467..6d95fafe 100644 --- a/StratisCore.UI/src/app/wallet/advanced/advanced.component.html +++ b/StratisCore.UI/src/app/wallet/advanced/advanced.component.html @@ -22,6 +22,9 @@ + diff --git a/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.css b/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.css new file mode 100644 index 00000000..e69de29b diff --git a/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.html b/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.html new file mode 100644 index 00000000..da392393 --- /dev/null +++ b/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.html @@ -0,0 +1,16 @@ +
+
Change Base Unit
+
+
+
+ Base Unit: +
+
+ + 1 Strat = +
+
+
+
diff --git a/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.spec.ts b/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.spec.ts new file mode 100644 index 00000000..cdc68d06 --- /dev/null +++ b/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BaseUnitComponent } from './base-unit.component'; + +describe('BaseUnitComponent', () => { + let component: BaseUnitComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BaseUnitComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BaseUnitComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.ts b/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.ts new file mode 100644 index 00000000..c61578fc --- /dev/null +++ b/StratisCore.UI/src/app/wallet/advanced/components/base-unit/base-unit.component.ts @@ -0,0 +1,34 @@ +import { Component, OnInit } from '@angular/core'; +import { GlobalService } from '../../../../shared/services/global.service'; +import { BaseUnit } from '../../../../shared/BaseUnit'; +import { take } from 'rxjs/operators'; + +@Component({ + selector: 'app-base-unit', + templateUrl: './base-unit.component.html', + styleUrls: ['./base-unit.component.css'] +}) +export class BaseUnitComponent implements OnInit { + coinUnit: string; + baseUnits: BaseUnit[]; + + constructor(private globalService: GlobalService) { + // Set the initial value + this.globalService.baseUnit.pipe(take(1)).subscribe(b => { + this.selectedBaseUnit = b; + }); + + this.coinUnit = this.globalService.getCoinUnit(); + this.baseUnits = this.globalService.getBaseUnits(); + } + + selectedBaseUnit: BaseUnit; + + ngOnInit() { + } + + onBaseUnitChanged() { + this.globalService.setBaseUnit(this.selectedBaseUnit); + } + +} diff --git a/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.html b/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.html index c2579299..f83fe998 100644 --- a/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.html +++ b/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.html @@ -8,12 +8,12 @@
Spendable balance

- {{ (confirmedBalance | coinNotation) || (0 | coinNotation) }} - {{ coinUnit }} + + {{ coinUnit }}

    -
  • {{ (unconfirmedBalance | coinNotation) || (0 | coinNotation) }} (unconfirmed)
  • +
  • (unconfirmed)
@@ -66,9 +66,9 @@
Spendable balance
{{ transaction.transactionType }} - - {{ transaction.transactionAmount + transaction.transactionFee | coinNotation }} {{ coinUnit }} - + {{ transaction.transactionAmount + transaction.transactionFee | coinNotation }} {{ coinUnit }} - + {{ transaction.transactionAmount + transaction.transactionFee | coinNotation }} {{ coinUnit }} + - + + + + {{ transaction.transactionTimestamp * 1000 | date:'medium' }} details @@ -145,9 +145,9 @@
Spendable balance
  • Waiting for staking to start...
  • -
  • Staking weight: {{ stakingWeight | coinNotation | number: '1.0-0' }} {{ coinUnit }}
  • -
  • Coins awaiting maturity: {{ awaitingMaturity | coinNotation | number: '1.0-0' }} {{ coinUnit }}
  • -
  • Network weight: {{ netStakingWeight | coinNotation | number: '1.0-0' }} {{ coinUnit }}
  • +
  • Staking weight:
  • +
  • Coins awaiting maturity:
  • +
  • Network weight:
  • Expected reward time is:
  • {{ dateTime }}
  • diff --git a/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.ts b/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.ts index 34563c9a..9a922486 100644 --- a/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.ts +++ b/StratisCore.UI/src/app/wallet/dashboard/dashboard.component.ts @@ -50,7 +50,11 @@ export class DashboardComponent implements OnInit, OnDestroy { ngOnInit() { this.sidechainEnabled = this.globalService.getSidechainEnabled(); this.walletName = this.globalService.getWalletName(); - this.coinUnit = this.globalService.getCoinUnit(); + + this.globalService.formattedBaseUnit + .pipe(takeUntil(this.destroyed$)) + .subscribe(baseUnit => this.coinUnit = baseUnit); + this.refreshData(); }; diff --git a/StratisCore.UI/src/app/wallet/history/history.component.html b/StratisCore.UI/src/app/wallet/history/history.component.html index 95ed1b1b..9e95c052 100644 --- a/StratisCore.UI/src/app/wallet/history/history.component.html +++ b/StratisCore.UI/src/app/wallet/history/history.component.html @@ -16,9 +16,9 @@ {{ transaction.transactionType }} - - {{ transaction.transactionAmount + transaction.transactionFee | coinNotation }} {{ coinUnit }} - + {{ transaction.transactionAmount + transaction.transactionFee | coinNotation }} {{ coinUnit }} - + {{ transaction.transactionAmount + transaction.transactionFee | coinNotation }} {{ coinUnit }} + - + + + + {{ transaction.transactionTimestamp * 1000 | date:'medium' }} details diff --git a/StratisCore.UI/src/app/wallet/send/send.component.html b/StratisCore.UI/src/app/wallet/send/send.component.html index 96397f5f..e37ee49b 100644 --- a/StratisCore.UI/src/app/wallet/send/send.component.html +++ b/StratisCore.UI/src/app/wallet/send/send.component.html @@ -18,7 +18,7 @@
    - +
    {{ sendFormErrors.amount }}
    @@ -33,7 +33,7 @@
    Please enter a valid amount and destination address to calculate the fee. - +
    - +
    {{ sendToSidechainFormErrors.amount }}
    @@ -107,7 +107,7 @@
    Please enter a valid amount, federation and destination address to calculate the fee. - +