Browse Source

Merge pull request #97 from pbca26/redux

Redux
all-modes
pbca26 8 years ago
committed by GitHub
parent
commit
eef417daa3
  1. 64
      react/src/actions/actionCreators.js
  2. 2
      react/src/components/addcoin/addcoinOptionsCrypto.js
  3. 2
      react/src/components/addcoin/payload.js
  4. 55
      react/src/components/dashboard/coinTileItem.js
  5. 4
      react/src/components/dashboard/walletsBalance.js
  6. 215
      react/src/components/dashboard/walletsData.js
  7. 5
      react/src/components/dashboard/walletsNativeReceive.js
  8. 2
      react/src/components/dashboard/walletsNativeSend.js
  9. 176
      react/src/components/dashboard/walletsNativeTxHistory.js
  10. 2
      react/src/components/dashboard/walletsNav.js
  11. 25
      react/src/components/dashboard/walletsProgress.js
  12. 9
      react/src/reducers/activeCoin.js
  13. 7
      react/src/styles/index.scss
  14. 2
      react/src/util/time.js

64
react/src/actions/actionCreators.js

@ -625,6 +625,42 @@ export function getPeersListState(json) {
}
}
/*params = {
'userpass': tmpIguanaRPCAuth,
'agent': 'dex',
'method': 'listtransactions',
'address': coinaddr_value,
'count': 100,
'skip': 0,
'symbol': coin
};*/
export function getFullTransactionsList(coin) {
const payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'coin': coin,
'method': 'listtransactions',
'params': [
0,
9999999,
[]
]
};
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, 'getFullTransactionsList', 'Error', 'error'));
})
.then(response => response.json())
.then(json => dispatch(getNativeTxHistoryState(json)))
}
}
export function getPeersList(coin) {
const payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
@ -772,7 +808,15 @@ export function stopInterval(name, intervals) {
}
}
// TODO: add custom json parser
function getSyncInfoState(json) {
try {
JSON.parse(json);
json = JSON.parse(json);
} catch(e) {
//
}
return {
type: SYNCING_FULL_MODE,
progress: json,
@ -798,8 +842,16 @@ export function getSyncInfo(coin) {
console.log(error);
dispatch(triggerToaster(true, 'getSyncInfo', 'Error', 'error'));
})
.then(response => response.json())
.then(json => dispatch(getSyncInfoState(json, dispatch)))
.then(function(response) {
const _response = response.text().then(function(text) { return text; });
return _response;
})
.then(function(json) {
if (json.indexOf('coin is busy processing') === -1) {
dispatch(getSyncInfoState(json, dispatch));
}
})
}
}
@ -1225,9 +1277,15 @@ export function getNativeTxHistory(coin) {
}
export function getNativeTxHistoryState(json) {
if (json && json.error) {
json = null;
} else if (json && json.result) {
json = json.result;
}
return {
type: DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY,
txhistory: json && !json.error ? json : 0,
txhistory: json,
}
}

2
react/src/components/addcoin/addcoinOptionsCrypto.js

