mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Wallet management/Settings improvements (#130)
* New Branch Splits settings out into their own areas for performance reasons * Formatting * Adds cutout logo for navbar * Better settings loading screen Better cache handling * Adds snackbar support Adds error websocketmessage support * pushing from one pc to another * Rejoins settings after failure to be able to seperate them without big rewrites * Wallet manipulation in settings * Reformats wallet page Updates menu to be 'wallets' * Lists enabled exchanges in settings before you click for modal * Fixes currency list issue * Fixes object reference bug in exchange-grid.component.html * password text
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { HomeComponent } from './pages/home/home.component';
|
||||
import { SettingsComponent } from './pages/settings/settings.component';
|
||||
import { AboutComponent } from './pages/about/about.component';
|
||||
import { DashboardComponent } from './pages/dashboard/dashboard.component';
|
||||
import { WalletComponent } from './pages/wallet/wallet.component';
|
||||
@@ -9,6 +8,9 @@ import { TradingComponent } from './pages/trading/trading.component';
|
||||
import { ExchangeGridComponent } from './pages/exchange-grid/exchange-grid.component';
|
||||
import { CurrencyListComponent } from './pages/currency-list/currency-list.component';
|
||||
|
||||
//Settings
|
||||
import { SettingsComponent } from './pages/settings/settings.component';
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
@@ -25,10 +27,6 @@ const routes: Routes = [
|
||||
path:'dashboard',
|
||||
component: DashboardComponent
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
},
|
||||
{
|
||||
path: 'wallet',
|
||||
component: WalletComponent
|
||||
@@ -57,8 +55,12 @@ const routes: Routes = [
|
||||
{
|
||||
path: 'help',
|
||||
component: CurrencyListComponent
|
||||
}
|
||||
|
||||
},
|
||||
//Settings
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsComponent
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</mat-list-item>
|
||||
<mat-list-item routerLink="wallet" routerLinkActive="wallet-highlight">
|
||||
<mat-icon>account_balance_wallet</mat-icon>
|
||||
<h3>Wallet</h3>
|
||||
<h3>Wallets</h3>
|
||||
</mat-list-item>
|
||||
<mat-list-item routerLink="trading" routerLinkActive="trading-highlight">
|
||||
<mat-icon>swap_horiz</mat-icon>
|
||||
@@ -58,11 +58,11 @@
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-list-item *ngIf="isConnected" matTooltip="Online!">
|
||||
<mat-icon>network_wifi</mat-icon>
|
||||
</mat-list-item>
|
||||
<mat-list-item *ngIf="!isConnected" matTooltip="Offline">
|
||||
<mat-icon>signal_wifi_off</mat-icon>
|
||||
</mat-list-item>
|
||||
<mat-icon>network_wifi</mat-icon>
|
||||
</mat-list-item>
|
||||
<mat-list-item *ngIf="!isConnected" matTooltip="Offline">
|
||||
<mat-icon>signal_wifi_off</mat-icon>
|
||||
</mat-list-item>
|
||||
</mat-nav-list>
|
||||
|
||||
</mat-sidenav>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.container {
|
||||
height: 100vh;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,16 +27,20 @@ import {
|
||||
MatLineModule,
|
||||
MatTooltipModule,
|
||||
MatTabsModule,
|
||||
MatSnackBarModule,
|
||||
MatDialogModule,
|
||||
} from '@angular/material';
|
||||
|
||||
|
||||
//Pages
|
||||
import { AppComponent } from './app.component';
|
||||
import { HomeComponent } from './pages/home/home.component';
|
||||
import { AboutComponent } from './pages/about/about.component';
|
||||
import { SettingsComponent } from './pages/settings/settings.component';
|
||||
import { DashboardComponent } from './pages/dashboard/dashboard.component';
|
||||
import { WalletComponent } from './pages/wallet/wallet.component';
|
||||
import { DonateComponent } from './pages/donate/donate.component';
|
||||
import { HelpComponent } from './pages/help/help.component';
|
||||
|
||||
import { SettingsComponent, EnabledCurrenciesDialogueComponent } from './pages/settings/settings.component';
|
||||
|
||||
//Shared
|
||||
import { NavbarComponent } from './shared/navbar/navbar.component';
|
||||
@@ -70,7 +74,6 @@ import { BuyFormComponent } from './shared/buy-form/buy-form.component';
|
||||
import { ExchangeGridComponent } from './pages/exchange-grid/exchange-grid.component';
|
||||
import { CurrencyListComponent } from './pages/currency-list/currency-list.component';
|
||||
import { SellFormComponent } from './shared/sell-form/sell-form.component';
|
||||
import { HelpComponent } from './pages/help/help.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@@ -99,7 +102,11 @@ import { HelpComponent } from './pages/help/help.component';
|
||||
SellFormComponent,
|
||||
HelpComponent,
|
||||
IterateMapPipe,
|
||||
EnabledCurrenciesPipe
|
||||
EnabledCurrenciesPipe,
|
||||
EnabledCurrenciesDialogueComponent
|
||||
],
|
||||
entryComponents: [
|
||||
EnabledCurrenciesDialogueComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@@ -124,6 +131,8 @@ import { HelpComponent } from './pages/help/help.component';
|
||||
MatLineModule,
|
||||
MatTooltipModule,
|
||||
MatTabsModule,
|
||||
MatSnackBarModule,
|
||||
MatDialogModule,
|
||||
AmChartsModule,
|
||||
],
|
||||
providers: [
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<h2>Currency List</h2>
|
||||
<h3>Select and monitor currencies of the same type</h3>
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel *ngFor="let currency of exchangeCurrencies | iterateMap">
|
||||
<mat-expansion-panel-header [ngClass]="{'selected' : selectedCurrency == currency.value}" >
|
||||
@@ -13,7 +15,7 @@
|
||||
</div>
|
||||
<form class="form-content">
|
||||
<mat-list>
|
||||
<mat-list-item [ngClass]="{'selected' : selectedExchange == exchange}" *ngFor="let exchange of currency.key" >
|
||||
<mat-list-item [ngClass]="{'selected' : (selectedExchange == exchange && selectedCurrency == currency.value)}" *ngFor="let exchange of currency.key" >
|
||||
<h4 matLine>{{exchange}}</h4>
|
||||
<button mat-button (click)="selectCurrency(exchange, currency.value)">SELECT</button>
|
||||
</mat-list-item>
|
||||
|
||||
@@ -58,7 +58,6 @@ export class CurrencyListComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.exchangeCurrencies.forEach((value: string[], key: string) => {});
|
||||
}
|
||||
|
||||
private getSettings(): void {
|
||||
@@ -69,5 +68,4 @@ export class CurrencyListComponent implements OnInit {
|
||||
this.ws.messages.next(WebSocketMessage.GetSettingsMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<h2>Exchange List</h2>
|
||||
<h3>Select and monitor currencies from the same exchange</h3>
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel *ngFor="let exchange of exchangeCurrencies | iterateMap">
|
||||
<mat-expansion-panel-header [ngClass]="{'selected' : selectedExchange == exchange.value}">
|
||||
<mat-expansion-panel-header [ngClass]="{'selected' : selectedExchange == exchange.key}">
|
||||
<mat-panel-title>
|
||||
{{exchange.value}}
|
||||
{{exchange.value}}
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
image and blurb
|
||||
<div>
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
<form class="form-content">
|
||||
<mat-list>
|
||||
<mat-list-item [ngClass]="{'selected' : selectedCurrency == currency.ParsedName}" *ngFor="let currency of exchange.key | enabledCurrencies" >
|
||||
<mat-list-item [ngClass]="{'selected' : selectedCurrency == currency.ParsedName && selectedExchange == exchange.value }" *ngFor="let currency of exchange.key | enabledCurrencies" >
|
||||
<h4 matLine>{{currency.ParsedName}}</h4>
|
||||
<button mat-button (click)="selectCurrency(exchange.value,currency.ParsedName)">SELECT</button>
|
||||
</mat-list-item>
|
||||
|
||||
@@ -1,19 +1,42 @@
|
||||
<div class="loading-spinner" *ngIf="settings === null">
|
||||
<mat-progress-spinner color="accent" mode="indeterminate"></mat-progress-spinner>
|
||||
</div>
|
||||
<div *ngIf="settings !== null">
|
||||
|
||||
<div *ngIf="settings !== null && ready">
|
||||
<button matTooltip="Save" (click)="saveSettings()" mat-fab color="accent" class="mat-fab mat-fab-bottom-right"><mat-icon >save</mat-icon></button>
|
||||
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel *ngIf="settings.SMSGlobal != null">
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
SMS Global
|
||||
Credentials
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
SMS configuration and contact management
|
||||
<mat-icon>phone_iphone</mat-icon>
|
||||
User Settings
|
||||
<mat-icon>person</mat-icon>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
<form class="form-content">
|
||||
<mat-form-field>
|
||||
<input matInput name="username" [(ngModel)]="settings.Webserver.AdminUsername" placeholder="Username">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput name="password" type="password" [(ngModel)]="settings.Webserver.AdminPassword" placeholder="Password">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input type="number" matInput name="connection-limit" [(ngModel)]="settings.Webserver.WebsocketConnectionLimit" placeholder="Websocket connection limit">
|
||||
</mat-form-field>
|
||||
<mat-checkbox name="allow-insecure-origin" [(ngModel)]="settings.Webserver.WebsocketAllowInsecureOrigin">Allow Insecure Websocket Origin</mat-checkbox>
|
||||
|
||||
</form>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
SMS Notifications
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Notification Settings
|
||||
<mat-icon>sms</mat-icon>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
<form class="form-content">
|
||||
@@ -23,9 +46,9 @@
|
||||
<input matInput name="smsUsername" [(ngModel)]="settings.SMSGlobal.Username" [disabled]="!settings?.SMSGlobal.Enabled" placeholder="Username">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput name="smsPassword" [(ngModel)]="settings.SMSGlobal.Password" [disabled]="!settings?.SMSGlobal.Enabled" placeholder="Password">
|
||||
<input matInput name="smsPassword" type="password" [(ngModel)]="settings.SMSGlobal.Password" [disabled]="!settings?.SMSGlobal.Enabled" placeholder="Password">
|
||||
</mat-form-field>
|
||||
|
||||
|
||||
<div *ngFor="let contact of settings.SMSGlobal?.Contacts">
|
||||
<mat-checkbox name="contactEnabled" [disabled]="!settings?.SMSGlobal.Enabled" [(ngModel)]="contact.Enabled">Enabled</mat-checkbox>
|
||||
<div mat-line></div>
|
||||
@@ -37,9 +60,39 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
<mat-action-row>
|
||||
<button mat-button>ADD</button>
|
||||
</mat-action-row>
|
||||
</mat-expansion-panel>
|
||||
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Wallets
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Wallet Address Settings
|
||||
<mat-icon>account_balance_wallet</mat-icon>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngFor="let wallet of settings.PortfolioAddresses?.Addresses">
|
||||
<mat-form-field class="long">
|
||||
<input matInput name="wallet-address" [(ngModel)]="wallet.Address" placeholder="Address" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput name="wallet-cointype" [(ngModel)]="wallet.CoinType" placeholder="Coin Type" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput name="wallet-description" [(ngModel)]="wallet.Description" placeholder="Description" />
|
||||
</mat-form-field>
|
||||
<button mat-button (click)="removeWallet(wallet)">REMOVE</button>
|
||||
</div>
|
||||
<mat-action-row>
|
||||
<button mat-button (click)="addWallet()">ADD</button>
|
||||
</mat-action-row>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel *ngFor="let exchange of settings?.Exchanges">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
@@ -47,7 +100,7 @@
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Exchange Settings
|
||||
<mat-icon>attach_money</mat-icon>
|
||||
<mat-icon>poll</mat-icon>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
<form class="form-content">
|
||||
@@ -57,7 +110,7 @@
|
||||
<input matInput name="apiKey" [(ngModel)]="exchange.APIKey" [disabled]="!exchange.Enabled" placeholder="API Key*">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput name="apiSecretKey" [(ngModel)]="exchange.APISecret" [disabled]="!exchange.Enabled" placeholder="API Secret Key*">
|
||||
<input matInput name="apiSecretKey" type="password" [(ngModel)]="exchange.APISecret" [disabled]="!exchange.Enabled" placeholder="API Secret Key*">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput name="apiClientId" [(ngModel)]="exchange.ClientID" [disabled]="!exchange.Enabled" placeholder="API ClientID">
|
||||
@@ -66,12 +119,10 @@
|
||||
<h4>
|
||||
Enabled currencies
|
||||
</h4>
|
||||
<div *ngFor="let currency of exchange.Pairs">
|
||||
<p>{{currency.Name}}</p>
|
||||
<mat-checkbox name="{{currency.Name}}2" [(ngModel)]="currency.Enabled"></mat-checkbox>
|
||||
</div>
|
||||
<p ><span *ngFor="let pair of exchange.Pairs | enabledCurrencies; let isLast=last">{{pair.Name}}{{isLast ? '' : ', '}}</span> </p>
|
||||
<button mat-button [disabled]="!exchange.Enabled" (click)="openModal(exchange.Pairs)">CHANGE</button>
|
||||
</form>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
</mat-accordion>
|
||||
</div>
|
||||
@@ -9,4 +9,17 @@
|
||||
|
||||
.form-content {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mat-card {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.long {
|
||||
width:450px;
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
|
||||
import { WebsocketResponseHandlerService } from './../../services/websocket-response-handler/websocket-response-handler.service';
|
||||
import { WebSocketMessageType, WebSocketMessage } from './../../shared/classes/websocket';
|
||||
import { Config, CurrencyPairRedux } from './../../shared/classes/config';
|
||||
import { Config, CurrencyPairRedux, Wallet } from './../../shared/classes/config';
|
||||
import { MatSnackBar, MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';
|
||||
import { WalletComponent } from '../wallet/wallet.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
@@ -9,36 +11,68 @@ import { Config, CurrencyPairRedux } from './../../shared/classes/config';
|
||||
styleUrls: ['./settings.component.scss'],
|
||||
})
|
||||
|
||||
export class SettingsComponent implements OnInit {
|
||||
export class SettingsComponent {
|
||||
public settings: Config = new Config();
|
||||
private ws: WebsocketResponseHandlerService;
|
||||
public ready: boolean = false;
|
||||
private snackBar: MatSnackBar;
|
||||
private dialogue;
|
||||
|
||||
constructor(private websocketHandler: WebsocketResponseHandlerService) {
|
||||
constructor(private websocketHandler: WebsocketResponseHandlerService, snackBar: MatSnackBar, public dialog: MatDialog) {
|
||||
this.ws = websocketHandler;
|
||||
|
||||
this.snackBar = snackBar;
|
||||
}
|
||||
ngOnInit() {
|
||||
this.ws.shared.subscribe(msg => {
|
||||
if (msg.event === WebSocketMessageType.GetConfig) {
|
||||
this.settings.setConfig(msg.data);
|
||||
this.ready = true;
|
||||
} else if (msg.event === WebSocketMessageType.SaveConfig) {
|
||||
// check if err is returned, then display some notification
|
||||
if(msg.error !== null || msg.error.length > 0) {
|
||||
this.snackBar.open(msg.error, '', {
|
||||
duration: 4000,
|
||||
});
|
||||
}
|
||||
if (msg.error === null || msg.error === '') {
|
||||
this.settings.clearCache();
|
||||
this.getSettings();
|
||||
this.snackBar.open('Success', msg.data, {
|
||||
duration: 1000,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
this.getSettings();
|
||||
}
|
||||
|
||||
public addWallet() :void {
|
||||
this.settings.PortfolioAddresses.Addresses.push(<Wallet>{});
|
||||
}
|
||||
|
||||
public removeWallet(wallet:any) {
|
||||
this.settings.PortfolioAddresses.Addresses.splice(this.settings.PortfolioAddresses.Addresses.indexOf(wallet), 1);
|
||||
}
|
||||
|
||||
|
||||
public openModal(pairs: any): void {
|
||||
let dialogRef = this.dialog.open(EnabledCurrenciesDialogueComponent, {
|
||||
width: '20%',
|
||||
height: '40%',
|
||||
data: { pairs: pairs }
|
||||
});
|
||||
}
|
||||
|
||||
private getSettings(): void {
|
||||
if(this.settings.isConfigCacheValid()) {
|
||||
this.settings.setConfig(JSON.parse(window.localStorage['config']))
|
||||
this.ready = true;
|
||||
} else {
|
||||
this.settings.clearCache();
|
||||
this.ws.messages.next(WebSocketMessage.GetSettingsMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private saveSettings(): void {
|
||||
|
||||
this.settings.fromReduxToArray()
|
||||
var settingsSave = {
|
||||
Event: 'SaveConfig',
|
||||
@@ -48,3 +82,25 @@ export class SettingsComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'dialog-overview-example-dialog',
|
||||
template: '<h4>Enabled Currencies</h4><div *ngFor="let currency of data.pairs"><mat-checkbox name="{{currency.Name}}2" [(ngModel)]="currency.Enabled">{{currency.Name}}</mat-checkbox></div><button mat-raised-button color="primary" (click)="close()">DONE</button>',
|
||||
})
|
||||
export class EnabledCurrenciesDialogueComponent {
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<EnabledCurrenciesDialogueComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) { }
|
||||
|
||||
onNoClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this.dialogRef.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,114 +1,84 @@
|
||||
<div class="loading-spinner" *ngIf="wallet === null">
|
||||
<mat-progress-spinner color="accent" mode="indeterminate"></mat-progress-spinner>
|
||||
<mat-progress-spinner color="accent" mode="indeterminate"></mat-progress-spinner>
|
||||
</div>
|
||||
<mat-accordion *ngIf="wallet !== null">
|
||||
<mat-expansion-panel [expanded]="true">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Coin Totals
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<mat-list>
|
||||
<div *ngIf="wallet !== null">
|
||||
<button matTooltip="Recalculate" (click)="setWallet()" mat-fab color="accent" class="mat-fab mat-fab-bottom-right">
|
||||
<mat-icon>dialpad</mat-icon>
|
||||
</button>
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<h4>Coin Totals</h4>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.coin_totals">
|
||||
<i [ngClass]="coin.icon"></i>
|
||||
<h4 mat-line>{{coin.coin}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}</h4>
|
||||
<h4 mat-line><i [ngClass]="coin.icon"></i> {{coin.coin}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</mat-expansion-panel>
|
||||
</mat-list>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Online Summary
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<mat-list>
|
||||
<mat-divider></mat-divider>
|
||||
<h4>Offline Coins</h4>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.coins_offline">
|
||||
<h4 mat-line><i [ngClass]="coin.icon"></i> {{coin.coin}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
<mat-divider></mat-divider>
|
||||
<h4>Offline Summary</h4>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.offline_summary.BTC">
|
||||
<i class="cc btc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *ngFor="let coin of wallet?.offline_summary.LTC">
|
||||
<i class="cc ltc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *ngFor="let coin of wallet?.offline_summary.ETH">
|
||||
<i class="cc eth"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
<h4>Online Coins</h4>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.coins_online">
|
||||
<i [ngClass]="coin.icon"></i>
|
||||
<h4 mat-line>{{coin.coin}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
<mat-divider></mat-divider>
|
||||
<h4> Online Summary</h4>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.online_summary.BTC">
|
||||
<i class="cc btc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
<i class="cc btc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item *ngFor="let coin of wallet?.online_summary.LTC">
|
||||
<i class="cc ltc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
<i class="cc ltc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item *ngFor="let coin of wallet?.online_summary.ETH">
|
||||
<i class="cc eth"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
<i class="cc eth"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Offline Summary
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.offline_summary.BTC">
|
||||
<i class="cc btc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item *ngFor="let coin of wallet?.offline_summary.LTC">
|
||||
<i class="cc ltc"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item *ngFor="let coin of wallet?.offline_summary.ETH">
|
||||
<i class="cc eth"></i>
|
||||
<h4 mat-line>Address: {{coin.address}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}{{coin.coin}} - {{coin.percentage}}%</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Online Coins
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.coins_online">
|
||||
<i [ngClass]="coin.icon"></i>
|
||||
<h4 mat-line>{{coin.coin}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Offline Coins
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let coin of wallet?.coins_offline">
|
||||
<i [ngClass]="coin.icon"></i>
|
||||
<h4 mat-line>{{coin.coin}}</h4>
|
||||
<h4 mat-line>{{coin.balance}}</h4>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</mat-expansion-panel>
|
||||
|
||||
|
||||
|
||||
|
||||
</mat-accordion>
|
||||
</mat-list>
|
||||
|
||||
|
||||
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
.wallet-card {
|
||||
width: 80%;
|
||||
margin: 10px auto;
|
||||
}
|
||||
|
||||
.BTC {
|
||||
color:orange;
|
||||
@@ -11,4 +7,24 @@
|
||||
}
|
||||
.ETH {
|
||||
color:darkslategrey;
|
||||
}
|
||||
}
|
||||
// FAB
|
||||
.mat-fab {
|
||||
top: auto;
|
||||
right: 30px;
|
||||
bottom: 20px;
|
||||
left: auto;
|
||||
position: fixed;
|
||||
z-index:9;
|
||||
}
|
||||
mat-grid-list {
|
||||
height: 90vh;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
width:90%;
|
||||
}
|
||||
|
||||
mat-grid-tile {
|
||||
box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.37);
|
||||
}
|
||||
@@ -28,6 +28,7 @@ export class WalletComponent implements OnInit {
|
||||
this.ws.shared.subscribe(msg => {
|
||||
if (msg.event === WebSocketMessageType.GetPortfolio) {
|
||||
this.wallet = <Wallet>msg.data;
|
||||
console.log(msg.data);
|
||||
this.attachIcon(this.wallet.coin_totals);
|
||||
this.attachIcon(this.wallet.coins_offline);
|
||||
this.attachIcon(this.wallet.coins_online);
|
||||
|
||||
@@ -10,14 +10,18 @@ const WEBSOCKET_URL = 'ws://localhost:9050/ws';
|
||||
export class WebsocketResponseHandlerService {
|
||||
public messages: Subject<any>;
|
||||
public shared: Observable<WebSocketMessage>;
|
||||
public isConnected :boolean = false;
|
||||
public isConnected: boolean = false;
|
||||
private ws: WebsocketService;
|
||||
|
||||
constructor(@Optional() @SkipSelf() parentModule: WebsocketResponseHandlerService, wsService: WebsocketService) {
|
||||
this.messages = <Subject<WebSocketMessage>>wsService
|
||||
this.ws = wsService;
|
||||
this.messages = <Subject<WebSocketMessage>>this.ws
|
||||
.connect(WEBSOCKET_URL)
|
||||
|
||||
.map((response: MessageEvent): WebSocketMessage => {
|
||||
this.isConnected = wsService.isConnected;
|
||||
var interval = setInterval(() => {
|
||||
this.isConnected = this.ws.isConnected;
|
||||
}, 2000);
|
||||
let websocketResponseMessage = JSON.parse(response.data);
|
||||
var websocketResponseData = websocketResponseMessage.Data === undefined ? websocketResponseMessage.data : websocketResponseMessage.Data;
|
||||
var websocketResponseEvent = websocketResponseMessage.Event === undefined ? websocketResponseMessage.event : websocketResponseMessage.Event;
|
||||
@@ -27,10 +31,11 @@ export class WebsocketResponseHandlerService {
|
||||
responseMessage.data = websocketResponseData;
|
||||
responseMessage.exchange = websocketResponseMessage.exchange;
|
||||
responseMessage.assetType = websocketResponseMessage.assetType;
|
||||
responseMessage.error = websocketResponseMessage.error;
|
||||
|
||||
return responseMessage;
|
||||
});
|
||||
this.isConnected = wsService.isConnected;
|
||||
this.isConnected = this.ws.isConnected;
|
||||
|
||||
this.shared = this.messages.share(); //multicast
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{{tickerCard.Exchange}} {{tickerCard.CurrencyPair}} Last: {{this.tickerCard.Last}}
|
||||
{{tickerCard.Exchange}} {{tickerCard.CurrencyPair}} Last: {{tickerCard.Last}}
|
||||
@@ -1,86 +1,56 @@
|
||||
import {Component, OnInit, OnDestroy }from '@angular/core';
|
||||
import {WebsocketResponseHandlerService }from './../../services/websocket-response-handler/websocket-response-handler.service';
|
||||
import {WebSocketMessageType }from './../../shared/classes/websocket';
|
||||
import { Component, OnInit, OnDestroy} from '@angular/core';
|
||||
import { WebsocketResponseHandlerService } from './../../services/websocket-response-handler/websocket-response-handler.service';
|
||||
import { WebSocketMessageType } from './../../shared/classes/websocket';
|
||||
import { ExchangeCurrency, TickerUpdate } from './../../shared/classes/ticker';
|
||||
|
||||
@Component( {
|
||||
selector:'app-all-updates-ticker',
|
||||
templateUrl:'./all-updates-ticker.component.html',
|
||||
styleUrls:['./all-updates-ticker.component.scss'],
|
||||
@Component({
|
||||
selector: 'app-all-updates-ticker',
|
||||
templateUrl: './all-updates-ticker.component.html',
|
||||
styleUrls: ['./all-updates-ticker.component.scss'],
|
||||
})
|
||||
export class AllEnabledCurrencyTickersComponent implements OnInit {
|
||||
allCurrencies:ExchangeCurrency[] = < ExchangeCurrency[] > []; ;
|
||||
private ws:WebsocketResponseHandlerService;
|
||||
tickerCard:TickerUpdate = new TickerUpdate();
|
||||
showTicker:boolean = true;
|
||||
message:string;
|
||||
allCurrencies: ExchangeCurrency[] = < ExchangeCurrency[] > [];;
|
||||
private ws: WebsocketResponseHandlerService;
|
||||
tickerCard: TickerUpdate = new TickerUpdate();
|
||||
|
||||
constructor(private websocketHandler: WebsocketResponseHandlerService) {
|
||||
this.tickerCard.Exchange = "Loading";
|
||||
this.tickerCard.CurrencyPair = "...";
|
||||
this.tickerCard.Last = -1;
|
||||
this.ws = websocketHandler;
|
||||
this.ws.shared.subscribe(msg => {
|
||||
this.tickerCard.Exchange = "Loading";
|
||||
this.tickerCard.CurrencyPair = "...";
|
||||
this.tickerCard.Last = -1;
|
||||
this.ws = websocketHandler;
|
||||
this.ws.shared.subscribe(msg => {
|
||||
if (msg.event === WebSocketMessageType.TickerUpdate) {
|
||||
if (window.localStorage["selectedExchange"] !== undefined &&
|
||||
window.localStorage["selectedCurrency"] !== undefined) {
|
||||
this.tickerCard.Exchange = window.localStorage["selectedExchange"];
|
||||
this.tickerCard.CurrencyPair = window.localStorage["selectedCurrency"];
|
||||
if (msg.exchange == window.localStorage["selectedExchange"]) {
|
||||
if (this.stripCurrencyCharacters(msg.data.CurrencyPair) == window.localStorage["selectedCurrency"]) {
|
||||
|
||||
this.updateTicker(msg)
|
||||
if (window.localStorage["selectedExchange"] !== undefined &&
|
||||
window.localStorage["selectedCurrency"] !== undefined) {
|
||||
|
||||
this.tickerCard.Exchange = window.localStorage["selectedExchange"];
|
||||
this.tickerCard.CurrencyPair = window.localStorage["selectedCurrency"];
|
||||
|
||||
if (msg.exchange == this.tickerCard.Exchange &&
|
||||
this.stripCurrencyCharacters(msg.data.CurrencyPair) == this.tickerCard.CurrencyPair) {
|
||||
this.updateTicker(msg)
|
||||
}
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
this.updateTicker(msg)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private updateTicker(msg:any):void {
|
||||
var modal = < ExchangeCurrency > {};
|
||||
modal.currencyPair = msg.data.CurrencyPair;
|
||||
modal.exchangeName = msg.exchange;
|
||||
var ticker = < TickerUpdate > msg.data;
|
||||
this.tickerCard = ticker;
|
||||
this.tickerCard.Exchange = msg.exchange;
|
||||
this.message = this.tickerCard.Exchange + " " + this.tickerCard.CurrencyPair + " Last: " + this.tickerCard.Last;
|
||||
private updateTicker(msg: any): void {
|
||||
var ticker = <TickerUpdate> msg.data;
|
||||
this.tickerCard = ticker;
|
||||
this.tickerCard.Exchange = msg.exchange;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
|
||||
private stripCurrencyCharacters(name:string):string {
|
||||
name = name.replace('_', '');
|
||||
name = name.replace('-', '');
|
||||
name = name.replace(' ', '');
|
||||
name = name.toLocaleUpperCase();
|
||||
return name;
|
||||
private stripCurrencyCharacters(name: string): string {
|
||||
name = name.replace('_', '');
|
||||
name = name.replace('-', '');
|
||||
name = name.replace(' ', '');
|
||||
name = name.toLocaleUpperCase();
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ExchangeCurrency {
|
||||
currencyPair:string;
|
||||
exchangeName:string;
|
||||
}
|
||||
|
||||
export interface CurrencyPair {
|
||||
delimiter:string;
|
||||
first_currency:string;
|
||||
second_currency:string;
|
||||
}
|
||||
|
||||
export class TickerUpdate {
|
||||
Pair:CurrencyPair;
|
||||
CurrencyPair:string;
|
||||
Last:number;
|
||||
High:number;
|
||||
Low:number;
|
||||
Bid:number;
|
||||
Ask:number;
|
||||
Volume:number;
|
||||
PriceATH:number;
|
||||
Exchange:string;
|
||||
}
|
||||
@@ -37,7 +37,25 @@
|
||||
this.PortfolioAddresses = configData.PortfolioAddresses
|
||||
this.SMSGlobal = configData.SMSGlobal
|
||||
this.Webserver = configData.Webserver
|
||||
this.fromArrayToRedux()
|
||||
if(configData.Exchanges.length > 0
|
||||
&& configData.Exchanges[0].Pairs
|
||||
&& configData.Exchanges[0].Pairs.length > 0) {
|
||||
console.log('Successfully retrieved well-formed pairs');
|
||||
return;
|
||||
}
|
||||
this.fromArrayToRedux();
|
||||
//Rewrite to cache on parsing to redux array
|
||||
this.saveToCache();
|
||||
}
|
||||
|
||||
public saveToCache() : void {
|
||||
window.localStorage['config'] = JSON.stringify(this);
|
||||
window.localStorage['configDate'] = new Date().toString();
|
||||
}
|
||||
|
||||
public clearCache() : void {
|
||||
window.localStorage['config'] = null;
|
||||
window.localStorage['configDate'] = null;
|
||||
}
|
||||
|
||||
public fromArrayToRedux() : void {
|
||||
@@ -57,8 +75,7 @@
|
||||
this.Exchanges[i].Pairs.push(currencyPair);
|
||||
}
|
||||
}
|
||||
window.localStorage['config'] = JSON.stringify(this);
|
||||
window.localStorage['configDate'] = new Date().toString();
|
||||
|
||||
}
|
||||
|
||||
public parseSettings() : void {
|
||||
@@ -82,23 +99,17 @@
|
||||
if (enabled.indexOf(this.Exchanges[i].Pairs[j].Name) == -1) {
|
||||
// Step 3 if its not in the enabled list, add it
|
||||
enabled.push(this.Exchanges[i].Pairs[j].Name);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (enabled.indexOf(this.Exchanges[i].Pairs[j].Name) > -1) {
|
||||
enabled.splice(enabled.indexOf(this.Exchanges[i].Pairs[j].Name), 1);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Step 4 JSONifiy the enabled list and set it to the this.settings.Exchanges[i].EnabledPairs
|
||||
this.Exchanges[i].EnabledPairs = enabled.join();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class CurrencyPairRedux {
|
||||
@@ -113,7 +124,15 @@ export class CurrencyPairRedux {
|
||||
}
|
||||
|
||||
export interface PortfolioAddresses {
|
||||
Addresses?: any;
|
||||
Addresses?: Wallet[];
|
||||
}
|
||||
|
||||
export interface Wallet {
|
||||
Address:string;
|
||||
CoinType:string;
|
||||
Balance:number;
|
||||
Description:string
|
||||
|
||||
}
|
||||
|
||||
export interface Contact {
|
||||
|
||||
24
web/src/app/shared/classes/ticker.ts
Normal file
24
web/src/app/shared/classes/ticker.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export interface ExchangeCurrency {
|
||||
currencyPair: string;
|
||||
exchangeName: string;
|
||||
}
|
||||
|
||||
export interface CurrencyPair {
|
||||
delimiter: string;
|
||||
first_currency: string;
|
||||
second_currency: string;
|
||||
}
|
||||
|
||||
export class TickerUpdate {
|
||||
Pair: CurrencyPair;
|
||||
CurrencyPair: string;
|
||||
Last: number;
|
||||
High: number;
|
||||
Low: number;
|
||||
Bid: number;
|
||||
Ask: number;
|
||||
Volume: number;
|
||||
PriceATH: number;
|
||||
Exchange: string;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ export class WebSocketMessage {
|
||||
public data: any;
|
||||
public exchange: string;
|
||||
public assetType: string;
|
||||
public error: string;
|
||||
|
||||
public static CreateAuthenticationMessage(): WebSocketMessage {
|
||||
var response = new WebSocketMessage();
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<nav class="docs-navbar">
|
||||
<mat-toolbar color="primary">
|
||||
<a (click)="sidebarService.toggle()" class="material-icons"></a>
|
||||
<a mat-button class="docs-button" routerLink="/" aria-label="Angular Material">
|
||||
<span>GoCryptoTrader</span>
|
||||
<a mat-button class="docs-button" style="width:1rem;" routerLink="/" aria-label="Angular Material">
|
||||
<span ><img style="width:100%; vertical-align:middle;" src="assets/images/gctlogo-small-cutoutt.png" /></span>
|
||||
</a>
|
||||
<app-selected-currency></app-selected-currency>
|
||||
<div class="flex-spacer"></div>
|
||||
|
||||
BIN
web/src/assets/images/gctlogo-small-cutoutt.png
Normal file
BIN
web/src/assets/images/gctlogo-small-cutoutt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
@@ -150,8 +150,12 @@ body {
|
||||
|
||||
|
||||
.mat-drawer-content {
|
||||
height:92% !important;
|
||||
height:84% !important;
|
||||
margin-top: 4rem !important;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
padding-bottom:2rem;
|
||||
padding-top:5px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user