Browse Source

added http requests stack modal

all-modes
pbca26 8 years ago
parent
commit
490ddb48a4
  1. 147
      react/src/actions/actionCreators.js
  2. 147
      react/src/components/dashboard/notifications.js
  3. 9
      react/src/components/dashboard/sendCoin.js
  4. 8
      react/src/components/dashboard/walletsNativeTxInfo.js
  5. 18
      react/src/components/toaster/toaster.js
  6. 80
      react/src/styles/index.scss
  7. 2
      react/src/translate/en.js
  8. 6
      react/src/util/time.js

147
react/src/actions/actionCreators.js

@ -15,7 +15,7 @@ import { translate } from '../translate/translate';
let Config;
try {
Config = window.require('electron').remote.getCurrentWindow();
Config = window.require('electron').remote.getCurrentWindow().appConfig;
} catch (e) {
Config = _config;
}
@ -386,10 +386,6 @@ export function dismissToasterMessage() {
export function addCoin(coin, mode, syncOnly, port) {
console.log('coin, mode, syncOnly', coin + ' ' + mode + ' ' + syncOnly);
/*startIguanaInstance(mode, coin)
.then(function(json) {
console.log('addCoin+startIguanaInstance', json);
});*/
if (mode === '-1') {
return dispatch => {
dispatch(shepherdGetConfig(coin, mode));
@ -482,10 +478,6 @@ export function iguanaAddCoin(coin, mode, acData, port) {
if (mode === 0) {
return dispatch => {
return _iguanaAddCoin(dispatch);
/*startIguanaInstance('basilisk', 'basilisk')
.then(function(json) {
_iguanaAddCoin(dispatch);
});*/
}
} else {
return dispatch => {
@ -591,10 +583,9 @@ export function _shepherdGetConfig(coin, mode) {
}
}
// TODO: fix setconf/getconf KMD
export function shepherdGetConfig(coin, mode) {
if (coin === 'KMD' && mode === '-1') {
if (coin === 'KMD' &&
mode === '-1') {
return dispatch => {
return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/getconf', {
method: 'POST',
@ -674,7 +665,8 @@ export function getDexCoins() {
function rpcErrorHandler(json, dispatch) {
console.log('json', json);
if (json && json.error) {
if (json &&
json.error) {
if (json.error === 'bitcoinrpc needs coin that is active') {
dispatch(triggerToaster(true, 'No active coin', translate('TOASTR.SERVICE_NOTIFICATION'), 'error'));
}
@ -722,7 +714,7 @@ export function iguanaWalletPassphrase(_passphrase) {
'status': 'success',
'response': json,
}));
dispatch(iguanaWalletPassphraseState(json, dispatch))
dispatch(iguanaWalletPassphraseState(json, dispatch));
});
}
}
@ -895,7 +887,7 @@ export function encryptWallet(_passphrase, cb, coin) {
'status': 'success',
'response': json,
}));
dispatch(cb.call(this, json, coin))
dispatch(cb.call(this, json, coin));
});
}
}
@ -931,7 +923,7 @@ export function walletPassphrase(_passphrase) {
'status': 'error',
'response': error,
}));
dispatch(triggerToaster(true, 'walletPassphrase', 'Error', 'error'))
dispatch(triggerToaster(true, 'walletPassphrase', 'Error', 'error'));
})
.then(json => {
dispatch(logGuiHttp({
@ -944,10 +936,12 @@ export function walletPassphrase(_passphrase) {
}
export function getPeersListState(json) {
var peersList = {};
let peersList = {};
if (json && json.rawpeers && json.rawpeers.length) {
for (var i=0; i < json.rawpeers.length; i++) {
if (json &&
json.rawpeers &&
json.rawpeers.length) {
for (let i = 0; i < json.rawpeers.length; i++) {
peersList[json.rawpeers[i].coin] = json.rawpeers[i].peers;
}
}
@ -959,15 +953,6 @@ export function getPeersListState(json) {
}
export function getFullTransactionsList(coin) {
/*params = {
'userpass': tmpIguanaRPCAuth,
'agent': 'dex',
'method': 'listtransactions',
'address': coinaddr_value,
'count': 100,
'skip': 0,
'symbol': coin
};*/
const payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'coin': coin,
@ -1041,7 +1026,9 @@ export function getBasiliskTransactionsList(coin, address) {
})
.then(response => response.json())
.then(function(json) {
if (json.result && !json.result.basilisk && 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');
}
@ -1506,11 +1493,14 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
}
function calcBalance(result, json, dispatch, mode) {
if (mode === 'full' || mode === 'basilisk') {
if (mode === 'full' ||
mode === 'basilisk') {
result[0] = result[0].result;
}
if (mode !== 'basilisk' && json && json.length) {
if (mode !== 'basilisk' &&
json &&
json.length) {
const allAddrArray = json.map(res => res.address).filter((x, i, a) => a.indexOf(x) == i);
for (let a = 0; a < allAddrArray.length; a++) {
@ -1526,7 +1516,8 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
}
if (isNewAddr) {
if (allAddrArray[a].substring(0, 2) === 'zc' || allAddrArray[a].substring(0, 2) === 'zt') {
if (allAddrArray[a].substring(0, 2) === 'zc' ||
allAddrArray[a].substring(0, 2) === 'zt') {
result[1][result[1].length] = allAddrArray[a];
} else {
result[0][result[0].length] = allAddrArray[a];
@ -1583,7 +1574,7 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
})
.then(response => response.json())
.then(function(json) {
var updatedCache = Object.assign({}, json.result);
let updatedCache = Object.assign({}, json.result);
json = json.result.basilisk;
// if listunspent is not in cache file retrieve new copy
// otherwise read from cache data
@ -1595,12 +1586,12 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
'timestamp': _timestamp,
'function': 'getKMDAddressesNative+Balance',
'type': 'post',
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.basiliskPort : Config.iguanaCorePort),
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort),
'payload': payload,
'status': 'pending',
}));
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.basiliskPort : Config.iguanaCorePort), {
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort), {
method: 'POST',
body: JSON.stringify(payload),
})
@ -1636,12 +1627,12 @@ export function getKMDAddressesNative(coin, mode, currentAddress) {
'timestamp': _timestamp,
'function': 'getKMDAddressesNative+Balance',
'type': 'post',
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.basiliskPort : Config.iguanaCorePort),
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort),
'payload': payload,
'status': 'pending',
}));
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.basiliskPort : Config.iguanaCorePort), {
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort), {
method: 'POST',
body: JSON.stringify(payload),
})
@ -1717,7 +1708,7 @@ export function fetchUtxoCache(_payload) {
_coin = '&coin=' + _payload.coin,
_calls = '&calls=' + _payload.calls,
_address = _payload.address ? ('&address=' + _payload.address) : '',
_iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + Config.basiliskPort : '';
_iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + (Config.iguanaCorePort + 1) : '';
return dispatch => {
return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/' + _route + _userpass + _pubkey + _coin + _calls + _address + _iguanaInstancePort, {
@ -1736,7 +1727,9 @@ export function fetchUtxoCache(_payload) {
}
function getShepherdCacheState(json, pubkey, coin) {
if (json.result && json.error && json.result.indexOf('no file with handle') > -1) {
if (json.result &&
json.error &&
json.result.indexOf('no file with handle') > -1) {
return dispatch => {
dispatch(fetchNewCacheData({
'pubkey': pubkey,
@ -1813,7 +1806,9 @@ function parseImportPrivKeyResponse(json, dispatch) {
dispatch(triggerToaster(true, 'Privkey already in wallet', translate('TOASTR.SETTINGS_NOTIFICATION'), 'warning'));
}
}
if (json && json.result !== undefined && json.result == 'success') {
if (json &&
json.result !== undefined &&
json.result == 'success') {
return dispatch => {
dispatch(triggerToaster(true, translate('TOASTR.PRIV_KEY_IMPORTED'), translate('TOASTR.SETTINGS_NOTIFICATION'), 'success'));
}
@ -1931,7 +1926,9 @@ export function getSyncInfoNativeKMD(skipDebug) {
}
function getSyncInfoNativeState(json, coin, skipDebug) {
if (coin === 'KMD' && json && json.error) {
if (coin === 'KMD' &&
json &&
json.error) {
return getSyncInfoNativeKMD(skipDebug);
} else {
return {
@ -1942,7 +1939,7 @@ function getSyncInfoNativeState(json, coin, skipDebug) {
}
function getPassthruAgent(coin) {
var passthru_agent;
let passthru_agent;
if ( coin === 'KMD') { passthru_agent = 'komodo'; };
if ( coin === 'ZEC') { passthru_agent = 'zcash'; };
@ -2014,12 +2011,12 @@ export function getDexBalance(coin, mode, addr) {
'timestamp': _timestamp,
'function': 'getDexBalance',
'type': 'post',
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort),
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort),
'payload': payload,
'status': 'pending',
}));
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), {
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort), {
method: 'POST',
body: JSON.stringify(payload),
})
@ -2053,7 +2050,8 @@ export function getDexBalance(coin, mode, addr) {
export function getKMDBalanceTotal(coin) {
let payload;
if (coin !== 'KMD' && coin !== 'ZEC') {
if (coin !== 'KMD' &&
coin !== 'ZEC') {
payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': 'iguana',
@ -2103,7 +2101,8 @@ export function getKMDBalanceTotal(coin) {
'status': 'success',
'response': json,
}));
if (json && !json.error) {
if (json &&
!json.error) {
dispatch(getNativeBalancesState(json));
}
})
@ -2176,7 +2175,8 @@ export function getNativeTxHistory(coin) {
}
export function getNativeTxHistoryState(json) {
if (json && json.error) {
if (json &&
json.error) {
json = null;
} else if (json && json.result) {
json = json.result;
@ -2201,10 +2201,10 @@ export function getNewKMDAddresses(coin, pubpriv) {
let payload,
ajax_function_input = '';
if ( pubpriv === 'public' ) {
if (pubpriv === 'public') {
ajax_function_input = 'getnewaddress';
}
if ( pubpriv === 'private' ) {
if (pubpriv === 'private') {
ajax_function_input = 'z_getnewaddress';
}
@ -2375,7 +2375,8 @@ export function sendNativeTx(coin, _payload) {
'response': json,
}));
if (json.error && json.error.toString().indexOf('code:') > -1) {
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'));
@ -2472,7 +2473,8 @@ export function getKMDOPID(opid, coin) {
}
function sendToAddressState(json, dispatch) {
if (json && json.error) {
if (json &&
json.error) {
dispatch(triggerToaster(true, json.error, 'Error', 'error'));
return {
@ -2603,13 +2605,16 @@ export function sendFromAddress(coin, _payload) {
}
function checkAddressBasiliskHandle(json) {
if (json && json.error) {
if (json &&
json.error) {
return dispatch => {
dispatch(triggerToaster(true, json.error, translate('TOASTR.WALLET_NOTIFICATION'), 'error'));
}
}
if (json && json.coin && json.randipbits) {
if (json &&
json.coin &&
json.randipbits) {
return dispatch => {
dispatch(triggerToaster(true, 'Address already registered', translate('TOASTR.WALLET_NOTIFICATION'), 'warning'));
}
@ -2631,12 +2636,12 @@ export function checkAddressBasilisk(coin, address) {
'timestamp': _timestamp,
'function': 'checkAddressBasilisk',
'type': 'post',
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort),
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort),
'payload': payload,
'status': 'pending',
}));
return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), {
return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort), {
method: 'POST',
body: JSON.stringify(payload),
})
@ -2698,7 +2703,7 @@ export function validateAddressBasilisk(coin, address) {
'status': 'pending',
}));
return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), {
return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort), {
method: 'POST',
body: JSON.stringify(payload),
})
@ -2750,11 +2755,11 @@ export function getDexNotaries(coin) {
'timestamp': _timestamp,
'function': 'getDexNotaries',
'type': 'post',
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort),
'url': 'http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort),
'payload': payload,
'status': 'pending',
}));
return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort), {
return fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort), {
method: 'POST',
body: JSON.stringify(payload),
})
@ -2780,7 +2785,9 @@ export function getDexNotaries(coin) {
}
function createNewWalletState(json) {
if (json && json.result && json.result === 'success') {
if (json &&
json.result &&
json.result === 'success') {
return dispatch => {
dispatch(triggerToaster(true, translate('TOASTR.WALLET_CREATED_SUCCESFULLY'), translate('TOASTR.ACCOUNT_NOTIFICATION'), 'success'));
}
@ -2880,7 +2887,7 @@ export function fetchNewCacheData(_payload) {
_coin = '&coin=' + _payload.coin,
_calls = '&calls=' + _payload.calls,
_address = _payload.address ? ('&address=' + _payload.address) : '',
_iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + Config.basiliskPort : '';
_iguanaInstancePort = Config.useBasiliskInstance ? '&port=' + (Config.iguanaCorePort + 1) : '';
return dispatch => {
return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/' + _route + _userpass + _pubkey + _coin + _calls + _address + _iguanaInstancePort, {
@ -2920,7 +2927,7 @@ function initNotaryNodesConSequence(nodes) {
'status': 'pending',
}));
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.basiliskPort : Config.iguanaCorePort) + '/api/dex/getinfo?userpass=' + ('tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth')) + '&symbol=' + node, {
fetch('http://127.0.0.1:' + (Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort) + '/api/dex/getinfo?userpass=' + ('tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth')) + '&symbol=' + node, {
method: 'GET',
})
.catch(function(error) {
@ -2973,7 +2980,8 @@ function updateNotaryNodeConState(json, totalNodes, currentNodeIndex, currentNod
}
function connectAllNotaryNodes(json, dispatch) {
if (json && json.length) {
if (json &&
json.length) {
dispatch(initNotaryNodesConSequence(json));
return {
@ -3030,10 +3038,6 @@ export function restartIguanaInstance(pmid) {
headers: {
'Content-Type': 'application/json',
},
/*body: JSON.stringify({
mode,
coin
}),*/
})
.catch(function(error) {
console.log(error);
@ -3289,12 +3293,6 @@ export function getAppConfig() {
}
function getSyncOnlyForksState(json) {
/*try {
JSON.parse(json.result);
} catch(e) {
console.log(e);
}*/
return {
type: SYNC_ONLY_DATA,
forks: JSON.parse(json.result),
@ -3398,7 +3396,8 @@ export function logGuiHttp(payload) {
return dispatch => {
dispatch(guiLogState(payload));
return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/guilog', {
// disabled for now
/*return fetch('http://127.0.0.1:' + Config.agamaPort + '/shepherd/guilog', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@ -3409,7 +3408,7 @@ export function logGuiHttp(payload) {
console.log(error);
dispatch(triggerToaster(true, 'logGuiHttp', 'Error', 'error'));
})
.then(response => response.json())
.then(response => response.json())*/
}
}

147
react/src/components/dashboard/notifications.js

@ -1,4 +1,9 @@
import React from 'react';
import {
checkTimestamp,
secondsElapsedToString,
secondsToString
} from '../../util/time';
import { translate } from '../../translate/translate';
class Notifications extends React.Component {
@ -10,10 +15,17 @@ class Notifications extends React.Component {
totalErrorCalls: 0,
totalSuccessCalls: 0,
totalPendingCalls: 0,
activeTab: 2,
};
this.toggleNotificationsModal = this.toggleNotificationsModal.bind(this);
}
openTab(tab) {
this.setState(Object.assign({}, this.state, {
activeTab: tab,
}));
}
componentWillReceiveProps(props) {
// get total number of calls per type
if (this.props.Dashboard &&
@ -45,19 +57,142 @@ class Notifications extends React.Component {
}
}
toggleNotificationsModal() {
renderNotificationsByType(type) {
// get total number of calls per type
if (this.props.Dashboard &&
this.props.Dashboard.guiLog) {
const _guiLog = this.props.Dashboard.guiLog;
let items = [];
let index = 0;
for (let timestamp in _guiLog) {
if (_guiLog[timestamp].status === type) {
const _logItem = _guiLog[timestamp];
items.push(
<div key={ timestamp }>
<div>{ (index + 1) }.</div>
<div>
<strong>Time:</strong> { secondsToString(timestamp, true, true) }
</div>
<div>
<strong>GUI Function:</strong> { _logItem.function }
</div>
<div>
<strong>HTTP:</strong> { _logItem.httpMethod.toUpperCase() }
</div>
<div>
<strong>URL:</strong> { _logItem.url }
</div>
<div>
<strong>Payload:</strong> { JSON.stringify(_logItem.payload, null, '\t') }
</div>
<div className={ type !== 'pending' ? '' : 'hide' }>
<strong>Response:</strong> { JSON.stringify(_logItem.response, null, '\t') }
</div>
<hr />
</div>
);
}
index++;
}
return items;
}
}
renderNotificationsModal() {
if (this.state.displayModal) {
return (
<div onKeyDown={ (event) => this.handleKeydown(event) }>
<div className="modal show" aria-hidden="false" role="dialog">
<div className="modal-dialog modal-center modal-lg">
<div className="modal-content">
<div className="modal-body" style={{ height: '590px' }}>
<div className="panel nav-tabs-horizontal">
<ul className="nav nav-tabs nav-tabs-line" role="tablist">
<li className={ this.state.activeTab === 0 ? 'active' : 'pointer' } role="presentation">
<a
role="tab"
onClick={ () => this.openTab(0) }>
<i className="icon fa fa-thumbs-o-up" aria-hidden="true"></i> Success ({ this.state.totalSuccessCalls })
</a>
</li>
<li className={ this.state.activeTab === 1 ? 'active' : 'pointer' } role="presentation">
<a
role="tab"
onClick={ () => this.openTab(1) }>
<i className="icon fa fa-exclamation-triangle" aria-hidden="true"></i> Error ({ this.state.totalErrorCalls })
</a>
</li>
<li className={ this.state.activeTab === 2 ? 'active' : 'pointer' } role="presentation">
<a
role="tab"
onClick={ () => this.openTab(2) }>
<i className="icon fa fa-clock-o" aria-hidden="true"></i> Pending ({ this.state.totalPendingCalls })
</a>
</li>
</ul>
<div className="panel-body" style={{ height: '500px', overflowY: 'scroll' }}>
<div className="tab-content">
<div
className={ this.state.activeTab === 0 ? 'tab-pane active' : 'tab-pane' }
role="tabpanel">
{ this.renderNotificationsByType('success') }
</div>
<div
className={ this.state.activeTab === 1 ? 'tab-pane active' : 'tab-pane' }
role="tabpanel">
{ this.renderNotificationsByType('error') }
</div>
<div
className={ this.state.activeTab === 2 ? 'tab-pane active' : 'tab-pane' }
role="tabpanel">
{ this.renderNotificationsByType('pending') }
</div>
</div>
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-default"
data-dismiss="modal"
onClick={ this.toggleNotificationsModal }>{ translate('INDEX.CLOSE') }</button>
</div>
</div>
</div>
</div>
<div className="modal-backdrop show in"></div>
</div>
);
} else {
return null;
}
}
toggleNotificationsModal() {
this.setState(Object.assign({}, this.state, {
displayModal: !this.state.displayModal,
}));
}
render() {
return (
<div className="notifications-badge" onClick={ this.toggleNotificationsModal }>
<span className="badge success">{ this.state.totalSuccessCalls }</span>
<span className="badge error">{ this.state.totalErrorCalls }</span>
<span className="badge pending">{ this.state.totalPendingCalls }</span>
<div>
<div
className={ this.props.Dashboard.activeHandle && this.props.Dashboard.activeHandle.status === 'unlocked' ? 'notifications-badge stick-to-top' : 'notifications-badge' }
onClick={ this.toggleNotificationsModal }>
<span className="badge success">{ this.state.totalSuccessCalls }</span>
<span className="badge error">{ this.state.totalErrorCalls }</span>
<span className="badge pending">{ this.state.totalPendingCalls }</span>
</div>
{ this.renderNotificationsModal() }
</div>
);
}
}
export default Notifications;
export default Notifications;

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

@ -235,7 +235,6 @@ class SendCoin extends React.Component {
if (this.props.ActiveCoin.mode === 'basilisk') {
_amount = this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][address.address] && this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][address.address].getbalance.data && this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][address.address].getbalance.data.balance ? this.props.ActiveCoin.cache[this.props.ActiveCoin.coin][address.address].getbalance.data.balance : 'N/A';
}
console.log('mainAddressAmount ' + address.address, _amount);
if (_amount !== 'N/A') {
items.push(
@ -561,7 +560,7 @@ class SendCoin extends React.Component {
for (let i = 0; i < substrBlocks; i++) {
out.push(
<div key={i}>{_lastSendToResponse.substring(i * substrLength, substrLength * i + substrLength)}</div>
<div key={ i }>{ _lastSendToResponse.substring(i * substrLength, substrLength * i + substrLength) }</div>
);
}
@ -759,7 +758,7 @@ class SendCoin extends React.Component {
<input type="checkbox" checked={ this.state.sendApiType } />
<div className="slider" onClick={ this.toggleSendAPIType }></div>
</label>
<div className="toggle-label" onClick={ this.toggleSendAPIType }>{ translate('SEND.SEND_VIA') } sendtoaddress API</div>
<div className="toggle-label" onClick={ this.toggleSendAPIType }>{ translate('SEND.SEND_VIA') } (sendtoaddress API)</div>
</span>
</div>
</div>
@ -867,7 +866,7 @@ class SendCoin extends React.Component {
<strong>{ translate('INDEX.TOTAL') } ({ translate('INDEX.AMOUNT_SM') } - txfee):</strong> <span id="edexcoin_total_value">{ Number(this.state.amount) - Number(this.state.fee) }</span> { this.props.ActiveCoin.coin }
</span>
</div>
<div className="col-lg-10 margin-top-30">
<div className={ this.state.sendApiType ? 'hide' : 'col-lg-10 margin-top-30' }>
<span className="pointer">
<label className="switch">
<input type="checkbox" checked={ this.state.sendSig } />
@ -896,7 +895,7 @@ class SendCoin extends React.Component {
<div className="panel-body">
<div className="row">
<div className="col-xs-12">
<strong>{translate('INDEX.TO')}</strong>
<strong>{ translate('INDEX.TO') }</strong>
</div>
<div className="col-lg-6 col-sm-6 col-xs-12" id="mdl_confirm_currency_sendto_addr">{ this.state.sendTo }</div>
<div className="col-lg-6 col-sm-6 col-xs-6">

8
react/src/components/dashboard/walletsNativeTxInfo.js

@ -23,6 +23,12 @@ class WalletsNativeTxInfo extends React.Component {
}));
}
handleKeydown(e) {
if (e.key === 'Escape') {
this.toggleTxInfoModal();
}
}
render() {
if (this.props &&
this.props.ActiveCoin.showTransactionInfo &&
@ -31,7 +37,7 @@ class WalletsNativeTxInfo extends React.Component {
const txInfo = this.props.ActiveCoin.txhistory[this.props.ActiveCoin.showTransactionInfoTxIndex];
return (
<div>
<div onKeyDown={ (event) => this.handleKeydown(event) }>
<div className="modal show" id="kmd_txid_info_mdl" aria-hidden="false" role="dialog">
<div className="modal-dialog modal-center modal-lg">
<div className="modal-content">

18
react/src/components/toaster/toaster.js

@ -15,7 +15,9 @@ class Toaster extends React.Component {
}
componentWillReceiveProps(props) {
if (props && props.message && props.display) {
if (props &&
props.message &&
props.display) {
this.setState({
message: props.message,
display: props.display,
@ -44,11 +46,15 @@ class Toaster extends React.Component {
return (
<div className="toaster">
<div id="toast-container" className="single-toast toast-bottom-right" aria-live="polite" role="alert">
<div className={"toast toast-" + this.state.type}>
<button className="toast-close-button" role="button" onClick={this.dismissToast}>×</button>
<div className="toast-title">{this.state.title}</div>
<div className="toast-message">{this.state.message}</div>
<div
id="toast-container"
className="single-toast toast-bottom-right"
aria-live="polite"
role="alert">
<div className={ 'toast toast-' + this.state.type }>
<button className="toast-close-button" role="button" onClick={ this.dismissToast }>×</button>
<div className="toast-title">{ this.state.title }</div>
<div className="toast-message">{ this.state.message }</div>
</div>
</div>
</div>

80
react/src/styles/index.scss

@ -149,6 +149,10 @@ body {
right: 15px;
}
.page-aside {
position: fixed;
}
.page-aside-inner .wallet-widgets-list {
overflow-y: auto;
height: 100%;
@ -375,19 +379,91 @@ input:checked + .slider:before {
text-align: center;
}
.breadcrumb>li+li:before {
#section-dashboard .navbar-brand {
padding: 10px 20px;
}
.breadcrumb > li + li:before {
display: none;
}
.notifications {
.notice {
position: relative;
margin: 1em;
background: #F9F9F9;
padding: 1em 1em 1em 2em;
border-left: 4px solid #DDD;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.125);
}
.notice:before {
position: absolute;
top: 50%;
margin-top: -17px;
left: -17px;
background-color: #DDD;
color: #FFF;
width: 30px;
height: 30px;
border-radius: 100%;
text-align: center;
line-height: 30px;
font-weight: bold;
font-family: Georgia;
text-shadow: 1px 1px rgba(0, 0, 0, 0.5);
}
.info {
border-color: #0074D9;
}
.info:before {
content: 'i';
background-color: #0074D9;
}
.success {
border-color: #2ECC40;
}
.success:before {
content: '';
background-color: #2ECC40;
}
.warning {
border-color: #FFDC00;
}
.warning:before {
content: '!';
background-color: #FFDC00;
}
.error {
border-color: #FF4136;
}
.error:before {
content: 'X';
background-color: #FF4136;
}
}
.notifications-badge.stick-to-top {
top: 38px;
left: 30px;
z-index: 1500;
}
.notifications-badge {
position: absolute;
position: fixed;
bottom: 10px;
left: 5px;
cursor: pointer;
height: 20px;
z-index: 20;
.badge {
margin-left: 2px;

2
react/src/translate/en.js

@ -445,7 +445,7 @@ export const _lang = {
'WAITING': 'Waiting',
'PROCESSING_TRANSACTION': 'Processing transaction',
'NOTE_IT_WILL_TAKE': 'Note: it may take a few minutes to complete the transaction',
'SEND_VIA': 'Send via',
'SEND_VIA': 'Alternative send method',
'ENTER_AN_ADDRESS': 'Enter an address',
'YOU_PICKED_OPT': 'You picked option',
'PLEASE_WAIT': 'Please wait'

6
react/src/util/time.js

@ -1,4 +1,4 @@
export function secondsToString(seconds, skipMultiply) {
export function secondsToString(seconds, skipMultiply, showSeconds) {
var a = new Date(seconds * (skipMultiply ? 1 : 1000)),
months = [
'Jan',
@ -20,7 +20,7 @@ export function secondsToString(seconds, skipMultiply) {
hour = a.getHours() < 10 ? '0' + a.getHours() : a.getHours(),
min = a.getMinutes() < 10 ? '0' + a.getMinutes() : a.getMinutes(),
sec = a.getSeconds(),
time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min; // + ':' + sec;
time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + (showSeconds ? ':' + sec : '');
return time;
}
@ -41,6 +41,6 @@ export function secondsElapsedToString(timestamp) { // in seconds
let returnTimeVal = (hours > 0 ? hours + ' hour(s) ' : '') +
(minutes > 0 ? minutes + ' minute(s) ' : '') +
(seconds > 0 ? seconds + ' second(s) ' : '');
return returnTimeVal;
}
Loading…
Cancel
Save