@ -13,7 +13,7 @@ class AddCoinOptionsCrypto extends React.Component {
<option value="DGB|full">Digibyte (DGB)</option>
<option value="DOGE|full">Dogecoin (DOGE)</option>
<option value="FRK|full">Franko (FRK)</option>
<option value="GMC|full">Gamerscoin (GMC)</option>
<option value="GAME|full">Gamecredits (GAME)</option>
<option value="KMD|basilisk|native">Komodo (KMD)</option>
<option value="LTC|full">Litecoin (LTC)</option>
<option value="MZC|full">MazaCoin (MZC)</option>

2
react/src/components/addcoin/payload.js

@ -131,7 +131,7 @@ export function checkCoinType(coin) {
export function startCrypto(confpath, coin, mode) {
var tmpinternval = 0,
AddCoinData = {},
tmpPendValue,
tmpPendValue = 4, // TODO: hook up to shepherd sysinfo
tmpIguanaRPCAuth = 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth');
if (coin !== 'BTC' && coin !== 'LTC' && coin !== 'DOGE') {

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

@ -12,7 +12,8 @@ import {
getKMDBalanceTotal,
getNativeTxHistory,
getKMDAddressesNative,
getKMDOPID
getKMDOPID,
getFullTransactionsList
} from '../../actions/actionCreators';
import Store from '../../store';
@ -24,37 +25,37 @@ class CoinTileItem extends React.Component {
}
dashboardChangeActiveCoin(coin, mode) {
if (mode === 'full' && coin !== this.props.ActiveCoin.coin) {
if (coin !== this.props.ActiveCoin.coin) {
Store.dispatch(stopInterval('sync', this.props.Interval.interval));
var _iguanaActiveHandle = setInterval(function() {
Store.dispatch(getSyncInfo(coin));
Store.dispatch(iguanaEdexBalance(coin, mode));
Store.dispatch(dashboardChangeActiveCoin(coin, mode));
if (mode === 'full') {
var _iguanaActiveHandle = setInterval(function() {
Store.dispatch(getSyncInfo(coin));
Store.dispatch(iguanaEdexBalance(coin, mode));
Store.dispatch(getAddressesByAccount(coin));
Store.dispatch(getFullTransactionsList(coin));
}, 3000);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
}
if (mode === 'native') {
// TODO: add conditions to skip txhistory, balances, addresses while "activating best chain"
var _iguanaActiveHandle = setInterval(function() {
Store.dispatch(getSyncInfoNative(coin));
Store.dispatch(getKMDBalanceTotal(coin));
Store.dispatch(getNativeTxHistory(coin));
Store.dispatch(getKMDAddressesNative(coin));
Store.dispatch(getKMDOPID(null, coin));
}, coin === 'KMD' ? 15000 : 3000);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
}
if (mode === 'basilisk') {
Store.dispatch(getAddressesByAccount(coin));
}, 3000);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
} else if (mode === 'native' && coin !== this.props.ActiveCoin.coin) {
Store.dispatch(stopInterval('sync', this.props.Interval.interval));
// TODO: add conditions to skip txhistory, balances, addresses while "activating best chain"
var _iguanaActiveHandle = setInterval(function() {
Store.dispatch(getSyncInfoNative(coin));
Store.dispatch(getKMDBalanceTotal(coin));
Store.dispatch(getNativeTxHistory(coin));
Store.dispatch(getKMDAddressesNative(coin));
Store.dispatch(getKMDOPID(null, coin));
}, coin === 'KMD' ? 15000 : 3000);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
} else {
Store.dispatch(stopInterval('sync', this.props.Interval.interval));
Store.dispatch(getAddressesByAccount(coin));
// basilisk
// basilisk
}
}
Store.dispatch(dashboardChangeActiveCoin(coin, mode));
Store.dispatch(iguanaActiveHandle(true));
/*this.setState(Object.assign({}, this.state, {
activeHandleInterval: _iguanaActiveHandle,
}));*/
}
render() {

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

@ -3,7 +3,7 @@ import { translate } from '../../translate/translate';
class WalletsBalance extends React.Component {
render() {
if (this.props && this.props.coin && this.props.mode !== 'native') {
if (this.props && this.props.coin && this.props.mode !== 'native' && this.props.balance && !this.props.send && !this.props.receive) {
return (
<div id="wallet-widgets" data-plugin="masonry" data-edexcoin="COIN">
<div className="col-xs-12">
@ -37,7 +37,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 && this.props.ActiveCoin && this.props.ActiveCoin.balance ? this.props.ActiveCoin.balance : 0}</span>
<span data-edexcoin="COIN" id="edex_total_balance"></span> <span data-edexcoin="COIN" id="edex_total_balance_coincode">{this.props && this.props.balance ? this.props.balance : 0}</span>
</span>
</div>
</div>

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

@ -1,5 +1,6 @@
import React from 'react';
import { translate } from '../../translate/translate';
import { secondsToString } from '../../util/time';
import { basiliskRefresh, basiliskConnection, getDexNotaries } from '../../actions/actionCreators';
import Store from '../../store';
@ -8,7 +9,11 @@ class WalletsData extends React.Component {
super(props);
this.state = {
basiliskActionsMenu: false,
itemsPerPage: 10,
activePage: 1,
itemsList: null,
};
this.updateInput = this.updateInput.bind(this);
this.toggleBasiliskActionsMenu = this.toggleBasiliskActionsMenu.bind(this);
this.basiliskRefreshAction = this.basiliskRefreshAction.bind(this);
this.basiliskConnectionAction = this.basiliskConnectionAction.bind(this);
@ -37,8 +42,154 @@ class WalletsData extends React.Component {
Store.dispatch(getDexNotaries(this.props.ActiveCoin.coin));
}
updateInput(e) {
let historyToSplit = this.props.ActiveCoin.txhistory;
historyToSplit = historyToSplit.slice(0, e.target.value);
this.setState({
[e.target.name]: e.target.value,
activePage: 1,
itemsList: historyToSplit,
});
}
componentWillReceiveProps(props) {
if (this.props.ActiveCoin.txhistory && 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 = this.props.ActiveCoin.txhistory;
historyToSplit = historyToSplit.slice((this.state.activePage - 1) * this.state.itemsPerPage, this.state.activePage * this.state.itemsPerPage);
this.setState(Object.assign({}, this.state, {
itemsList: historyToSplit,
}));
}
}
}
updateCurrentPage(page) {
let historyToSplit = this.props.ActiveCoin.txhistory;
historyToSplit = historyToSplit.slice((page - 1) * this.state.itemsPerPage, page * this.state.itemsPerPage);
this.setState(Object.assign({}, this.state, {
activePage: page,
itemsList: historyToSplit,
}));
}
renderPaginationItems() {
let items = [];
for (let i=0; i <= Math.floor(this.props.ActiveCoin.txhistory.length / this.state.itemsPerPage); i++) {
items.push(
<li className={this.state.activePage === i + 1 ? 'paginate_button active' : 'paginate_button'}>
<a aria-controls="kmd-tx-history-tbl" data-dt-idx="1" tabIndex="0" key={i + '-pagination'} onClick={this.state.activePage !== (i + 1) ? () => this.updateCurrentPage(i + 1) : null}>{i + 1}</a>
</li>
);
}
return items;
}
renderPaginationItemsPerPageSelector() {
if (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory.length > 10) {
return (
<div className="dataTables_length" id="kmd-tx-history-tbl_length">
<label>
Show&nbsp;
<select name="itemsPerPage" aria-controls="kmd-tx-history-tbl" className="form-control input-sm" onChange={this.updateInput}>
<option value="1">10</option>
<option value="2">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>&nbsp;
entries
</label>
</div>
);
} else {
return null;
}
}
renderPagination() {
if (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory.length > 10) {
return (
<div className="row unselectable">
<div className="col-sm-5">
<div className="dataTables_info" id="kmd-tx-history-tbl_info" role="status" aria-live="polite">Showing {((this.state.activePage - 1) * this.state.itemsPerPage) + 1} to {this.state.activePage * this.state.itemsPerPage} of {this.props.ActiveCoin.txhistory.length} entries</div>
</div>
<div className="col-sm-7">
<div className="dataTables_paginate paging_simple_numbers" id="kmd-tx-history-tbl_paginate">
<ul className="pagination">
<li className={this.state.activePage === 1 ? 'paginate_button previous disabled' : 'paginate_button previous'} id="kmd-tx-history-tbl_previous">
<a aria-controls="kmd-tx-history-tbl" data-dt-idx="0" tabIndex="0" onClick={() => this.updateCurrentPage(this.state.activePage - 1)}>Previous</a>
</li>
{this.renderPaginationItems()}
<li className={this.state.activePage === Math.floor(this.props.ActiveCoin.txhistory.length / this.state.itemsPerPage) ? 'paginate_button next disabled' : 'paginate_button next'} id="kmd-tx-history-tbl_next">
<a aria-controls="kmd-tx-history-tbl" data-dt-idx="2" tabIndex="0" onClick={() => this.updateCurrentPage(this.state.activePage + 1)}>Next</a>
</li>
</ul>
</div>
</div>
</div>
);
} else {
return null;
}
}
renderTxType(category) {
if ( category === 'send' ) {
return (
<span>
<i className="icon fa-arrow-circle-left"></i> <span>{translate('DASHBOARD.OUT')}</span>
</span>
);
}
if ( category === 'receive' ) {
return (
<span>
<i className="icon fa-arrow-circle-right"></i> <span>{translate('DASHBOARD.IN')}</span>
</span>
);
}
if ( category === 'generate' ) {
return (
<span>
<i className="icon fa-cogs"></i> <span>{translate('DASHBOARD.MINED')}</span>
</span>
);
}
if ( category === 'immature' ) {
return (
<span>
<i className="icon fa-clock-o"></i> <span>{translate('DASHBOARD.IMMATURE')}</span>
</span>
);
}
}
renderTxHistoryList() {
if (this.state.itemsList && this.state.itemsList.length) {
return this.state.itemsList.map((tx, index) =>
<tr key={tx.txid + tx.amount}>
<td>{this.renderTxType(tx.category)}</td>
<td>{tx.confirmations}</td>
<td>{tx.amount}</td>
<td>{secondsToString(tx.blocktime)}</td>
<td>{tx.address}</td>
<td>
<button type="button" className="btn btn-xs white btn-info waves-effect waves-light btn-kmdtxid" onClick={() => this.toggleTxInfoModal(!this.props.ActiveCoin.showTransactionInfo, index)}><i className="icon fa-search"></i></button>
</td>
</tr>
);
} else {
return null;
}
}
render() {
if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.coin && this.props.ActiveCoin.mode !== 'native') {
if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.coin && this.props.ActiveCoin.mode !== 'native' && !this.props.ActiveCoin.send && !this.props.ActiveCoin.receive) {
return (
<div data-edexcoin="COIN" id="edexcoin_dashboardinfo">
<div className="col-xs-12 margin-top-20">
@ -84,28 +235,46 @@ class WalletsData extends React.Component {
<h4 className="panel-title">{translate('INDEX.TRANSACTION_HISTORY')}</h4>
</header>
<div className="panel-body">
<table className="table table-hover dataTable table-striped" data-edexcoin="COIN" id="edex-tx-history-tbl" width="100%">
<thead>
<tr>
<th>{translate('INDEX.DIRECTION')}</th>
<th className="hidden-xs hidden-sm">{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th className="hidden-xs hidden-sm">{translate('INDEX.TX_DETAIL')}</th>
</tr>
</thead>
<tfoot>
<tr>
<th>{translate('INDEX.DIRECTION')}</th>
<th>{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th className="hidden-xs hidden-sm">{translate('INDEX.TX_DETAIL')}</th>
</tr>
</tfoot>
</table>
<div className="row">
<div className="col-sm-6">
{this.renderPaginationItemsPerPageSelector()}
</div>
<div className="col-sm-6">
<div id="kmd-tx-history-tbl_filter" className="dataTables_filter">
<label>
Search: <input type="search" className="form-control input-sm" placeholder="" aria-controls="kmd-tx-history-tbl" disabled="true" />
</label>
</div>
</div>
</div>
<div className="row">
<table className="table table-hover dataTable table-striped" data-edexcoin="COIN" id="edex-tx-history-tbl" width="100%">
<thead>
<tr>
<th>{translate('INDEX.DIRECTION')}</th>
<th className="hidden-xs hidden-sm">{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th className="hidden-xs hidden-sm">{translate('INDEX.TX_DETAIL')}</th>
</tr>
</thead>
<tbody>
{this.renderTxHistoryList()}
</tbody>
<tfoot>
<tr>
<th>{translate('INDEX.DIRECTION')}</th>
<th>{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th className="hidden-xs hidden-sm">{translate('INDEX.TX_DETAIL')}</th>
</tr>
</tfoot>
</table>
</div>
{this.renderPagination()}
</div>
</div>
</div>

5
react/src/components/dashboard/walletsNativeReceive.js

@ -3,7 +3,7 @@ import { translate } from '../../translate/translate';
import { getNewKMDAddresses, copyCoinAddress } from '../../actions/actionCreators';
import Store from '../../store';
// TODO: add addr balance
// TODO: importaddress, importprivkey(?)
class WalletsNativeReceive extends React.Component {
constructor(props) {
@ -25,8 +25,7 @@ class WalletsNativeReceive extends React.Component {
}
renderAddressList(type) {
console.log(this.props.ActiveCoin.addresses[type]);
if (this.props.ActiveCoin.addresses[type] && this.props.ActiveCoin.addresses[type].length) {
if (this.props.ActiveCoin.addresses && this.props.ActiveCoin.addresses[type] && this.props.ActiveCoin.addresses[type].length) {
return this.props.ActiveCoin.addresses[type].map((address) =>
<tr key={address.address}>
<td>

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

@ -22,7 +22,7 @@ class WalletsNativeSend extends React.Component {
}
renderAddressByType(type) {
if (this.props.ActiveCoin.addresses[type] && this.props.ActiveCoin.addresses[type].length) {
if (this.props.ActiveCoin.addresses && this.props.ActiveCoin.addresses[type] && this.props.ActiveCoin.addresses[type].length) {
return this.props.ActiveCoin.addresses[type].map((address) =>
<li data-original-index="2" key={address.address} className={address.amount <= 0 ? 'hide' : ''}>
<a tabIndex="0" data-tokens="null" onClick={() => this.updateAddressSelection(address.address, type, address.amount)}><i className={type === 'public' ? 'icon fa-eye' : 'icon fa-eye-slash'}></i> <span className="text">[ {address.amount} {this.props.ActiveCoin.coin} ] {address.address}</span><span className="glyphicon glyphicon-ok check-mark"></span></a>

176
react/src/components/dashboard/walletsNativeTxHistory.js

@ -7,9 +7,16 @@ import Store from '../../store';
class WalletsNativeTxHistory extends React.Component {
constructor(props) {
super(props);
this.state = {
itemsPerPage: 10,
activePage: 1,
itemsList: null,
};
this.updateInput = this.updateInput.bind(this);
}
// TODO: implement sorting and pagination
// TODO: implement sorting
// implement pagination past X items should call listtransactions to get new chunk of data
// z transactions
// filter based on addr
@ -17,6 +24,17 @@ class WalletsNativeTxHistory extends React.Component {
Store.dispatch(toggleDashboardTxInfoModal(display, txIndex));
}
updateInput(e) {
let historyToSplit = this.props.ActiveCoin.txhistory;
historyToSplit = historyToSplit.slice(0, e.target.value);
this.setState({
[e.target.name]: e.target.value,
activePage: 1,
itemsList: historyToSplit,
});
}
renderTxType(category) {
if ( category === 'send' ) {
return (
@ -60,9 +78,92 @@ class WalletsNativeTxHistory extends React.Component {
}
}
componentWillReceiveProps(props) {
if (!this.state.itemsList || (this.state.itemsList && !this.state.itemsList.length) || (props.ActiveCoin.txhistory !== this.props.ActiveCoin.txhistory)) {
let historyToSplit = this.props.ActiveCoin.txhistory;
historyToSplit = historyToSplit.slice((this.state.activePage - 1) * this.state.itemsPerPage, this.state.activePage * this.state.itemsPerPage);
this.setState(Object.assign({}, this.state, {
itemsList: historyToSplit,
}));
}
}
updateCurrentPage(page) {
let historyToSplit = this.props.ActiveCoin.txhistory;
historyToSplit = historyToSplit.slice((page - 1) * this.state.itemsPerPage, page * this.state.itemsPerPage);
this.setState(Object.assign({}, this.state, {
activePage: page,
itemsList: historyToSplit,
}));
}
renderPaginationItems() {
let items = [];
for (let i=0; i <= Math.floor(this.props.ActiveCoin.txhistory.length / this.state.itemsPerPage); i++) {
items.push(
<li className={this.state.activePage === i + 1 ? 'paginate_button active' : 'paginate_button'}>
<a aria-controls="kmd-tx-history-tbl" data-dt-idx="1" tabIndex="0" key={i + '-pagination'} onClick={this.state.activePage !== (i + 1) ? () => this.updateCurrentPage(i + 1) : null}>{i + 1}</a>
</li>
);
}
return items;
}
renderPaginationItemsPerPageSelector() {
if (this.props.ActiveCoin.txhistory.length > 10) {
return (
<div className="dataTables_length" id="kmd-tx-history-tbl_length">
<label>
Show&nbsp;
<select name="itemsPerPage" aria-controls="kmd-tx-history-tbl" className="form-control input-sm" onChange={this.updateInput}>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>&nbsp;
entries
</label>
</div>
);
} else {
return null;
}
}
renderPagination() {
if (this.props.ActiveCoin.txhistory.length > 10) {
return (
<div className="row unselectable">
<div className="col-sm-5">
<div className="dataTables_info" id="kmd-tx-history-tbl_info" role="status" aria-live="polite">Showing {((this.state.activePage - 1) * this.state.itemsPerPage) + 1} to {this.state.activePage * this.state.itemsPerPage} of {this.props.ActiveCoin.txhistory.length} entries</div>
</div>
<div className="col-sm-7">
<div className="dataTables_paginate paging_simple_numbers" id="kmd-tx-history-tbl_paginate">
<ul className="pagination">
<li className={this.state.activePage === 1 ? 'paginate_button previous disabled' : 'paginate_button previous'} id="kmd-tx-history-tbl_previous">
<a aria-controls="kmd-tx-history-tbl" data-dt-idx="0" tabIndex="0" onClick={() => this.updateCurrentPage(this.state.activePage - 1)}>Previous</a>
</li>
{this.renderPaginationItems()}
<li className={this.state.activePage === Math.floor(this.props.ActiveCoin.txhistory.length / this.state.itemsPerPage) ? 'paginate_button next disabled' : 'paginate_button next'} id="kmd-tx-history-tbl_next">
<a aria-controls="kmd-tx-history-tbl" data-dt-idx="2" tabIndex="0" onClick={() => this.updateCurrentPage(this.state.activePage + 1)}>Next</a>
</li>
</ul>
</div>
</div>
</div>
);
} else {
return null;
}
}
renderTxHistoryList() {
if (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory.length && this.props.ActiveCoin.nativeActiveSection === 'default') {
return this.props.ActiveCoin.txhistory.map((tx, index) =>
if (this.state.itemsList && this.state.itemsList.length && this.props.ActiveCoin.nativeActiveSection === 'default') {
return this.state.itemsList.map((tx, index) =>
<tr key={tx.txid + tx.amount}>
<td>
<span className="label label-default">
@ -98,33 +199,48 @@ class WalletsNativeTxHistory extends React.Component {
<h3 className="panel-title">{translate('INDEX.TRANSACTION_HISTORY')}</h3>
</header>
<div className="panel-body">
<table className="table table-hover dataTable table-striped" data-extcoin="COIN" id="kmd-tx-history-tbl" width="100%">
<thead>
<tr>
<th>{translate('INDEX.TYPE')}</th>
<th>{translate('INDEX.DIRECTION')}</th>
<th>{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th>{translate('INDEX.TX_DETAIL')}</th>
</tr>
</thead>
<tbody>
{this.renderTxHistoryList()}
</tbody>
<tfoot>
<tr>
<th>{translate('INDEX.TYPE')}</th>
<th>{translate('INDEX.DIRECTION')}</th>
<th>{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th>{translate('INDEX.TX_DETAIL')}</th>
</tr>
</tfoot>
</table>
<div className="row">
<div className="col-sm-6">
{this.renderPaginationItemsPerPageSelector()}
</div>
<div className="col-sm-6">
<div id="kmd-tx-history-tbl_filter" className="dataTables_filter">
<label>
Search: <input type="search" className="form-control input-sm" placeholder="" aria-controls="kmd-tx-history-tbl" disabled="true" />
</label>
</div>
</div>
</div>
<div className="row">
<table className="table table-hover dataTable table-striped" data-extcoin="COIN" id="kmd-tx-history-tbl" width="100%">
<thead>
<tr>
<th>{translate('INDEX.TYPE')}</th>
<th>{translate('INDEX.DIRECTION')}</th>
<th>{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th>{translate('INDEX.TX_DETAIL')}</th>
</tr>
</thead>
<tbody>
{this.renderTxHistoryList()}
</tbody>
<tfoot>
<tr>
<th>{translate('INDEX.TYPE')}</th>
<th>{translate('INDEX.DIRECTION')}</th>
<th>{translate('INDEX.CONFIRMATIONS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
<th>{translate('INDEX.TIME')}</th>
<th>{translate('INDEX.DEST_ADDRESS')}</th>
<th>{translate('INDEX.TX_DETAIL')}</th>
</tr>
</tfoot>
</table>
</div>
{this.renderPagination()}
</div>
</div>
</div>

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

@ -67,7 +67,7 @@ class WalletsNav extends React.Component {
} else {
return (
<div>
<div className="page-header page-header-bordered header-easydex" id="header-dashboard" data-edexcoin="COIN" style={{paddingBottom: '20px', marginBottom: this.props.ActiveCoin.mode === 'native' ? '0' : '30px'}}>
<div className="page-header page-header-bordered header-easydex" id="header-dashboard" data-edexcoin="COIN" style={{paddingBottom: '20px', marginBottom: this.props.ActiveCoin.mode !== 'basilisk' && this.props.Dashboard.progress ? '0' : '30px'}}>
<ol className="breadcrumb" data-edexcoin="COIN">
<b>{translate('INDEX.MY')} <span data-edexcoin="COIN" id="edexcoin-active">{this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-'}</span> {translate('INDEX.ADDRESS')}: </b> <span data-edexcoin="COIN" id="edexcoin_active_addr">{this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-'}</span> <button className="btn btn-default btn-xs clipboard-edexaddr" data-edexcoin="COIN" id="edexcoin_active_addr_clipboard" data-clipboard-text="" onClick={() => this.copyMyAddress(this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin])}><i className="icon wb-copy" aria-hidden="true"></i> {translate('INDEX.COPY')}</button>
</ol>

25
react/src/components/dashboard/walletsProgress.js

@ -2,22 +2,41 @@ import React from 'react';
import { translate } from '../../translate/translate';
class WalletsProgress extends React.Component {
constructor(props) {
super(props);
this.isFullySynced = this.isFullySynced.bind(this);
}
isFullySynced() {
if ((Number(this.props.Dashboard.progress.balances) +
Number(this.props.Dashboard.progress.validated) +
Number(this.props.Dashboard.progress.bundles) +
Number(this.props.Dashboard.progress.utxo)) / 4 === 100) {
return true;
} else {
return false;
}
}
render() {
if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.mode === 'full' && this.props.Dashboard.progress) {
if (this.props.Dashboard.progress && this.props.Dashboard.progress.error) {
return (<div style={{textAlign: 'center', padding: '10px'}}>Coin is busy processing</div>);
} else {
return (
<div id="edex-footer" data-edexcoin="COIN">
<div id="edex-footer" data-edexcoin="COIN" style={{marginBottom: '20px'}}>
<div className="row no-space" data-edexcoin="COIN">
<div data-edexcoin="COIN" id="currency-progressbars">
<div className="progress progress-sm">
<div className="progress-bar progress-bar-info progress-bar-striped active" style={{width: this.props.Dashboard.progress.bundles + '%', fontSize: '80%'}} role="progressbar" data-edexcoin="COIN" id="currency-bundles">
<div className={this.isFullySynced() ? 'progress-bar progress-bar-striped active progress-bar-indicating progress-bar-success' : 'hide'} style={{width: '100%', fontSize: '80%'}} role="progressbar" data-edexcoin="GAME" id="currency-bundles">
{translate('INDEX.BUNDLES')} <span data-edexcoin="GAME" id="currency-bundles-percent">({this.props.ActiveCoin.coin}) 100.00% - ( {this.props.Dashboard.progress.blocks} / {this.props.Dashboard.progress.blocks} ) ==&gt;&gt; RT{this.props.Dashboard.progress.RTheight}</span>
</div>
<div className={this.isFullySynced() ? 'hide' : 'progress-bar progress-bar-info progress-bar-striped active'} style={{width: this.props.Dashboard.progress.bundles + '%', fontSize: '80%'}} role="progressbar" data-edexcoin="COIN" id="currency-bundles">
{translate('INDEX.BUNDLES')} <span data-edexcoin="COIN" id="currency-bundles-percent">{this.props.Dashboard.progress.bundles}%</span>
</div>
</div>
</div>
<div data-edexcoin="COIN" id="additional-progress-bars">
<div data-edexcoin="COIN" id="additional-progress-bars" className={this.isFullySynced() ? 'hide' : ''}>
<div className="progress progress-sm">
<div className="progress-bar progress-bar-warning progress-bar-striped active" style={{width: this.props.Dashboard.progress.utxo + '%', fontSize: '80%'}} role="progressbar" data-edexcoin="COIN" id="currency-utxo">
utxo <span data-edexcoin="COIN" id="currency-utxo-percent">{this.props.Dashboard.progress.utxo}%</span>

9
react/src/reducers/activeCoin.js

@ -12,6 +12,8 @@ import {
DASHBOARD_ACTIVE_COIN_NATIVE_OPIDS
} from '../actions/actionCreators';
// TODO: keep all coin data in array of objects instead of single object
export function ActiveCoin(state = {
coin: null,
mode: null,
@ -29,6 +31,13 @@ export function ActiveCoin(state = {
return Object.assign({}, state, {
coin: action.coin,
mode: action.mode,
balance: 0,
txhistory: [],
send: false,
receive: false,
showTransactionInfo: false,
showTransactionInfoTxIndex: null,
nativeActiveSection: 'default',
});
case DASHBOARD_ACTIVE_COIN_BALANCE:
return Object.assign({}, state, {

7
react/src/styles/index.scss

@ -78,7 +78,8 @@ body {
#edexcoin_dashboardinfo a,
.nav-top-menu,
#kmd_txid_info_mdl .nav-tabs li {
#kmd_txid_info_mdl .nav-tabs li,
.pagination a {
cursor: pointer;
cursor: hand;
}
@ -88,6 +89,10 @@ body {
background-size: 100%;
}
.unselectable {
user-select: none;
}
/*.toaster .single-toast:nth-child(0) {
bottom: 12px;
}

2
react/src/util/time.js

@ -20,7 +20,7 @@ export function secondsToString(seconds) {
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; // + ':' + sec;
return time;
}
Loading…
Cancel
Save