Browse Source

Merge pull request #110 from pbca26/redux

Redux
all-modes
pbca26 8 years ago
committed by GitHub
parent
commit
e19f9e9eaa
  1. 67
      react/src/actions/actionCreators.js
  2. 39
      react/src/components/dashboard/appSettings.js
  3. 40
      react/src/components/dashboard/coinTileItem.js
  4. 165
      react/src/components/dashboard/sendCoin.js
  5. 41
      react/src/components/dashboard/settings.js
  6. 53
      react/src/components/dashboard/walletsBalance.js
  7. 82
      react/src/components/dashboard/walletsData.js
  8. 2
      react/src/components/dashboard/walletsNativeSend.js
  9. 13
      react/src/components/login/login.js
  10. 11
      react/src/reducers/activeCoin.js
  11. 4
      react/src/styles/index.scss
  12. 19
      react/src/util/cacheFormat.js

67
react/src/actions/actionCreators.js

@ -52,9 +52,17 @@ export const SYNC_ONLY_DATA = 'SYNC_ONLY_DATA';
export const LOAD_APP_CONFIG = 'LOAD_APP_CONFIG';
export const SAVE_APP_CONFIG = 'SAVE_APP_CONFIG';
export const SERVICE_ERROR = 'SERVICE_ERROR';
export const DASHBOARD_ACTIVE_ADDRESS = 'DASHBOARD_ACTIVE_ADDRESS';
var iguanaForks = {}; // forks in mem array
export function changeActiveAddress(address) {
return {
type: DASHBOARD_ACTIVE_ADDRESS,
address,
}
}
function updateErrosStack(method) {
return {
apiMethod: method,
@ -795,7 +803,7 @@ export function getBasiliskTransactionsList(coin, address) {
})
.then(response => response.json())
.then(function(json) {
if (json.result && json.result.indexOf('no file with handle') > -1) {
if (json.result && !json.result.basilisk && json.result.indexOf('no file with handle') > -1) {
console.log('new cache');
}
@ -1091,6 +1099,7 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
.then(response => response.json())
.then(function(json) {
json = json.result.basilisk;
if (json[coin].addresses) {
resolve({ 'result': json[coin].addresses });
}
@ -1254,8 +1263,8 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
json = json.result.basilisk;
// if listunspent is not in cache file retrieve new copy
// otherwise read from cache data
if (json[coin][currentAddress].listunspent) {
calcBalance(result, json[coin][currentAddress].listunspent.data, dispatch, mode);
if (json[coin][currentAddress].refresh) {
calcBalance(result, json[coin][currentAddress].refresh.data, dispatch, mode);
} else {
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.basiliskPort : Config.iguanaCorePort), {
method: 'POST',
@ -1267,7 +1276,7 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
})
.then(response => response.json())
.then(function(json) {
updatedCache.basilisk[coin][currentAddress].listunspent = {
updatedCache.basilisk[coin][currentAddress].refresh = {
'data': json,
'status': 'done',
'timestamp': Date.now(),
@ -1296,6 +1305,9 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
}
export function shepherdGroomPost(_filename, _payload) {
console.log('shepherdGroomPost to file ', _filename);
console.log('shepherdGroomPost payload ', _payload);
return dispatch => {
return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/groom/', {
method: 'POST',
@ -1316,13 +1328,37 @@ export function shepherdGroomPost(_filename, _payload) {
}
}
export function shepherdGroomPostPromise(_filename, _payload) {
console.log('shepherdGroomPostPromise to file ', _filename);
console.log('shepherdGroomPostPromise payload ', _payload);
return new Promise((resolve, reject) => {
fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/groom/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
'filename': _filename,
'payload': JSON.stringify(_payload),
}),
})
.catch(function(error) {
console.log(error);
dispatch(triggerToaster(true, 'shepherdGroomPostPromise', 'Error', 'error'));
})
.then(response => response.json())
.then(json => resolve(json))
})
}
export function fetchUtxoCache(_payload) {
const _userpass = '?userpass=tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
_pubkey = '&pubkey=' + _payload.pubkey,
_route = _payload.allcoins ? 'cache-all' : 'cache-one',
_coin = '&coin=' + _payload.coin,
_calls = '&calls=' + _payload.calls,
_address = '&address=' + _payload.address,
_address = _payload.address ? ('&address=' + _payload.address) : '',
_iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + Config.basiliskPort : '';
return dispatch => {
@ -1343,7 +1379,7 @@ export function fetchUtxoCache(_payload) {
function getShepherdCacheState(json, pubkey, coin) {
if (json.result && json.error && json.result.indexOf('no file with handle') > -1) {
console.log('new cache');
console.log('request new cache', true);
return dispatch => {
dispatch(fetchNewCacheData({
'pubkey': pubkey,
@ -1585,7 +1621,6 @@ export function getKMDBalanceTotal(coin) {
'asset': coin,
'function': 'z_gettotalbalance',
'hex': '3000',
'immediate': 60000,
'timeout': 60000
};
} else {
@ -1595,7 +1630,6 @@ export function getKMDBalanceTotal(coin) {
'method': 'passthru',
'function': 'z_gettotalbalance',
'hex': '3000',
'immediate': 60000,
'timeout': 60000
};
}
@ -1802,7 +1836,13 @@ export function sendNativeTx(coin, _payload) {
dispatch(triggerToaster(true, 'sendNativeTx', 'Error', 'error'));
})
.then(response => response.json())
.then(json => dispatch(triggerToaster(true, translate('TOASTR.TX_SENT_ALT'), translate('TOASTR.WALLET_NOTIFICATION'), 'success')))
.then(function(json) {
if (json.error && json.error.toString().indexOf('code:') > -1) {
dispatch(triggerToaster(true, 'Send failed', translate('TOASTR.WALLET_NOTIFICATION'), 'error'));
} else {
dispatch(triggerToaster(true, translate('TOASTR.TX_SENT_ALT'), translate('TOASTR.WALLET_NOTIFICATION'), 'success'));
}
})
.catch(function(ex) {
dispatch(triggerToaster(true, translate('TOASTR.TX_SENT_ALT'), translate('TOASTR.WALLET_NOTIFICATION'), 'success'));
console.log('parsing failed', ex);
@ -2138,11 +2178,11 @@ export function deleteCacheFile(_payload) {
}
}
export function getCacheFile() {
const _pubkey = JSON.parse(sessionStorage.getItem('IguanaActiveAccount')).pubkey;
export function getCacheFile(pubkey) {
const _pubkey = pubkey || JSON.parse(sessionStorage.getItem('IguanaActiveAccount')).pubkey;
return new Promise((resolve, reject) => {
fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/groom?pubkey=' + _pubkey, {
fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/groom?filename=' + _pubkey, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
@ -2164,10 +2204,11 @@ export function fetchNewCacheData(_payload) {
_route = _payload.allcoins ? 'cache-all' : 'cache-one',
_coin = '&coin=' + _payload.coin,
_calls = '&calls=' + _payload.calls,
_address = _payload.address ? ('&address=' + _payload.address) : '',
_iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + Config.basiliskPort : '';
return dispatch => {
return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/' + _route + _userpass + _pubkey + _coin + _calls + _iguanaInstancePort, {
return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/' + _route + _userpass + _pubkey + _coin + _calls + _address + _iguanaInstancePort, {
method: 'GET',
headers: {
'Content-Type': 'application/json',

39
react/src/components/dashboard/appSettings.js

@ -0,0 +1,39 @@
import React from 'react';
import { translate } from '../../translate/translate';
import {
} from '../../actions/actionCreators';
import Store from '../../store';
class AppSettings extends React.Component {
constructor(props) {
super(props);
//this.closeSyncOnlyModal = this.closeSyncOnlyModal.bind(this);
}
render() {
/*if (this.props && this.props.SyncOnly.display) {
return (
<div>
<div className="modal show sync-only-forks" aria-hidden="false" role="dialog">
<div className="modal-dialog modal-center modal-lg">
<div className="modal-content">
<div className="modal-body" style={{height: '590px'}}>
{this.renderForksList()}
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" onClick={this.closeSyncOnlyModal}>Close</button>
</div>
</div>
</div>
</div>
<div className="modal-backdrop show in"></div>
</div>
);
} else {
return null;
}*/
}
}
export default AppSettings;

40
react/src/components/dashboard/coinTileItem.js

@ -16,7 +16,8 @@ import {
getFullTransactionsList,
getBasiliskTransactionsList,
getShepherdCache,
fetchNewCacheData
fetchNewCacheData,
changeActiveAddress
} from '../../actions/actionCreators';
import Store from '../../store';
@ -32,6 +33,9 @@ class CoinTileItem extends React.Component {
// 3) limit req in basilisk as much as possible incl. activehandle
// 4) add pending requests store
// TODO: update all addresses once in 20 min, current address every 10 min
// always fetch main addr data and current selected address
dispatchCoinActions(coin, mode) {
if (mode === 'native') {
Store.dispatch(iguanaActiveHandle(true));
@ -51,9 +55,9 @@ class CoinTileItem extends React.Component {
if (mode === 'basilisk') {
const useAddress = this.props.ActiveCoin.mainBasiliskAddress ? this.props.ActiveCoin.mainBasiliskAddress : this.props.Dashboard.activeHandle[coin];
Store.dispatch(iguanaActiveHandle(true));
Store.dispatch(getShepherdCache(JSON.parse(sessionStorage.getItem('IguanaActiveAccount')).pubkey, coin));
if (this.props && this.props.Dashboard && this.props.Dashboard.activeHandle && this.props.Dashboard.activeHandle[coin]) {
Store.dispatch(getShepherdCache(this.props.Dashboard.activeHandle.pubkey, coin));
Store.dispatch(getBasiliskTransactionsList(coin, useAddress));
Store.dispatch(getKMDAddressesNative(coin, mode, useAddress));
//Store.dispatch(iguanaEdexBalance(coin, mode));
@ -83,21 +87,35 @@ class CoinTileItem extends React.Component {
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
}
if (mode === 'basilisk') {
var _iguanaActiveHandle = setInterval(function() {
this.dispatchCoinActions(coin, mode);
}.bind(this), 3000);
const _basiliskMainAddress = this.props.Dashboard.activeHandle[coin] || JSON.parse(sessionStorage.getItem('IguanaActiveAccount'))[coin];
Store.dispatch(changeActiveAddress(_basiliskMainAddress));
var _basiliskCache = setInterval(function() {
if (_basiliskMainAddress) {
Store.dispatch(fetchNewCacheData({
'pubkey': this.props.Dashboard.activeHandle.pubkey,
'allcoins': false,
'coin': this.props.ActiveCoin.coin,
'coin': coin,
'calls': 'listtransactions:getbalance',
'address': _basiliskMainAddress,
}));
}.bind(this), 60000);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
Store.dispatch(startInterval('basilisk', _basiliskCache));
// basilisk
var _iguanaActiveHandle = setInterval(function() {
this.dispatchCoinActions(coin, mode);
}.bind(this), 3000);
var _basiliskCache = setInterval(function() {
Store.dispatch(fetchNewCacheData({
'pubkey': this.props.Dashboard.activeHandle.pubkey,
'allcoins': false,
'coin': this.props.ActiveCoin.coin,
'calls': 'listtransactions:getbalance',
'address': _basiliskMainAddress,
}));
}.bind(this), 240000);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
Store.dispatch(startInterval('basilisk', _basiliskCache));
// basilisk
}
}
}
}

165
react/src/components/dashboard/sendCoin.js

@ -21,7 +21,8 @@ import {
fetchUtxoCache,
basiliskRefresh,
edexGetTransaction,
getCacheFile
getCacheFile,
shepherdGroomPostPromise
} from '../../actions/actionCreators';
import Store from '../../store';
@ -32,7 +33,6 @@ const socket = io.connect('http://127.0.0.1:' + Config.agamaPort);
class SendCoin extends React.Component {
constructor(props) {
super(props);
this.state = {
currentStep: 0,
sendFrom: this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : null,
@ -46,26 +46,7 @@ class SendCoin extends React.Component {
addressSelectorOpen: false,
currentStackLength: 0,
totalStackLength: 0,
vin: [
{
"txid": "8f5d3bc7ff1d8abdedefa4ed71c2a085a5fec62b8491c08e4a6ed53925df0235",
"vout": 0,
"scriptSig": {
"asm": "3045022100ea6442b209ab48b7109f13399fa12f85915ee2204a21698b85454987d9303fe1022025e4630c684af9b982b243420d69e094d0fc708aaccf11b83fd9320fe4dd45f701 02bee71575d87c7285eda952358175af10879081a0cc6b94623aac6cb2c6a51eae",
"hex": "483045022100ea6442b209ab48b7109f13399fa12f85915ee2204a21698b85454987d9303fe1022025e4630c684af9b982b243420d69e094d0fc708aaccf11b83fd9320fe4dd45f7012102bee71575d87c7285eda952358175af10879081a0cc6b94623aac6cb2c6a51eae"
},
"sequence": 4294967295
},
{
"txid": "4cfb597119d4239e8fa75486d1ba4c62cef615a52568aca1bc9be3b457c12eac",
"vout": 0,
"scriptSig": {
"asm": "3044022001c1481b5fb142a1f38f8387c8d0ba6e4d6c6a96a8c6765ce805ce841cb2a58b02206caec099e209a469b78c22c674be77d92698fff94b4521c0d5e462ac5b19627c01 02bee71575d87c7285eda952358175af10879081a0cc6b94623aac6cb2c6a51eae",
"hex": "473044022001c1481b5fb142a1f38f8387c8d0ba6e4d6c6a96a8c6765ce805ce841cb2a58b02206caec099e209a469b78c22c674be77d92698fff94b4521c0d5e462ac5b19627c012102bee71575d87c7285eda952358175af10879081a0cc6b94623aac6cb2c6a51eae"
},
"sequence": 4294967295
}
]
utxoMethodInProgress: false,
};
this.updateInput = this.updateInput.bind(this);
this.handleBasiliskSend = this.handleBasiliskSend.bind(this);
@ -73,11 +54,18 @@ class SendCoin extends React.Component {
this.toggleSendSig = this.toggleSendSig.bind(this);
this.getOAdress = this.getOAdress.bind(this);
this.toggleSendAPIType = this.toggleSendAPIType.bind(this);
this.renderUTXOCacheInfo = this.renderUTXOCacheInfo.bind(this);
this._fetchNewUTXOData = this._fetchNewUTXOData.bind(this);
socket.on('messages', msg => this.updateSocketsData(msg));
}
componentWillReceiveProps(props) {
if (!this.state.sendFrom && this.props.ActiveCoin.activeAddress) {
this.setState(Object.assign({}, this.state, {
sendFrom: this.props.ActiveCoin.activeAddress,
}));
}
}
updateSocketsData(data) {
console.log('sockets', data);
if (data && data.message && data.message.shepherd.iguanaAPI &&
@ -107,40 +95,55 @@ class SendCoin extends React.Component {
'calls': 'refresh',
'address': this.state.sendFrom,
}));
console.log('_fetchUtxoCache', {
'pubkey': this.props.Dashboard.activeHandle.pubkey,
'allcoins': false,
'coin': this.props.ActiveCoin.coin,
'calls': 'refresh',
'address': this.state.sendFrom,
});
}
renderUTXOCacheInfo() {
if (this.props.ActiveCoin.mode === 'basilisk' &&
this.state.sendFrom &&
!this.state.sendApiType &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom] &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh) {
const refreshCacheData = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh;
const timestamp = checkTimestamp(refreshCacheData.timestamp);
const isReadyToUpdate = timestamp > 600 ? true : false;
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom]) {
let refreshCacheData,
timestamp,
isReadyToUpdate,
waitUntilCallIsFinished = this.state.currentStackLength > 1 ? true : false;
if (this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh ||
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].listunspent) {
refreshCacheData = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh || this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].listunspent;
timestamp = checkTimestamp(refreshCacheData.timestamp);
isReadyToUpdate = timestamp > 600 ? true : false;
} else {
isReadyToUpdate = true;
}
if (this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh.data &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh.data.error &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh.data.error === 'request failed') {
timestamp = null;
}
return (
<div className="col-lg-12">
<hr />
Total UTXO available: {refreshCacheData.data.length}<br />
Last updated @ {secondsToString(refreshCacheData.timestamp, true)} | {secondsElapsedToString(timestamp)} ago<br />
Total UTXO available: {refreshCacheData ? refreshCacheData.data && refreshCacheData.data.length : 'N/A. Press update button.'}<br />
<div className={!timestamp ? 'hide' : ''}>
Last updated @ {secondsToString(refreshCacheData ? refreshCacheData.timestamp : 0, true)} | {secondsElapsedToString(timestamp || 0)} ago<br />
</div>
<div className={isReadyToUpdate ? 'hide' : ''}>Next update available in {secondsElapsedToString(600 - timestamp)}s</div>
<div className={this.state.currentStackLength === 1 || (this.state.currentStackLength === 0 && this.state.totalStackLength === 0) ? 'hide' : 'progress progress-sm'} style={{width: '100%', marginBottom: '10px', marginTop: '10px'}}>
<div className="progress-bar progress-bar-striped active progress-bar-indicating progress-bar-success" style={{width: 100 - (this.state.currentStackLength * 100 / this.state.totalStackLength) + '%', fontSize: '80%'}} role="progressbar">
Processing requests: {this.state.currentStackLength} / {this.state.totalStackLength}
</div>
</div>
<button type="button" style={{marginTop: '10px'}} className={isReadyToUpdate ? 'btn btn-primary waves-effect waves-light' : 'hide'} onClick={this._fetchNewUTXOData}>
Update
<button type="button" style={{marginTop: '10px'}} className={isReadyToUpdate ? 'btn btn-primary waves-effect waves-light' : 'hide'} onClick={this._fetchNewUTXOData} disabled={waitUntilCallIsFinished}>
{waitUntilCallIsFinished ? 'Locked, please wait...' : 'Update'}
</button>
<hr />
<div>
Split funds
<hr />
</div>
</div>
);
} else {
@ -241,12 +244,6 @@ class SendCoin extends React.Component {
sendFromAmount: amount ? amount : this.props.ActiveCoin.addresses[type][address].amount,
addressSelectorOpen: !this.state.addressSelectorOpen,
}));
this.renderCachedUTXOInfo();
}
renderCachedUTXOInfo() {
}
changeSendCoinStep(step) {
@ -254,6 +251,7 @@ class SendCoin extends React.Component {
this.setState(Object.assign({}, this.state, {
currentStep: step,
utxoMethodInProgress: !this.state.sendApiType && this.props.ActiveCoin.mode === 'basilisk' ? true : false,
}));
if (step === 2) {
@ -274,6 +272,7 @@ class SendCoin extends React.Component {
toggleSendAPIType() {
this.setState(Object.assign({}, this.state, {
sendApiType: !this.state.sendApiType,
sendFrom: this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin],
}));
}
@ -286,7 +285,9 @@ class SendCoin extends React.Component {
handleBasiliskSend() {
const refreshData = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].refresh;
const listunspentData = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.state.sendFrom].listunspent;
const utxoSet = refreshData && refreshData.data || listunspentData && listunspentData.data;
const utxoSet = (refreshData && refreshData.data) || (listunspentData && listunspentData.data);
const _pubkey = this.props.Dashboard.activeHandle.pubkey;
const forceUpdateCache = this._fetchNewUTXOData;
const sendData = {
'coin': this.props.ActiveCoin.coin,
'sendfrom': this.state.sendFrom,
@ -305,7 +306,6 @@ class SendCoin extends React.Component {
Store.dispatch(triggerToaster(true, translate('TOASTR.SIGNED_TX_GENERATED') + '.', translate('TOASTR.WALLET_NOTIFICATION'), 'success'));
if (sendData.sendsig === 1) {
// Store.dispatch(triggerToaster(true, translate('TOASTR.SENDING_TX') + '.', translate('TOASTR.WALLET_NOTIFICATION'), 'success'));
const dexrawtxData = {
'signedtx': json.signedtx,
'coin': sendData.coin
@ -316,6 +316,10 @@ class SendCoin extends React.Component {
if (dexRawTxJSON.indexOf('"error":{"code"') > -1) {
Store.dispatch(triggerToaster(true, 'Transaction failed', translate('TOASTR.WALLET_NOTIFICATION'), 'error'));
Store.dispatch(sendToAddressStateAlt(JSON.parse(dexRawTxJSON)));
this.setState(Object.assign({}, this.state, {
utxoMethodInProgress: false,
}));
} else {
Store.dispatch(triggerToaster(true, translate('TOASTR.SIGNED_TX_SENT'), translate('TOASTR.WALLET_NOTIFICATION'), 'success'));
Store.dispatch(sendToAddressStateAlt(json));
@ -326,7 +330,7 @@ class SendCoin extends React.Component {
edexGetTransaction({
'coin': sendData.coin,
'txid': dexRawTxJSON.txid
'txid': dexRawTxJSON.txid ? dexRawTxJSON.txid : dexRawTxJSON
})
.then(function(json) {
console.log('gettx', json);
@ -336,6 +340,8 @@ class SendCoin extends React.Component {
}
let processRefreshUTXOs = function(vinData) {
console.log('vin', vinData);
return new Promise(function(resolve, reject) {
let edexGetTxIDListRes = edexGetTxIDList(vinData);
resolve(edexGetTxIDListRes);
@ -347,11 +353,11 @@ class SendCoin extends React.Component {
console.log(txidListToRemove);
console.log(sendData);
getCacheFile()
getCacheFile(_pubkey)
.then(function(result) {
console.log(result);
let saveThisData = edexRemoveTXID(result, txidListToRemove);
console.log(saveThisData);
console.log('got cache file', result);
let saveThisData = edexRemoveTXID(result.result, txidListToRemove);
console.log('saveThisData', saveThisData);
resolve(saveThisData);
});
});
@ -361,16 +367,26 @@ class SendCoin extends React.Component {
return new Promise(function(resolve, reject) {
console.log('saveNewCacheData', saveThisData);
shepherdGroomPost(saveThisData)
shepherdGroomPostPromise(_pubkey, saveThisData)
.then(function(result) {
console.log('saveNewCacheData', saveThisData);
console.log(result);
resolve(result);
});
});
}
forceUpdateCache();
Store.dispatch(triggerToaster(true, 'Local UTXO data is updated. Ready to send new transaction.', translate('TOASTR.WALLET_NOTIFICATION'), 'info'));
this.setState(Object.assign({}, this.state, {
utxoMethodInProgress: false,
}));
}.bind(this));
}.bind(this));
}.bind(this);
Store.dispatch(triggerToaster(true, 'Awaiting transaction data response...', translate('TOASTR.WALLET_NOTIFICATION'), 'info'));
function waterfallUTXOProcess() {
Store.dispatch(triggerToaster(true, 'Processing UTXO...', translate('TOASTR.WALLET_NOTIFICATION'), 'info'));
setTimeout(function() {
getTxidData()
.then(function(gettxdata) {
return processRefreshUTXOs(gettxdata.vin);
@ -381,20 +397,39 @@ class SendCoin extends React.Component {
.then(function(save_this_data) {
return saveNewCacheData(save_this_data);
});
}, 2000);
}
let sentTxData = setInterval(function() {
getTxidData()
.then(function(gettxdata) {
if (gettxdata.vin && gettxdata.vin.length) {
clearInterval(sentTxData);
waterfallUTXOProcess();
}
})
}, 1000);
console.log('utxo remove', true);
}
});
}.bind(this));
} else {
Store.dispatch(sendToAddressStateAlt(json));
this.setState(Object.assign({}, this.state, {
utxoMethodInProgress: false,
}));
}
} else {
Store.dispatch(sendToAddressStateAlt(json));
Store.dispatch(triggerToaster(true, translate('TOASTR.SIGNED_TX_GENERATED_FAIL') + '.', translate('TOASTR.WALLET_NOTIFICATION'), 'error'));
this.setState(Object.assign({}, this.state, {
utxoMethodInProgress: false,
}));
}
console.log(json);
});
}.bind(this));
}
renderSignedTx(isRawTx) {
@ -480,7 +515,10 @@ class SendCoin extends React.Component {
} else {
return (
<div style={{padding: '20px', textAlign: 'center'}}>
<div style={{padding: '10px 0'}}>Processing transaction...</div>
<div style={{padding: '10px 0'}}>
Processing transaction...<br />
Note: it may take a few minutes to complete the transaction.
</div>
<div className="loader-wrapper active">
<div className="loader-layer loader-blue">
<div className="loader-circle-left">
@ -712,6 +750,9 @@ class SendCoin extends React.Component {
<div className="panel" id="edexcoin-send-txdetails-screen">
<div className="panel-heading">
<h4 className="panel-title">{translate('INDEX.TRANSACTION_RESULT')}</h4>
<div className={!this.state.sendSig ? 'hide' : 'center'}>
You picked option "{translate('INDEX.DONT_SEND')}"
</div>
<table className="table table-hover table-striped edexcoin_sendto_result" data-edexcoin="COIN" id="edexcoin_sendto_result">
<thead>
<tr>
@ -725,7 +766,7 @@ class SendCoin extends React.Component {
</table>
<div className="widget-body-footer">
<div className="widget-actions margin-bottom-15 margin-right-15">
<button type="button" className="btn btn-primary" id="edexcoin_send_coins_anothertx_btn" onClick={() => this.changeSendCoinStep(0)}>{translate('INDEX.MAKE_ANOTHER_TX')}</button>
<button type="button" className="btn btn-primary" id="edexcoin_send_coins_anothertx_btn" onClick={() => this.changeSendCoinStep(0)} disabled={this.state.utxoMethodInProgress}>{!this.state.utxoMethodInProgress ? translate('INDEX.MAKE_ANOTHER_TX') : 'Please wait...'}</button>
</div>
</div>
</div>

41
react/src/components/dashboard/settings.js

@ -7,7 +7,8 @@ import {
importPrivKey,
getDebugLog,
getPeersList,
addPeerNode
addPeerNode,
getAppConfig
} from '../../actions/actionCreators';
import Store from '../../store';
import AddCoinOptionsCrypto from '../addcoin/addcoinOptionsCrypto';
@ -42,6 +43,7 @@ class Settings extends React.Component {
componentDidMount() {
Store.dispatch(iguanaActiveHandle());
Store.dispatch(getAppConfig());
}
openTab(elemId, tab) {
@ -388,6 +390,43 @@ class Settings extends React.Component {
</div>
</div>
</div>
<div className="panel" id="AppSettings">
<div className="panel-heading" role="tab" onClick={() => this.openTab('AppSettings', 7)}>
<a className={this.state.activeTab === 6 ? 'panel-title' : 'panel-title collapsed'} data-toggle="collapse" data-parent="#AppSettings">
<i className="icon md-info" aria-hidden="true"></i>App Settings (config.json)
</a>
</div>
<div className={this.state.activeTab === 7 ? 'panel-collapse collapse in' : 'panel-collapse collapse'} style={{height: this.state.activeTab === 7 ? this.state.activeTabHeight + 'px' : '10px'}} id="DebugLogTab" aria-labelledby="DebugLog" role="tabpanel">
<div className="panel-body">
<p>Manage app settings</p>
<div className="col-sm-12"></div>
<form className="read-debug-log-import-form" method="post" action="javascript:" autoComplete="off">
<div className="form-group form-material floating">
<input type="text" className="form-control" name="debugLinesCount" id="read_debug_log_lines" value={this.state.debugLinesCount} onChange={this.updateInput} />
<label className="floating-label" htmlFor="read_debug_log_lines">{translate('INDEX.DEBUG_LOG_LINES')}</label>
</div>
<div className="form-group form-material floating">
<select className="form-control form-material" name="debugTarget" id="settings_select_debuglog_options" onChange={this.updateInput}>
<option value="iguana">Iguana</option>
<option value="komodo">Komodo</option>
</select>
<label className="floating-label" htmlFor="settings_select_debuglog_options">{translate('INDEX.TARGET')}</label>
</div>
<div className="col-sm-12 col-xs-12" style={{textAlign: 'center'}}>
<button type="button" className="btn btn-primary waves-effect waves-light" data-toggle="modal" data-dismiss="modal" id="read_debug_log_btn" onClick={this.readDebugLog}>{translate('INDEX.LOAD_DEBUG_LOG')}</button>
</div>
<div className="col-sm-12 col-xs-12" style={{textAlign: 'left'}}>
<br />
<div style={{padding: '20px 0'}}>{this.props.Settings.debugLog}</div>
</div>
</form>
<div className="col-sm-12" style={{paddingTop: '15px'}}>
<div className="row" data-plugin="masonry"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

53
react/src/components/dashboard/walletsBalance.js

@ -18,6 +18,49 @@ class WalletsBalance extends React.Component {
}
}
renderBalance(type) {
let _balance = '0';
if (this.props.ActiveCoin.mode === 'full') {
_balance = this.props.ActiveCoin.balance || 0;
} else {
if (this.props.ActiveCoin.cache) {
if (type === 'main' &&
this.props.ActiveCoin.mode === 'basilisk' &&
this.props.ActiveCoin.activeAddress &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.balance) {
_balance = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.balance;
}
if (type === 'interest' &&
this.props.ActiveCoin.mode === 'basilisk' &&
this.props.ActiveCoin.activeAddress &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.interest) {
_balance = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.interest;
}
if (type === 'total' &&
this.props.ActiveCoin.mode === 'basilisk' &&
this.props.ActiveCoin.activeAddress &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance &&
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data &&
(this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.balance ||
this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.interest)) {
const _regBalance = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.balance ? this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.balance : 0;
const _regInterest = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.interest ? this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][this.props.ActiveCoin.activeAddress].getbalance.data.interest : 0;
_balance = _regBalance + _regInterest;
}
}
}
return _balance;
}
render() {
if (this.props &&
this.props.ActiveCoin &&
@ -58,7 +101,7 @@ class WalletsBalance extends React.Component {
<i className="icon fa-eye font-size-24 vertical-align-bottom margin-right-5"></i>{translate('INDEX.BALANCE')}
</div>
<span className="pull-right padding-top-10" data-edexcoin="COIN" style={{fontSize: '22px'}}>
<span data-edexcoin="COIN" id="edex_total_balance"></span> <span data-edexcoin="COIN" id="edex_total_balance_coincode">{this.props.ActiveCoin && this.props.ActiveCoin.balance ? this.props.ActiveCoin.balance : 0}</span>
{this.renderBalance('main')} {this.props.ActiveCoin.coin}
</span>
</div>
</div>
@ -66,7 +109,7 @@ class WalletsBalance extends React.Component {
</div>
</div>
<div className={this.props.ActiveCoin.mode === 'native'|| (this.props.ActiveCoin.mode === 'basilisk' && this.props.ActiveCoin.coin === 'KMD') ? 'col-lg-4 col-xs-12' : 'col-lg-4 col-xs-12 hide'} data-edexcoin="COIN" id="edexcoin_getbalance_interest">
<div className={this.props.ActiveCoin.mode === 'native' || this.props.ActiveCoin.mode === 'basilisk' ? 'col-lg-4 col-xs-12' : 'col-lg-4 col-xs-12 hide'} data-edexcoin="COIN" id="edexcoin_getbalance_interest">
<div className="widget widget-shadow" id="widgetLineareaOne">
<div className="widget-content">
<div className="padding-20 padding-top-10">
@ -75,7 +118,7 @@ class WalletsBalance extends React.Component {
<i className="icon fa-money font-size-24 vertical-align-bottom margin-right-5"></i>{translate('INDEX.INTEREST_EARNED')}
</div>
<span className="pull-right padding-top-10" data-edexcoin="COIN" style={{fontSize: '22px'}}>
<span data-edexcoin="COIN" id="edex_interest_balance"></span> <span data-edexcoin="COIN" id="edex_total_interest_coincode"></span>
{this.renderBalance('interest')} {this.props.ActiveCoin.coin}
</span>
</div>
</div>
@ -83,7 +126,7 @@ class WalletsBalance extends React.Component {
</div>
</div>
<div className={this.props.ActiveCoin.mode === 'native' || (this.props.ActiveCoin.mode === 'basilisk' && this.props.ActiveCoin.coin === 'KMD') ? 'col-lg-4 col-xs-12' : 'col-lg-4 col-xs-12 hide'} data-edexcoin="COIN" id="edexcoin_getbalance_total_interest">
<div className={this.props.ActiveCoin.mode === 'native' || this.props.ActiveCoin.mode === 'basilisk' ? 'col-lg-4 col-xs-12' : 'col-lg-4 col-xs-12 hide'} data-edexcoin="COIN" id="edexcoin_getbalance_total_interest">
<div className="widget widget-shadow" id="widgetLineareaOne">
<div className="widget-content">
<div className="padding-20 padding-top-10">
@ -92,7 +135,7 @@ class WalletsBalance extends React.Component {
<i className="icon fa-bullseye font-size-24 vertical-align-bottom margin-right-5"></i>{translate('INDEX.TOTAL_BALANCE')}
</div>
<span className="pull-right padding-top-10" data-edexcoin="COIN" style={{fontSize: '22px'}}>
<span data-edexcoin="COIN" id="edex_total_balance_interest"></span> <span data-edexcoin="COIN" id="edex_total_balance_interest_coincode"></span>
{this.renderBalance('total')} {this.props.ActiveCoin.coin}
</span>
</div>
</div>

82
react/src/components/dashboard/walletsData.js

@ -16,7 +16,8 @@ import {
toggleViewCacheModal,
fetchNewCacheData,
fetchUtxoCache,
restartBasiliskInstance
restartBasiliskInstance,
changeActiveAddress
} from '../../actions/actionCreators';
import Store from '../../store';
@ -50,7 +51,6 @@ class WalletsData extends React.Component {
this.basiliskConnectionAction = this.basiliskConnectionAction.bind(this);
this.getDexNotariesAction = this.getDexNotariesAction.bind(this);
this.openDropMenu = this.openDropMenu.bind(this);
this.refreshTxList = this.refreshTxList.bind(this);
this.removeAndFetchNewCache = this.removeAndFetchNewCache.bind(this);
this._toggleViewCacheModal = this._toggleViewCacheModal.bind(this);
this.toggleCacheApi = this.toggleCacheApi.bind(this);
@ -133,15 +133,22 @@ class WalletsData extends React.Component {
}));
}
basiliskRefreshActionOne() {
Store.dispatch(fetchNewCacheData({
'pubkey': this.props.Dashboard.activeHandle.pubkey,
'allcoins': false,
'coin': this.props.ActiveCoin.coin,
'calls': 'listtransactions:getbalance',
}));
}
basiliskRefreshAction() {
/*if (this.props.Dashboard) {
Store.dispatch(basiliskRefresh(!this.props.Dashboard.basiliskRefresh));
}*/
Store.dispatch(fetchNewCacheData({
'pubkey': this.props.Dashboard.activeHandle.pubkey,
'allcoins': false,
'coin': this.props.ActiveCoin.coin,
'calls': 'listtransactions:getbalance',
'address': this.props.ActiveCoin.activeAddress,
}));
}
@ -173,6 +180,12 @@ class WalletsData extends React.Component {
}
componentWillReceiveProps(props) {
if (!this.state.currentAddress && this.props.ActiveCoin.activeAddress) {
this.setState(Object.assign({}, this.state, {
currentAddress: this.props.ActiveCoin.activeAddress,
}));
}
if (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory !== 'loading' && this.props.ActiveCoin.txhistory !== 'no data' && this.props.ActiveCoin.txhistory.length) {
if (!this.state.itemsList || (this.state.itemsList && !this.state.itemsList.length) || (props.ActiveCoin.txhistory !== this.props.ActiveCoin.txhistory)) {
let historyToSplit = sortByDate(this.props.ActiveCoin.txhistory);
@ -329,6 +342,8 @@ class WalletsData extends React.Component {
}
updateAddressSelection(address, type, amount) {
Store.dispatch(changeActiveAddress(address));
this.setState(Object.assign({}, this.state, {
currentAddress: address,
addressSelectorOpen: false,
@ -341,16 +356,35 @@ class WalletsData extends React.Component {
}.bind(this), 100);
}
refreshTxList() {
Store.dispatch(getBasiliskTransactionsList(this.props.ActiveCoin.coin, this.props.ActiveCoin.mainBasiliskAddress));
}
openDropMenu() {
this.setState(Object.assign({}, this.state, {
addressSelectorOpen: !this.state.addressSelectorOpen,
}));
}
/*filterTable() {
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
}*/
renderUseCacheToggle() {
if (this.props.ActiveCoin.mode === 'basilisk') {
return (
@ -379,7 +413,7 @@ class WalletsData extends React.Component {
}
renderAddressAmount() {
if (this.props.ActiveCoin.addresses['public'] && this.props.ActiveCoin.addresses['public'].length) {
if (this.props.ActiveCoin.addresses && this.props.ActiveCoin.addresses['public'] && this.props.ActiveCoin.addresses['public'].length) {
for (let i = 0; i < this.props.ActiveCoin.addresses['public'].length; i++) {
if (this.props.ActiveCoin.addresses['public'][i].address === this.state.currentAddress) {
return this.props.ActiveCoin.addresses['public'][i].amount;
@ -430,7 +464,12 @@ class WalletsData extends React.Component {
}
render() {
if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.coin && this.props.ActiveCoin.mode !== 'native' && !this.props.ActiveCoin.send && !this.props.ActiveCoin.receive) {
if (this.props &&
this.props.ActiveCoin &&
this.props.ActiveCoin.coin &&
this.props.ActiveCoin.mode !== 'native' &&
!this.props.ActiveCoin.send &&
!this.props.ActiveCoin.receive) {
return (
<span>
<WalletsBasiliskRefresh {...this.props} />
@ -450,9 +489,6 @@ class WalletsData extends React.Component {
Processing requests: {this.state.currentStackLength} / {this.state.totalStackLength}
</div>
</div>
<a href="javascript:void(0)" className="dropdown-toggle white btn-xs btn-info btn_refresh_edexcoin_dashboard margin-right-10" data-edexcoin="COIN" aria-expanded="false" role="button" onClick={this.refreshTxList}>
<i className="icon fa-refresh margin-right-10" aria-hidden="true"></i> {translate('INDEX.REFRESH')}
</a>
<div className={this.state.basiliskActionsMenu ? 'dropdown open' : 'dropdown'} onClick={this.toggleBasiliskActionsMenu}>
<a className="dropdown-toggle btn-xs btn-default" data-edexcoin="COIN" id="btn_edexcoin_basilisk" data-toggle="dropdown" href="javascript:void(0)"
aria-expanded="false" role="button">
@ -472,7 +508,12 @@ class WalletsData extends React.Component {
</li>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''}>
<a className="btn_edexcoin_dashboard_fetchdata" data-edexcoin="COIN" id="btn_edexcoin_dashboard_fetchdata" role="menuitem" onClick={this.basiliskRefreshActionOne}>
<i className="icon fa-cloud-download" aria-hidden="true"></i> {translate('INDEX.FETCH_WALLET_DATA')}
<i className="icon fa-cloud-download" aria-hidden="true"></i> {translate('INDEX.FETCH_WALLET_DATA')} (active address)
</a>
</li>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''}>
<a role="menuitem" onClick={this.basiliskRefreshAction}>
<i className="icon fa-cloud-download" aria-hidden="true"></i> Fetch (all addresses)
</a>
</li>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''}>
@ -480,19 +521,14 @@ class WalletsData extends React.Component {
<i className="icon fa-history" aria-hidden="true"></i> {translate('INDEX.REFETCH_WALLET_DATA')}
</a>
</li>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''}>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''} style={{display: 'none'}}>
<a role="menuitem" onClick={this._fetchUtxoCache}>
<i className="icon fa-history" aria-hidden="true"></i> Update UTXO
</a>
</li>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''}>
<a role="menuitem" onClick={this.basiliskRefreshAction}>
<i className="icon fa-cloud-download" aria-hidden="true"></i> Fetch all
</a>
</li>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''}>
<a role="menuitem" onClick={this.restartBasiliskInstance}>
<i className="icon fa-refresh" aria-hidden="true"></i> Restart Basilisk Instance
<i className="icon fa-refresh" aria-hidden="true"></i> Restart Basilisk Instance (!)
</a>
</li>
<li data-edexcoin="COIN" role="presentation" className={!this.state.useCache ? 'hide' : ''}>
@ -507,7 +543,7 @@ class WalletsData extends React.Component {
</header>
<div className="panel-body">
<div className="row">
<div className="col-sm-6">
<div className="col-sm-8">
{this.renderAddressList()}
</div>
{this.renderUseCacheToggle}

2
react/src/components/dashboard/walletsNativeSend.js

@ -187,7 +187,7 @@ class WalletsNativeSend extends React.Component {
Store.dispatch(sendNativeTx(this.props.ActiveCoin.coin, this.state));
setTimeout(function() {
Store.dispatch(getKMDOPID(null, this.props.ActiveCoin.coin));
}, 1000);
}.bind(this), 1000);
}
getOAdress() {

13
react/src/components/login/login.js

@ -68,9 +68,8 @@ class Login extends React.Component {
this.setState({
display: false,
});
// Store.dispatch(stopInterval('activeCoins', this.props.Interval.interval));
}
if (props && props.Main && !props.Main.isLoggedIn) {
this.setState({
display: true,
@ -85,6 +84,7 @@ class Login extends React.Component {
document.body.className = 'page-login layout-full page-dark';
}
if (this.state.activeLoginSection !== 'signup') {
if (props && props.Main && props.Main.activeCoins) {
this.setState({
@ -124,6 +124,7 @@ class Login extends React.Component {
this.setState({
isSeedConfirmError: false,
});
Store.dispatch(createNewWallet(this.state.randomSeedConfirm, this.props.Dashboard.activeHandle));
} else {
this.setState({
@ -132,6 +133,12 @@ class Login extends React.Component {
}
}
handleKeydown(e) {
if (e.key === 'Enter') {
this.loginSeed();
}
}
render() {
if ((this.state && this.state.display) || !this.props.Main) {
return (
@ -178,7 +185,7 @@ class Login extends React.Component {
<h4 style={{ color: '#fff' }} id="login-welcome">{translate('INDEX.WELCOME_LOGIN')}</h4>
<div className="login-form">
<div className="form-group form-material floating">
<input type={this.state.seedInputVisibility ? 'text' : 'password'} className="form-control" name="loginPassphrase" id="password" onChange={this.updateInput} />
<input type={this.state.seedInputVisibility ? 'text' : 'password'} className="form-control" name="loginPassphrase" id="password" onChange={this.updateInput} onKeyDown={(event) => this.handleKeydown(event)} />
<i className={this.state.seedInputVisibility ? 'seed-toggle fa fa-eye-slash' : 'seed-toggle fa fa-eye'} onClick={this.toggleSeedInputVisibility}></i>
<label className="floating-label" htmlFor="inputPassword">{translate('INDEX.WALLET_SEED')}</label>
</div>

11
react/src/reducers/activeCoin.js

@ -14,7 +14,8 @@ import {
DASHBOARD_ACTIVE_COIN_GET_CACHE,
DASHBOARD_ACTIVE_COIN_MAIN_BASILISK_ADDR,
DASHBOARD_GET_NOTARIES_LIST,
DASHBOARD_DISPLAY_NOTARIES_MODAL
DASHBOARD_DISPLAY_NOTARIES_MODAL,
DASHBOARD_ACTIVE_ADDRESS,
} from '../actions/actionCreators';
// TODO: refactor
@ -36,6 +37,7 @@ export function ActiveCoin(state = {
mainBasiliskAddress: null,
notaries: null,
displayNotariesModal: false,
activeAddress: null,
}, action) {
switch (action.type) {
case DASHBOARD_ACTIVE_COIN_CHANGE:
@ -55,6 +57,7 @@ export function ActiveCoin(state = {
lastSendToResponse: state.lastSendToResponse,
mainBasiliskAddress: state.mainBasiliskAddress,
opids: state.opids,
activeBasiliskAddress: state.activeBasiliskAddress,
};
let _coins = state.coins;
_coins[state.coin] = _coinDataToStore;
@ -74,6 +77,7 @@ export function ActiveCoin(state = {
lastSendToResponse: _coinData.lastSendToResponse,
mainBasiliskAddress: _coinData.mainBasiliskAddress,
opids: _coinData.opids,
activeBasiliskAddress: _coinData.activeBasiliskAddress,
});
} else {
if (state.coin) {
@ -91,6 +95,7 @@ export function ActiveCoin(state = {
lastSendToResponse: state.lastSendToResponse,
mainBasiliskAddress: state.mainBasiliskAddress,
opids: state.opids,
activeBasiliskAddress: state.activeBasiliskAddress,
};
let _coins = state.coins;
_coins[state.coin] = _coinData;
@ -185,6 +190,10 @@ export function ActiveCoin(state = {
return Object.assign({}, state, {
displayNotariesModal: action.display,
});
case DASHBOARD_ACTIVE_ADDRESS:
return Object.assign({}, state, {
activeAddress: action.address,
});
default:
return state;
}

4
react/src/styles/index.scss

@ -272,6 +272,10 @@ body {
}
}
.center {
text-align: center;
}
/*.toaster .single-toast:nth-child(0) {
bottom: 12px;
}

19
react/src/util/cacheFormat.js

@ -11,7 +11,7 @@ export function edexGetTxIDList(getTxData) {
}
export function edexRemoveTXID(_obj, txidArray) {
let txidToStr = txidArray.join(':');
let txidToStr = ':' + txidArray.join(':') + ':';
console.log(txidToStr);
@ -26,8 +26,21 @@ export function edexRemoveTXID(_obj, txidArray) {
_obj.basilisk[key][coinAddr].refresh.data &&
_obj.basilisk[key][coinAddr].refresh.data.length > 0) {
for (let i = 0; i < _obj.basilisk[key][coinAddr].refresh.data.length; i++) {
if (txidToStr.indexOf(_obj.basilisk[key][coinAddr].refresh.data[i].txid) > -1) {
if (txidToStr.indexOf(_obj.basilisk[key][coinAddr].refresh.data[i].txid.toString()) > -1) {
console.log('cacheformat remove node', _obj.basilisk[key][coinAddr].refresh.data[i].txid);
_obj.basilisk[key][coinAddr].refresh.data.splice(i, 1);
_obj.basilisk[key][coinAddr].refresh.timestamp = Date.now();
}
}
}
if (_obj.basilisk[key][coinAddr].listunspent &&
_obj.basilisk[key][coinAddr].listunspent.data &&
_obj.basilisk[key][coinAddr].listunspent.data.length > 0) {
for (let i = 0; i < _obj.basilisk[key][coinAddr].listunspent.data.length; i++) {
if (txidToStr.indexOf(_obj.basilisk[key][coinAddr].listunspent.data[i].txid.toString()) > -1) {
console.log('cacheformat remove node', _obj.basilisk[key][coinAddr].listunspent.data[i].txid);
_obj.basilisk[key][coinAddr].listunspent.data.splice(i, 1);
_obj.basilisk[key][coinAddr].listunspent.timestamp = Date.now();
}
}
}
@ -38,4 +51,6 @@ export function edexRemoveTXID(_obj, txidArray) {
} else {
console.log('basilisk node is missing');
}
return _obj;
}
Loading…
Cancel
Save