Commit b1355d6a authored by Paul Herbert's avatar Paul Herbert

2100 - Breeze ICO updates

parent 1344ee0e
......@@ -58,8 +58,9 @@
"core-js": "2.5.3",
"electron-context-menu": "0.9.1",
"enhanced-resolve": "3.4.1",
"ngx-clipboard": "9.0.0",
"ng2-datepicker": "^3.1.0",
"ngx-bootstrap": "2.0.0-beta.11",
"ngx-clipboard": "9.0.0",
"rxjs": "5.5.5",
"zone.js": "0.8.18"
},
......
<form [formGroup]='icoFormGroup'>
<div class="container" style="border:1px solid lightgray; border-radius: 4px; padding:10px; position: absolute; left:100px; width:65%">
<h4>ICO</h4>
<div style="margin-top:15px">
<div>
<label style="font-size:14px;margin-bottom:0px">Extended Public Key</label>
<div class="myAddress" *ngIf="extPubKeyLoadingState.success; else elseFeedback"><code style="overflow-wrap: break-word">{{ extPubKey }}</code></div>
<ng-template #elseFeedback>
<app-feedback [loading]="extPubKeyLoadingState.loading"
[errored]="extPubKeyLoadingState.errored"
[erroredText]="'Failed to get Extended Public Key'"></app-feedback>
</ng-template>
</div>
<div style="margin-top:20px">
<label style="font-size:14px;margin-bottom:1px">Generate Addresses</label>
<div style="display:flex; flex-direction:row">
<div class="input-group" style="height:35px; margin-bottom:1px; width:240px">
<input formControlName="addressCountControl" type="text" class="form-control" placeholder="Number to generate..." style="border-radius: 0px">
<span class="input-group-btn">
<div>
<button *ngIf="!addressCountControl.invalid && addressCount" (click)="generateAddresses()"
class="btn btn-default" type="button">Go</button>
<button *ngIf="addressCountControl.invalid || !addressCount" style="color: gray; outline:none" class="btn btn-default" type="button">Go</button>
</div>
</span>
</div>
<img style="width:16px; height:16px; margin-left:6px"
*ngIf="showTick" src="../../../../assets/images/Tick_Mark-16.png"/>
<app-feedback *ngIf="!generateAddressesLoadingState.success" style="margin-left:5px; width:115px"
[loading]="generateAddressesLoadingState.loading"
[errored]="generateAddressesLoadingState.errored"
[erroredText]="'Failed to generate'"></app-feedback>
</div>
</div>
</div>
</div>
</form>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AdvancedIcoComponent } from './advanced-ico.component';
describe('AdvancedIcoComponent', () => {
let component: AdvancedIcoComponent;
let fixture: ComponentFixture<AdvancedIcoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AdvancedIcoComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AdvancedIcoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Subscription } from 'rxJs/Subscription';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import 'rxjs/add/operator/filter';
import { timer } from 'rxjs/observable/timer';
import { AdvancedService } from './../advanced.service';
import { LoadingState } from './loadingState';
@Component({
selector: 'app-advanced-ico',
templateUrl: './advanced-ico.component.html',
styleUrls: ['./advanced-ico.component.css']
})
export class AdvancedIcoComponent implements OnInit, OnDestroy {
private addressCount: string;
private extPubKeySubs: Subscription;
private generateAddressesSubs: Subscription;
private addresses = new Array<string>();
constructor(private advancedService: AdvancedService, private formBuilder: FormBuilder) { }
ngOnInit() {
this.registerFormControls();
this.loadExtPubKey();
}
public icoFormGroup: FormGroup;
public extPubKey = "";
public extPubKeyLoadingState = new LoadingState();
public generateAddressesLoadingState = new LoadingState();
public get addressCountControl() { return this.icoFormGroup.get('addressCountControl'); }
public get showTick() {
return this.generateAddressesLoadingState.success && this.addresses.length && (Number(this.addressCount)===this.addresses.length)
}
public generateAddresses() {
this.internalGenerateAddresses();
}
private loadExtPubKey() {
this.extPubKeyLoadingState.loading = true;
this.extPubKeySubs = this.advancedService.getExtPubKey()
.subscribe(x => this.onExtPubKey(x),
_ => this.extPubKeyLoadingState.errored = true);
}
private internalGenerateAddresses() {
this.addresses = new Array<string>();
this.generateAddressesLoadingState.loading = true;
if (this.generateAddressesSubs) {
this.generateAddressesSubs.unsubscribe();
}
this.generateAddressesSubs = this.advancedService.generateAddresses(Number(this.addressCount))
.subscribe(x => this.onGenerateAddresses(x),
_ => this.generateAddressesLoadingState.errored = true);
}
private onExtPubKey(key: string) {
this.extPubKey = key;
this.extPubKeyLoadingState.loading = false;
}
private onGenerateAddresses(addresses: string[]) {
this.generateAddressesLoadingState.loading = false;
this.addresses = addresses;
}
private registerFormControls() {
this.icoFormGroup = this.formBuilder.group({
addressCountControl: ['', [Validators.pattern('^[1-9][0-9]*$')]]
});
this.addressCountControl.valueChanges.subscribe(_ => {
if (this.addressCountControl.invalid) {
this.addressCountControl.setValue(this.addressCount);
} else {
this.addressCount = this.addressCountControl.value;
}
});
}
ngOnDestroy() {
if (this.extPubKeySubs) {
this.extPubKeySubs.unsubscribe();
}
if (this.generateAddressesSubs) {
this.generateAddressesSubs.unsubscribe();
}
}
}
.mainDiv {
margin-left: 100px;
margin-top: 20px;
}
::ng-deep ng-datepicker input {
height: 35px;
}
\ No newline at end of file
<div class="mainDiv">
<app-advanced-ico></app-advanced-ico>
<form [formGroup]='icoFormGroup'>
<div style="margin-top:15px">
<div>
<label style="font-size:14px;margin-bottom:0px">Extended Public Key</label>
<div class="myAddress" *ngIf="extPubKeyLoadingState.success; else elseFeedback">
<code style="overflow-wrap: break-word">{{ extPubKey }}</code>
</div>
<ng-template #elseFeedback>
<app-feedback [loading]="extPubKeyLoadingState.loading" [errored]="extPubKeyLoadingState.errored" [erroredText]="'Failed to get Extended Public Key'"></app-feedback>
</ng-template>
</div>
<div style="margin-top:30px">
<label style="font-size:14px;margin-bottom:1px">Generate Addresses</label>
<div style="display:flex; flex-direction:row">
<div class="input-group" style="height:35px; margin-bottom:1px; width:240px">
<input formControlName="addressCountControl" type="text" class="form-control" placeholder="Number to generate..." style="border-radius: 0px">
<span class="input-group-btn">
<div>
<button *ngIf="!addressCountControl.invalid && addressCount" (click)="generateAddresses()" class="btn btn-default" type="button">Go</button>
<button *ngIf="addressCountControl.invalid || !addressCount" style="color: gray; outline:none" class="btn btn-default" type="button">Go</button>
</div>
</span>
</div>
<img style="width:16px; height:16px; margin-left:6px" *ngIf="showAddressesTick" src="../../../assets/images/Tick_Mark-16.png"
/>
<app-feedback *ngIf="!generateAddressesLoadingState.success" style="margin-left:5px; width:115px" [loading]="generateAddressesLoadingState.loading"
[errored]="generateAddressesLoadingState.errored" [erroredText]="'Failed to generate'"></app-feedback>
</div>
</div>
<div style="margin-top:30px">
<label style="font-size:14px;margin-bottom:1px">Resync</label>
<div style="display:flex; flex-direction:row">
<div class="input-group" style="height:35px; margin-bottom:1px; width:240px">
<ng-datepicker style="width:163px" [(ngModel)]="resyncDate" [options]="resyncDateOptions" formControlName="datePickerControl"></ng-datepicker>
<span class="input-group-btn">
<div>
<button style="height: 35px" (click)="resync()" class="btn btn-default" type="button">Go</button>
</div>
</span>
</div>
<img style="width:16px; height:16px; margin-left:6px" *ngIf="showResyncTick" src="../../../assets/images/Tick_Mark-16.png"
/>
<app-feedback *ngIf="!resyncLoadingState.success" style="margin-left:5px; width:115px" [loading]="resyncLoadingState.loading"
[errored]="resyncLoadingState.errored" [erroredText]="'Failed to sync'"></app-feedback>
</div>
</div>
</div>
</form>
</div>
\ No newline at end of file
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Subscription } from 'rxJs/Subscription';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { DatepickerOptions } from 'ng2-datepicker';
import { AdvancedService } from './advanced.service';
import { LoadingState } from './loadingState';
@Component({
selector: 'app-advanced',
templateUrl: './advanced.component.html',
styleUrls: ['./advanced.component.css']
})
export class AdvancedComponent implements OnInit {
constructor() { }
selector: 'app-advanced',
templateUrl: './advanced.component.html',
styleUrls: ['./advanced.component.css']
})
export class AdvancedComponent implements OnInit, OnDestroy {
private addressCount: string;
private extPubKeySubs: Subscription;
private generateAddressesSubs: Subscription;
private resyncSubs: Subscription;
private addresses = new Array<string>();
private resyncActioned = false;
constructor(private advancedService: AdvancedService, private formBuilder: FormBuilder) { }
public icoFormGroup: FormGroup;
public extPubKey = "";
public resyncDate = new Date();
public extPubKeyLoadingState = new LoadingState();
public generateAddressesLoadingState = new LoadingState();
public resyncDateOptions: DatepickerOptions;
public resyncLoadingState = new LoadingState();
public get datePickerControl() { return this.icoFormGroup.get('datePickerControl'); }
public get addressCountControl() { return this.icoFormGroup.get('addressCountControl'); }
public get showAddressesTick() {
return this.generateAddressesLoadingState.success && this.addresses.length && (Number(this.addressCount)===this.addresses.length);
}
public get showResyncTick(): boolean { return this.resyncLoadingState.success && this.resyncActioned; }
ngOnInit() {
this.registerFormControls();
this.setResyncDateOptions();
this.loadExtPubKey();
}
public generateAddresses() {
this.addresses = new Array<string>();
this.generateAddressesLoadingState.loading = true;
if (this.generateAddressesSubs) {
this.generateAddressesSubs.unsubscribe();
}
this.generateAddressesSubs = this.advancedService.generateAddresses(Number(this.addressCount))
.subscribe(x => this.onGenerateAddresses(x),
_ => this.generateAddressesLoadingState.errored = true);
}
public resync() {
if (this.resyncSubs) {
this.resyncSubs.unsubscribe();
}
this.resyncLoadingState.loading = this.resyncActioned = true;
this.resyncSubs = this.advancedService.resyncFromDate(this.resyncDate)
.subscribe(_ => this.onResync(),
_ => this.resyncLoadingState.errored = true);
}
private loadExtPubKey() {
this.extPubKeyLoadingState.loading = true;
this.extPubKeySubs = this.advancedService.getExtPubKey()
.subscribe(x => this.onExtPubKey(x),
_ => this.extPubKeyLoadingState.errored = true);
}
private onExtPubKey(key: string) {
this.extPubKey = key;
this.extPubKeyLoadingState.loading = false;
}
}
private onGenerateAddresses(addresses: string[]) {
this.generateAddressesLoadingState.loading = false;
this.addresses = addresses;
}
private onResync() {
this.resyncLoadingState.loading = false;
}
private registerFormControls() {
this.icoFormGroup = this.formBuilder.group({
addressCountControl: ['', [Validators.pattern('^[1-9][0-9]*$')]],
datePickerControl: [Validators.required]
});
this.addressCountControl.valueChanges.subscribe(_ => {
if (this.addressCountControl.invalid) {
this.addressCountControl.setValue(this.addressCount);
} else {
this.addressCount = this.addressCountControl.value;
}
});
}
private setResyncDateOptions() {
const today = new Date();
this.resyncDateOptions = {
minDate: new Date(today.getFullYear(),0),
maxDate: today,
displayFormat: 'MMMM D[,] YYYY'
};
}
ngOnDestroy() {
if (this.extPubKeySubs) {
this.extPubKeySubs.unsubscribe();
}
if (this.generateAddressesSubs) {
this.generateAddressesSubs.unsubscribe();
}
if (this.resyncSubs) {
this.resyncSubs.unsubscribe();
}
}
}
import { Injectable } from '@angular/core';
import { Observable } from 'rxJs/Observable';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/observable/empty';
import { GlobalService } from '../../shared/services/global.service';
......@@ -24,6 +25,10 @@ export class AdvancedService {
return this.httpClient.get(url).map(x => this.processAddresses(x));
}
public resyncFromDate(date: Date): Observable<any> {
return Observable.empty<any>();
}
private processAddresses(response: any): string[] {
let addresses = new Array<string>();
for (const address of response) {
......
......@@ -4,6 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { ClipboardModule } from 'ngx-clipboard';
import { HttpClientModule } from '@angular/common/http';
import { NgDatepickerModule } from 'ng2-datepicker';
import { WalletComponent } from './wallet.component';
import { MenuComponent } from './menu/menu.component';
......@@ -15,7 +16,6 @@ import { WalletRoutingModule } from './wallet-routing.module';
import { SidebarComponent } from './sidebar/sidebar.component';
import { StatusBarComponent } from './status-bar/status-bar.component';
import { AdvancedComponent } from './advanced/advanced.component';
import { AdvancedIcoComponent } from './advanced/advanced-ico/advanced-ico.component';
import { AdvancedService } from '../wallet/advanced/advanced.service';
import { FeedbackComponent } from './advanced/feedback/feedback.component';
......@@ -29,7 +29,8 @@ import { FeedbackComponent } from './advanced/feedback/feedback.component';
SharedModule.forRoot(),
NgbModule,
ReactiveFormsModule,
WalletRoutingModule
WalletRoutingModule,
NgDatepickerModule
],
declarations: [
WalletComponent,
......@@ -39,7 +40,6 @@ import { FeedbackComponent } from './advanced/feedback/feedback.component';
SidebarComponent,
StatusBarComponent,
AdvancedComponent,
AdvancedIcoComponent,
FeedbackComponent
],
providers: [
......
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