From aca94eae04ebd0dc241d1fc8fa7073af5bb8fd24 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 8 Apr 2017 18:10:55 +0300 Subject: [PATCH] completed settings section --- react/src/actions/actionCreators.js | 252 +++++++++++++++++---- react/src/components/dashboard/settings.js | 114 ++++++++-- react/src/config.js | 2 + react/src/reducers/settings.js | 12 +- react/src/styles/index.scss | 8 + 5 files changed, 324 insertions(+), 64 deletions(-) diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index b9612e2..d499b01 100644 --- a/react/src/actions/actionCreators.js +++ b/react/src/actions/actionCreators.js @@ -1,4 +1,5 @@ import 'whatwg-fetch'; +import Config from '../config'; import { startCurrencyAssetChain, startAssetChain, startCrypto, checkCoinType } from '../components/addcoin/payload'; import { copyToClipboard } from '../util/copyToClipboard'; import { translate } from '../translate/translate'; @@ -17,6 +18,8 @@ export const DASHBOARD_ACTIVE_COIN_RECEIVE_FORM = 'DASHBOARD_ACTIVE_COIN_RECEIVE export const DASHBOARD_ACTIVE_COIN_RESET_FORMS = 'DASHBOARD_ACTIVE_COIN_RESET_FORMS'; export const ATOMIC = 'ATOMIC'; export const GET_WIF_KEY = 'GET_WIF_KEY'; +export const GET_PEERS_LIST = 'GET_PEERS_LIST'; +export const GET_DEBUG_LOG = 'GET_DEBUG_LOG'; function atomicState(json) { return { @@ -178,11 +181,11 @@ export function copyCoinAddress(address) { if (_result) { return dispatch => { - dispatch(triggerToaster(true, translate('DASHBOARD.ADDR_COPIED'), translate('TOASTR.COIN_NOTIFICATION'), 'success')) + dispatch(triggerToaster(true, translate('DASHBOARD.ADDR_COPIED'), translate('TOASTR.COIN_NOTIFICATION'), 'success')); } } else { return dispatch => { - dispatch(triggerToaster(true, 'Couldn\'t copy address to clipboard', translate('TOASTR.COIN_NOTIFICATION'), 'error')) + dispatch(triggerToaster(true, 'Couldn\'t copy address to clipboard', translate('TOASTR.COIN_NOTIFICATION'), 'error')); } } } @@ -223,13 +226,13 @@ export function addCoin(coin, mode) { export function iguanaAddCoin(coin, mode, acData) { return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify(acData), }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, translate('TOASTR.FAILED_TO_ADDCOIN'), translate('TOASTR.ACCOUNT_NOTIFICATION'), 'error')) + dispatch(triggerToaster(true, translate('TOASTR.FAILED_TO_ADDCOIN'), translate('TOASTR.ACCOUNT_NOTIFICATION'), 'error')); }) .then(response => response.json()) .then(json => dispatch(addCoinResult(coin, mode, acData))); @@ -272,7 +275,7 @@ export function shepherdHerd(coin, mode, path) { console.log('herdData', herdData); return dispatch => { - return fetch('http://127.0.0.1:17777/shepherd/herd', { + return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/herd', { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -284,7 +287,7 @@ export function shepherdHerd(coin, mode, path) { }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, translate('FAILED_SHEPHERD_HERD'), translate('TOASTR.SERVICE_NOTIFICATION'), 'error')) + dispatch(triggerToaster(true, translate('FAILED_SHEPHERD_HERD'), translate('TOASTR.SERVICE_NOTIFICATION'), 'error')); }) .then(response => response.json()) .then(json => dispatch(iguanaAddCoin(coin, mode, acData))); @@ -307,7 +310,7 @@ export function addCoinResult(coin, mode) { export function shepherdGetConfig(coin, mode) { return dispatch => { - return fetch('http://127.0.0.1:17777/shepherd/getconf', { + return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/getconf', { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -316,7 +319,7 @@ export function shepherdGetConfig(coin, mode) { }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, 'Failed to get mode config', 'Error', 'error')) + dispatch(triggerToaster(true, 'Failed to get mode config', 'Error', 'error')); }) .then(response => response.json()) .then(json => dispatch(shepherdHerd(coin, mode, json))); @@ -325,7 +328,7 @@ export function shepherdGetConfig(coin, mode) { export function getDexCoins() { return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', //mode: 'no-cors' body: JSON.stringify({ @@ -336,7 +339,7 @@ export function getDexCoins() { }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, 'Error getDexCoins', 'Error', 'error')) + dispatch(triggerToaster(true, 'Error getDexCoins', 'Error', 'error')); }) .then(response => response.json()) @@ -355,7 +358,7 @@ function rpcErrorHandler(json, dispatch) { export function iguanaWalletPassphrase(_passphrase) { return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify({ 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), @@ -368,7 +371,7 @@ export function iguanaWalletPassphrase(_passphrase) { }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, 'Error iguanaWalletPassphrase', 'Error', 'error')) + dispatch(triggerToaster(true, 'Error iguanaWalletPassphrase', 'Error', 'error')); }) .then(response => response.json()) .then(json => dispatch(iguanaWalletPassphraseState(json, dispatch))); @@ -377,7 +380,7 @@ export function iguanaWalletPassphrase(_passphrase) { export function iguanaActiveHandle(getMainAddress) { return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify({ 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), @@ -387,7 +390,7 @@ export function iguanaActiveHandle(getMainAddress) { }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, 'Error iguanaActiveHandle', 'Error', 'error')) + dispatch(triggerToaster(true, 'Error iguanaActiveHandle', 'Error', 'error')); }) .then(response => response.json()) .then(json => dispatch(getMainAddress ? getMainAddressState(json) : iguanaActiveHandleState(json))); @@ -396,7 +399,7 @@ export function iguanaActiveHandle(getMainAddress) { export function iguanaEdexBalance(coin) { return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify({ 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), @@ -407,7 +410,7 @@ export function iguanaEdexBalance(coin) { }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, 'Error iguanaEdexBalance', 'Error', 'error')) + dispatch(triggerToaster(true, 'Error iguanaEdexBalance', 'Error', 'error')); }) .then(response => response.json()) .then(json => dispatch(iguanaEdexBalanceState(json))); @@ -416,13 +419,13 @@ export function iguanaEdexBalance(coin) { export function atomic(payload) { return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify(payload), }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, payload.method, 'Atomic explore error', 'error')) + dispatch(triggerToaster(true, payload.method, 'Atomic explore error', 'error')); }) .then(response => response.json()) .then(json => dispatch(atomicState(json))); @@ -435,25 +438,24 @@ export function settingsWifkeyState(json, coin) { wifkey: json[coin + 'wif'], address: json[coin], } - console.log('test', json); } export function encryptWallet(_passphrase, cb, coin) { const payload = { - 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), - 'agent': 'bitcoinrpc', - 'method': 'encryptwallet', - 'passphrase': _passphrase + 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), + 'agent': 'bitcoinrpc', + 'method': 'encryptwallet', + 'passphrase': _passphrase }; return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify(payload), }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, 'encryptWallet', 'Error', 'error')) + dispatch(triggerToaster(true, 'encryptWallet', 'Error', 'error')); }) .then(dispatch(walletPassphrase(_passphrase))) .then(response => response.json()) @@ -463,39 +465,203 @@ export function encryptWallet(_passphrase, cb, coin) { export function walletPassphrase(_passphrase) { const payload = { - 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), - 'agent': 'bitcoinrpc', - 'method': 'walletpassphrase', - 'password': _passphrase, - 'timeout': '2592000' + 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), + 'agent': 'bitcoinrpc', + 'method': 'walletpassphrase', + 'password': _passphrase, + 'timeout': '2592000' }; return dispatch => { - return fetch('http://127.0.0.1:7778', { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', body: JSON.stringify(payload), }) .catch(function(error) { console.log(error); - dispatch(triggerToaster(true, 'walletPassphrase', 'Error', 'error')) + dispatch(triggerToaster(true, 'walletPassphrase', 'Error', 'error')); }) } } -/*function Shepherd_SysInfo() { - return new Promise((resolve) => { - $.ajax({ - type: 'GET', - url: 'http://127.0.0.1:17777/shepherd/sysinfo', - contentType: 'application/json' // send as JSON +export function getPeersListState(json) { + var peersList = {}; + if (json && json.rawpeers && json.rawpeers.length) { + for (var i=0; i < json.rawpeers.length; i++) { + peersList[json.rawpeers[i].coin] = json.rawpeers[i].peers; + } + } + return { + type: GET_PEERS_LIST, + supernetPeers: json && json.supernet[0] ? json.supernet : null, + rawPeers: peersList, + } +} + +export function getPeersList(coin) { + const payload = { + 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), + 'agent': 'SuperNET', + 'method': 'getpeers', + 'activecoin': coin, + }; + + return dispatch => { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + method: 'POST', + body: JSON.stringify(payload), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getPeersList', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => dispatch(getPeersListState(json, dispatch))) + } +} + +function addPeerNodeState(json, dispatch) { + if (json.error === 'addnode needs active coin, do an addcoin first') { + return dispatch => { + dispatch(triggerToaster(true, 'Addnode needs active coin', translate('TOASTR.SETTINGS_NOTIFICATION'), 'error')); + } + } + if (json.result === 'peer was already connected') { + return dispatch => { + dispatch(triggerToaster(true, 'Peer was already connected', translate('TOASTR.SETTINGS_NOTIFICATION'), 'warning')); + } + } + if (json.result === 'addnode connection was already pending') { + return dispatch => { + dispatch(triggerToaster(true, 'Addnode connection was already pending', translate('TOASTR.SETTINGS_NOTIFICATION'), 'warning')); + } + } + if (json.result === 'addnode submitted') { + return dispatch => { + dispatch(triggerToaster(true, 'Peer is added', translate('TOASTR.SETTINGS_NOTIFICATION'), 'success')); + } + } +} + +export function addPeerNode(coin, ip) { + const payload = { + 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), + 'agent': 'iguana', + 'method': 'addnode', + 'activecoin': coin, + 'ipaddr': ip + }; + + return dispatch => { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + method: 'POST', + body: JSON.stringify(payload), }) - .done(function(data) { - resolve(data); - }); - }); + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'addPeerNode', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => dispatch(addPeerNodeState(json, dispatch))) + } +} + +function getDebugLogState(json) { + const _data = json.result.replace('\n', '\r\n'); + + return { + type: GET_DEBUG_LOG, + data: _data, + } +} + +export function getDebugLog(target, linesCount) { + const payload = { + 'herdname': target, + 'lastLines': linesCount + }; + + return dispatch => { + return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/debuglog', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(payload), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'getDebugLog', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => dispatch(getDebugLogState(json))) + } +} + +function parseImportPrivKeyResponse(json, dispatch) { + if (json.error === 'illegal privkey') { + return dispatch => { + dispatch(triggerToaster(true, 'Illegal privkey', translate('TOASTR.SETTINGS_NOTIFICATION'), 'error')); + } + } + if (json.error === 'privkey already in wallet') { + return dispatch => { + dispatch(triggerToaster(true, 'Privkey already in wallet', translate('TOASTR.SETTINGS_NOTIFICATION'), 'warning')); + } + } + if (json && json.result !== undefined && json.result == 'success') { + return dispatch => { + dispatch(triggerToaster(true, translate('TOASTR.PRIV_KEY_IMPORTED'), translate('TOASTR.SETTINGS_NOTIFICATION'), 'success')); + } + } +} + +export function importPrivKey(wifKey) { + const payload = { + 'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'), + 'method': 'importprivkey', + 'params': [ + wifKey, + 'imported' + ] + }; + + return dispatch => { + return fetch('http://127.0.0.1:' + Config.iguanaCorePort, { + method: 'POST', + body: JSON.stringify(payload), + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'importPrivKey', 'Error', 'error')); + }) + .then(response => response.json()) + .then(json => dispatch(parseImportPrivKeyResponse(json, dispatch))) + .catch(function(ex) { + dispatch(parseImportPrivKeyResponse({ 'error': 'privkey already in wallet' }, dispatch)); + console.log('parsing failed', ex); + }) + } +} + +export function shepherdGetSysInfo() { + return dispatch => { + return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/sysinfo', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + } + }) + .catch(function(error) { + console.log(error); + dispatch(triggerToaster(true, 'Failed to get sys info', 'Error', 'error')) + }) + .then(response => response.json()) + .then(json => dispatch(shepherdHerd(coin, mode, json))); + } } -function Shepherd_SendPendValue() { +/*function Shepherd_SendPendValue() { Shepherd_SysInfo().then(function(result){ var ram_data = formatBytes(result.totalmem_bytes) var pend_val = null; diff --git a/react/src/components/dashboard/settings.js b/react/src/components/dashboard/settings.js index e5aa5ae..6f02e21 100644 --- a/react/src/components/dashboard/settings.js +++ b/react/src/components/dashboard/settings.js @@ -1,19 +1,41 @@ import React from 'react'; import { translate } from '../../translate/translate'; -import { iguanaActiveHandle, encryptWallet, settingsWifkeyState } from '../../actions/actionCreators'; +import { + iguanaActiveHandle, + encryptWallet, + settingsWifkeyState, + importPrivKey, + getDebugLog, + getPeersList, + addPeerNode +} from '../../actions/actionCreators'; import Store from '../../store'; import AddCoinOptionsCrypto from '../addcoin/addcoinOptionsCrypto'; import AddCoinOptionsAC from '../addcoin/addcoinOptionsAC'; import AddCoinOptionsACFiat from '../addcoin/addcoinOptionsACFiat'; +/* + TODO: + 1) pre-select active coin in add node tab + 2) add agama config section + 3) add fiat section +*/ class Settings extends React.Component { constructor(props) { super(props); this.state = { activeTab: 0, + debugLinesCount: 10, + debugTarget: 'iguana', }; this.exportWifKeys = this.exportWifKeys.bind(this); - this.updatePassphraseInput = this.updatePassphraseInput.bind(this); + this.updateInput = this.updateInput.bind(this); + this.importWifKey = this.importWifKey.bind(this); + this.readDebugLog = this.readDebugLog.bind(this); + this.checkNodes = this.checkNodes.bind(this); + this.addNode = this.addNode.bind(this); + this.renderPeersList = this.renderPeersList.bind(this); + this.renderSNPeersList = this.renderSNPeersList.bind(this); } componentDidMount() { @@ -30,7 +52,59 @@ class Settings extends React.Component { Store.dispatch(encryptWallet(this.state.wifkeysPassphrase, settingsWifkeyState, this.props.ActiveCoin.coin)); } - updatePassphraseInput(e) { + importWifKey() { + Store.dispatch(importPrivKey(this.state.importWifKey)); + } + + readDebugLog() { + Store.dispatch(getDebugLog(this.state.debugTarget, this.state.debugLinesCount)); + } + + checkNodes() { + if (this.state.getPeersCoin) { + Store.dispatch(getPeersList(this.state.getPeersCoin.split('|')[0])); + } + } + + addNode() { + if (this.state.addNodeCoin) { + Store.dispatch(addPeerNode(this.state.addNodeCoin.split('|')[0], this.state.addPeerIP)); + } + } + + renderPeersList() { + if (this.state.getPeersCoin) { + const coin = this.state.getPeersCoin.split('|')[0]; + + if (this.props.Settings.rawPeers && + this.state.getPeersCoin && + this.props.Settings.rawPeers[coin]) { + return this.props.Settings.rawPeers[coin].map((ip) =>
{ip}
); + } else { + return null; + } + } else { + return null; + } + } + + renderSNPeersList() { + if (this.state.getPeersCoin) { + const coin = this.state.getPeersCoin.split('|')[0]; + + if (this.props.Settings.supernetPeers && + this.state.getPeersCoin && + this.props.Settings.supernetPeers[coin]) { + return this.props.Settings.supernetPeers[coin].map((ip) =>
{ip}
); + } else { + return null; + } + } else { + return null; + } + } + + updateInput(e) { this.setState({ [e.target.name]: e.target.value, }); @@ -119,7 +193,7 @@ class Settings extends React.Component {
- @@ -128,17 +202,17 @@ class Settings extends React.Component {
- +
SuperNET Peers:
-

+

{this.renderSNPeersList()}

Raw Peers:
-

+

{this.renderPeersList()}

@@ -148,7 +222,7 @@ class Settings extends React.Component {
- @@ -156,11 +230,11 @@ class Settings extends React.Component {
- +
- +
@@ -207,7 +281,7 @@ class Settings extends React.Component {
- +
@@ -217,7 +291,7 @@ class Settings extends React.Component {
- +
{this.props.ActiveCoin.coin} @@ -256,11 +330,11 @@ class Settings extends React.Component {
- +
- +
@@ -284,26 +358,26 @@ class Settings extends React.Component {
- +
-
- +
-
+

- +
{this.props.Settings.debugLog}
-
+
diff --git a/react/src/config.js b/react/src/config.js index 7be35b6..bb2d029 100644 --- a/react/src/config.js +++ b/react/src/config.js @@ -1,2 +1,4 @@ module.exports = { + iguanaCorePort: 7778, + agamaPort: 17777 }; diff --git a/react/src/reducers/settings.js b/react/src/reducers/settings.js index f1ae464..d08740b 100644 --- a/react/src/reducers/settings.js +++ b/react/src/reducers/settings.js @@ -1,8 +1,9 @@ -import { GET_WIF_KEY } from '../actions/actionCreators'; +import { GET_WIF_KEY, GET_PEERS_LIST, GET_DEBUG_LOG } from '../actions/actionCreators'; export function Settings(state = { wifkey: null, address: null, + debugLog: null, }, action) { switch (action.type) { case GET_WIF_KEY: @@ -10,6 +11,15 @@ export function Settings(state = { wifkey: action.wifkey, address: action.address, }); + case GET_PEERS_LIST: + return Object.assign({}, state, { + supernetPeers: action.supernetPeers, + rawPeers: action.rawPeers, + }); + case GET_DEBUG_LOG: + return Object.assign({}, state, { + debugLog: action.data, + }); default: return state; } diff --git a/react/src/styles/index.scss b/react/src/styles/index.scss index 1c96cc3..dc16e93 100644 --- a/react/src/styles/index.scss +++ b/react/src/styles/index.scss @@ -68,6 +68,14 @@ body { content: '\F278'; } +#section-dashboard { + height: 100%; +} + +#section-iguana-wallet-settings { + background: #f3f4f5; +} + /*.toaster .single-toast:nth-child(0) { bottom: 12px; }