Browse Source

Merge pull request #96 from pbca26/redux

Redux
all-modes
pbca26 8 years ago
committed by GitHub
parent
commit
6f570b92f2
  1. BIN
      react/build.zip
  2. 394
      react/src/actions/actionCreators.js
  3. BIN
      react/src/assets/images/cryptologo/GAME.png
  4. 8
      react/src/components/dashboard/coinTileItem.js
  5. 40
      react/src/components/dashboard/walletsNativeReceive.js
  6. 198
      react/src/components/dashboard/walletsNativeSend.js
  7. 4
      react/src/components/dashboard/walletsNativeTxHistory.js
  8. 8
      react/src/reducers/activeCoin.js
  9. 4
      react/src/util/time.js

BIN
react/build.zip

Binary file not shown.

394
react/src/actions/actionCreators.js

@ -39,6 +39,7 @@ export const DASHBOARD_ACTIVE_SECTION = 'DASHBOARD_ACTIVE_SECTION';
export const DASHBOARD_ACTIVE_TXINFO_MODAL = 'DASHBOARD_ACTIVE_TXINFO_MODAL';
export const DASHBOARD_ACTIVE_COIN_NATIVE_BALANCE = 'DASHBOARD_ACTIVE_COIN_NATIVE_BALANCE';
export const DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY = 'DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY';
export const DASHBOARD_ACTIVE_COIN_NATIVE_OPIDS = 'DASHBOARD_ACTIVE_COIN_NATIVE_OPIDS';
export function toggleDashboardActiveSection(name) {
return {
@ -48,8 +49,6 @@ export function toggleDashboardActiveSection(name) {
}
export function toggleDashboardTxInfoModal(display, txIndex) {
console.log('toggleTxInfoModal', txIndex);
return {
type: DASHBOARD_ACTIVE_TXINFO_MODAL,
showTransactionInfo: display,
@ -811,89 +810,146 @@ function getKMDAddressesNativeState(json) {
}
}
export function getKMDAddressesNative(coin, pubpriv) {
var payload,
ajax_data_to_hex = '',
ajax_function_input = '',
tmplistaddr_hex_input = '',
passthru_agent = getPassthruAgent(coin),
tmpIguanaRPCAuth = 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth');
if ( pubpriv === 'public' ) {
ajax_function_input = 'getaddressesbyaccount';
tmplistaddr_hex_input = '222200';
}
if ( pubpriv === 'private' ) {
ajax_function_input = 'z_listaddresses';
tmplistaddr_hex_input = '';
}
if (passthru_agent === 'iguana') {
payload = {
'userpass': tmpIguanaRPCAuth,
'agent': passthru_agent,
'method': 'passthru',
'asset': coin,
'function': ajax_function_input,
'hex': tmplistaddr_hex_input
};
} else {
payload = {
'userpass': tmpIguanaRPCAuth,
'agent': passthru_agent,
'method': 'passthru',
'function': ajax_function_input,
'hex': tmplistaddr_hex_input
};
}
export function getKMDAddressesNative(coin) {
const type = ['public', 'private'];
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, 'getKMDAddressesNative', 'Error', 'error'));
Promise.all(type.map((_type, index) => {
return new Promise((resolve, reject) => {
var payload,
ajax_data_to_hex = '',
ajax_function_input = '',
tmplistaddr_hex_input = '',
passthru_agent = getPassthruAgent(coin),
tmpIguanaRPCAuth = 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth');
if ( _type === 'public' ) {
ajax_function_input = 'getaddressesbyaccount';
tmplistaddr_hex_input = '222200';
}
if ( _type === 'private' ) {
ajax_function_input = 'z_listaddresses';
tmplistaddr_hex_input = '';
}
if (passthru_agent === 'iguana') {
payload = {
'userpass': tmpIguanaRPCAuth,
'agent': passthru_agent,
'method': 'passthru',
'asset': coin,
'function': ajax_function_input,
'hex': tmplistaddr_hex_input
};
} else {
payload = {
'userpass': tmpIguanaRPCAuth,
'agent': passthru_agent,
'method': 'passthru',
'function': ajax_function_input,
'hex': tmplistaddr_hex_input
};
}
fetch('http://127.0.0.1:' + Config.iguanaCorePort, {
method: 'POST',
body: JSON.stringify(payload),
})
.catch(function(error) {
console.log(error);
dispatch(triggerToaster(true, 'getKMDAddressesNative', 'Error', 'error'));
})
.then(response => response.json())
.then(json => resolve(json))
});
}))
.then(result => {
// TODO: split into 2 functions
const passthru_agent = getPassthruAgent(coin),
tmpIguanaRPCAuth = 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth');
var payload;
if (passthru_agent == 'iguana') {
payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': passthru_agent,
'method': 'passthru',
'asset': coin,
'function': 'listunspent',
'hex': ''
};
} else {
payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': passthru_agent,
'method': 'passthru',
'function': 'listunspent',
'hex': ''
};
}
fetch('http://127.0.0.1:' + Config.iguanaCorePort, {
method: 'POST',
body: JSON.stringify(payload),
})
.catch(function(error) {
console.log(error);
dispatch(triggerToaster(true, 'getKMDAddressesNative+Balance', 'Error', 'error'));
})
.then(response => response.json())
.then(function(json) {
const allAddrArray = json.map(res => res.address).filter((x, i, a) => a.indexOf(x) == i);
for (let a=0; a < allAddrArray.length; a++) {
const filteredArray = json.filter(res => res.address === allAddrArray[a]).map(res => res.amount);
let isNewAddr = true;
for (let x=0; x < 2 && isNewAddr; x++) {
for (let y=0; y < result[x].length && isNewAddr; y++) {
if (allAddrArray[a] === result[x][y]) {
isNewAddr = false;
}
}
}
if (isNewAddr) {
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];
}
console.log('new addr ' + allAddrArray[a] + ' | ' + allAddrArray[a].substring(0, 2));
}
}
let newAddressArray = [];
for (let a=0; a < 2; a++) {
newAddressArray[a] = [];
for (let b=0; b < result[a].length; b++) {
const filteredArray = json.filter(res => res.address === result[a][b]).map(res => res.amount);
let sum = 0;
for (let i=0; i < filteredArray.length; i++) {
sum += filteredArray[i];
}
newAddressArray[a][b] = {
address: result[a][b],
amount: sum,
};
}
}
dispatch(getKMDAddressesNativeState({
'public': newAddressArray[0],
'private': newAddressArray[1]
}));
})
})
.then(response => response.json())
.then(json => dispatch(getKMDAddressesNativeState(json, dispatch)))
}
}
/*function KMDListAddresses(pubpriv) {
NProgress.done(true);
NProgress.configure({
template: templates.nprogressBar
});
NProgress.start();
$.ajax({
async: false,
type: 'POST',
data: JSON.stringify(ajax_data),
url: 'http://127.0.0.1:' + config.iguanaPort,
success: function(data, textStatus, jqXHR) {
var AjaxOutputData = JSON.parse(data); // Ajax output gets the whole list of unspent coin with addresses
result = AjaxOutputData;
},
error: function(xhr, textStatus, error) {
console.log('failed getting Coin History.');
console.log(xhr.statusText);
if ( xhr.readyState == 0 ) {
Iguana_ServiceUnavailable();
}
console.log(textStatus);
console.log(error);
}
});
NProgress.done();
return result;
}*/
function getDebugLogState(json) {
const _data = json.result.replace('\n', '\r\n');
@ -1175,6 +1231,186 @@ export function getNativeTxHistoryState(json) {
}
}
function handleGetNewKMDAddresses(pubpriv, coin, dispatch) {
dispatch(triggerToaster(true, translate('KMD_NATIVE.NEW_ADDR_GENERATED'), translate('TOASTR.WALLET_NOTIFICATION'), 'success'));
dispatch(getKMDAddressesNative(coin));
return {};
}
export function getNewKMDAddresses(coin, pubpriv) {
var payload,
ajax_function_input = '';
if ( pubpriv === 'public' ) {
ajax_function_input = 'getnewaddress';
}
if ( pubpriv === 'private' ) {
ajax_function_input = 'z_getnewaddress';
}
if (getPassthruAgent(coin) === 'iguana') {
payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': getPassthruAgent(coin),
'method': 'passthru',
'asset': coin,
'function': ajax_function_input,
'hex': ''
};
} else {
payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': coin,
'method': 'passthru',
'function': ajax_function_input,
'hex': ''
};
}
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, 'getNewKMDAddresses', 'Error', 'error'));
})
.then(response => response.json())
.then(json => dispatch(handleGetNewKMDAddresses(pubpriv, coin, dispatch)))
.catch(function(ex) {
dispatch(handleGetNewKMDAddresses(pubpriv, coin, dispatch))
})
}
}
export function iguanaHashHex(data) {
const payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': 'hash',
'method': 'hex',
'message': data
};
return new Promise((resolve, reject) => {
fetch('http://127.0.0.1:' + Config.iguanaCorePort, {
method: 'POST',
body: JSON.stringify(payload),
})
.catch(function(error) {
console.log(error);
dispatch(triggerToaster(true, 'iguanaHashHex', 'Error', 'error'));
})
.then(response => response.json())
.then(json => resolve(json.hex))
})
}
export function sendNativeTx(coin, _payload) {
const ajax_data_to_hex = '["' + _payload.sendFrom + '",[{"address":"' + _payload.sendTo + '","amount":' + (Number(_payload.amount) - Number(_payload.fee)) + '}]]';
var payload;
return dispatch => {
return iguanaHashHex(ajax_data_to_hex).then((hashHexJson) => {
console.log('sendNativeTx', hashHexJson);
if (getPassthruAgent(coin) == 'iguana') {
payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': getPassthruAgent(coin),
'method': 'passthru',
'asset': coin,
'function': 'z_sendmany',
'hex': hashHexJson
};
} else {
payload = {
'userpass': 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'),
'agent': getPassthruAgent(coin),
'method': 'passthru',
'function': 'z_sendmany',
'hex': hashHexJson
};
}
fetch('http://127.0.0.1:' + Config.iguanaCorePort, {
method: 'POST',
body: JSON.stringify(payload),
})
.catch(function(error) {
console.log(error);
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')))
.catch(function(ex) {
dispatch(triggerToaster(true, translate('TOASTR.TX_SENT_ALT'), translate('TOASTR.WALLET_NOTIFICATION'), 'success'));
console.log('parsing failed', ex);
})
});
}
}
export function getKMDOPIDState(json) {
return {
type: DASHBOARD_ACTIVE_COIN_NATIVE_OPIDS,
opids: json,
}
}
export function getKMDOPID(opid, coin) {
var tmpopid_output = '',
ajax_data_to_hex;
if ( opid === undefined ) {
ajax_data_to_hex = null;
} else {
ajax_data_to_hex = '["' + opid + '"]';
}
return dispatch => {
return iguanaHashHex(ajax_data_to_hex).then((hashHexJson) => {
if (hashHexJson === '5b226e756c6c225d00') {
hashHexJson = '';
}
var payload,
passthru_agent = getPassthruAgent(coin),
tmpIguanaRPCAuth = 'tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth');
if (passthru_agent == 'iguana') {
payload = {
'userpass': tmpIguanaRPCAuth,
'agent': passthru_agent,
'method': 'passthru',
'asset': coin,
'function': 'z_getoperationstatus',
'hex': hashHexJson
};
} else {
payload = {
'userpass': tmpIguanaRPCAuth,
'agent': passthru_agent,
'method': 'passthru',
'function': 'z_getoperationstatus',
'hex': hashHexJson
};
}
fetch('http://127.0.0.1:' + Config.iguanaCorePort, {
method: 'POST',
body: JSON.stringify(payload),
})
.catch(function(error) {
console.log(error);
dispatch(triggerToaster(true, 'getKMDOPID', 'Error', 'error'));
})
.then(response => response.json())
.then(json => dispatch(getKMDOPIDState(json)))
})
}
}
/*function Shepherd_SendPendValue() {
Shepherd_SysInfo().then(function(result){
var ram_data = formatBytes(result.totalmem_bytes)

BIN
react/src/assets/images/cryptologo/GAME.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

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

@ -11,7 +11,8 @@ import {
getSyncInfoNative,
getKMDBalanceTotal,
getNativeTxHistory,
getKMDAddressesNative
getKMDAddressesNative,
getKMDOPID
} from '../../actions/actionCreators';
import Store from '../../store';
@ -38,7 +39,8 @@ class CoinTileItem extends React.Component {
Store.dispatch(getSyncInfoNative(coin));
Store.dispatch(getKMDBalanceTotal(coin));
Store.dispatch(getNativeTxHistory(coin));
Store.dispatch(getKMDAddressesNative(coin, 'public'));
Store.dispatch(getKMDAddressesNative(coin));
Store.dispatch(getKMDOPID(null, coin));
}, coin === 'KMD' ? 15000 : 3000);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
} else {
@ -66,7 +68,7 @@ class CoinTileItem extends React.Component {
<img className="img-responsive" src={'assets/images/cryptologo/' + item.coinlogo + '.png'} alt="{item.coinname}"/>
<span className={'badge up badge-' + item.modecolor} id="basfull" data-edexcoincode="{item.coin}" data-toggle="tooltip" data-placement="top" data-original-title="{item.modetip}">{item.modecode}</span>
</a>
<div className="coin-name">{item.coinname} ({item.coinlogo})</div>
<div className="coin-name">{item.coinname} ({item.coinlogo.toUpperCase()})</div>
</div>
</div>
</div>

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

@ -1,5 +1,9 @@
import React from 'react';
import { translate } from '../../translate/translate';
import { getNewKMDAddresses, copyCoinAddress } from '../../actions/actionCreators';
import Store from '../../store';
// TODO: add addr balance
class WalletsNativeReceive extends React.Component {
constructor(props) {
@ -16,17 +20,24 @@ class WalletsNativeReceive extends React.Component {
}));
}
renderAddressList() {
if (this.props.ActiveCoin.addresses && this.props.ActiveCoin.addresses.length) {
return this.props.ActiveCoin.addresses.map((address) =>
<tr key={address}>
copyZAddress(address) {
Store.dispatch(copyCoinAddress(address));
}
renderAddressList(type) {
console.log(this.props.ActiveCoin.addresses[type]);
if (this.props.ActiveCoin.addresses[type] && this.props.ActiveCoin.addresses[type].length) {
return this.props.ActiveCoin.addresses[type].map((address) =>
<tr key={address.address}>
<td>
<span className="label label-default">
<i className="icon fa-eye"></i> {translate('IAPI.PUBLIC_SM')}
<span className={type === 'public' ? 'label label-default' : 'label label-dark'}>
<i className={type === 'public' ? 'icon fa-eye' : 'icon fa-eye-slash'}></i> {type === 'public' ? translate('IAPI.PUBLIC_SM') : translate('KMD_NATIVE.PRIVATE')}
</span>
&nbsp;&nbsp;
<button className="btn btn-default btn-xs clipboard-edexaddr" data-edexcoin="COIN" id="edexcoin_active_addr_clipboard" data-clipboard-text="" onClick={() => this.copyZAddress(address.address)}><i className="icon wb-copy" aria-hidden="true"></i> {translate('INDEX.COPY')}</button>
</td>
<td>{address}</td>
<td></td>
<td>{type === 'public' ? address.address : address.address.substring(0, 34) + '...'}</td>
<td>{address.amount}</td>
<td></td>
</tr>
);
@ -35,6 +46,10 @@ class WalletsNativeReceive extends React.Component {
}
}
getNewAddress(type) {
Store.dispatch(getNewKMDAddresses(this.props.ActiveCoin.coin, type));
}
render() {
if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.nativeActiveSection === 'receive') {
return (
@ -52,12 +67,12 @@ class WalletsNativeReceive extends React.Component {
</a>
<ul className="dropdown-menu dropdown-menu-right" aria-labelledby="GetNewRecievingAddress" role="menu">
<li role="presentation">
<a href="javascript:void(0)" data-extcoin="COIN" id="kmd_get_new_taddr" role="menuitem">
<a href="javascript:void(0)" data-extcoin="COIN" id="kmd_get_new_taddr" role="menuitem" onClick={() => this.getNewAddress('public')}>
<i className="icon fa-eye" aria-hidden="true"></i> {translate('INDEX.TRANSPARENT_ADDRESS')}
</a>
</li>
<li data-extcoin="COIN" role="presentation">
<a href="javascript:void(0)" data-extcoin="COIN" id="kmd_get_new_zaddr" role="menuitem">
<a href="javascript:void(0)" data-extcoin="COIN" id="kmd_get_new_zaddr" role="menuitem" onClick={() => this.getNewAddress('private')}>
<i className="icon fa-eye-slash" aria-hidden="true"></i> {translate('INDEX.PRIVATE_Z_ADDRESS')}
</a>
</li>
@ -72,15 +87,18 @@ class WalletsNativeReceive extends React.Component {
<tr>
<th>{translate('INDEX.TYPE')}</th>
<th>{translate('INDEX.ADDRESS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
</tr>
</thead>
<tbody>
{this.renderAddressList()}
{this.renderAddressList('public')}
{this.renderAddressList('private')}
</tbody>
<tfoot>
<tr>
<th>{translate('INDEX.TYPE')}</th>
<th>{translate('INDEX.ADDRESS')}</th>
<th>{translate('INDEX.AMOUNT')}</th>
</tr>
</tfoot>
</table>

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

@ -1,7 +1,188 @@
import React from 'react';
import { translate } from '../../translate/translate';
import { secondsToString } from '../../util/time';
import { sendNativeTx, getKMDOPID } from '../../actions/actionCreators';
import Store from '../../store';
class WalletsNativeSend extends React.Component {
constructor(props) {
super(props);
this.state = {
addressType: null,
sendFrom: null,
sendFromAmount: 0,
sendTo: null,
amount: 0,
fee: 0.0001,
addressSelectorOpen: false,
};
this.updateInput = this.updateInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.openDropMenu = this.openDropMenu.bind(this);
}
renderAddressByType(type) {
if (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>
</li>
);
} else {
return null;
}
}
renderSelectorCurrentLabel() {
if (this.state.sendFrom) {
return (
<span>
<i className={this.state.addressType === 'public' ? 'icon fa-eye' : 'icon fa-eye-slash'}></i> <span className="text">[ {this.state.sendFromAmount} {this.props.ActiveCoin.coin} ] {this.state.sendFrom}</span>
</span>
);
} else {
return (
<span>- Select Transparent or Private Address -</span>
);
}
}
renderAddressList() {
return (
<div className={'btn-group bootstrap-select form-control form-material showkmdwalletaddrs show-tick ' + (this.state.addressSelectorOpen ? 'open' : '')}>
<button type="button" className="btn dropdown-toggle btn-info" data-toggle="dropdown" data-id="kmd_wallet_send_from" title="- Select Transparent or Private Address -" aria-expanded="true" onClick={this.openDropMenu}>
<span className="filter-option pull-left">{this.renderSelectorCurrentLabel()} </span>&nbsp;<span className="bs-caret"><span className="caret"></span></span>
</button>
<div className="dropdown-menu open">
<ul className="dropdown-menu inner" role="menu">
<li data-original-index="1" className="selected">
<a tabIndex="0" data-tokens="null"><span className="text"> - Select Transparent or Private Address - </span><span className="glyphicon glyphicon-ok check-mark"></span></a>
</li>
{this.renderAddressByType('public')}
{this.renderAddressByType('private')}
</ul>
</div>
</div>
);
}
renderOPIDLabel(opid) {
if (opid.status === 'queued') {
return (
<span className="label label-warning">
<i className="icon fa-eye"></i> <span>{translate('KMD_NATIVE.QUEUED')}</span>
</span>
);
}
if (opid.status === 'executing') {
return (
<span className="label label-info">
<i className="icon fa-eye"></i> <span>{translate('KMD_NATIVE.EXECUTING')}</span>
</span>
);
}
if (opid.status === 'failed') {
return (
<span className="label label-danger">
<i className="icon fa-eye"></i> <span>{translate('KMD_NATIVE.FAILED')}</span>
</span>
);
}
if (opid.status === 'success') {
return (
<span className="label label-success">
<i className="icon fa-eye"></i> <span>{translate('KMD_NATIVE.SUCCESS')}</span>
</span>
);
}
}
renderOPIDResult(opid) {
var isWaitingStatus = true;
if (opid.status === 'queued') {
isWaitingStatus = false;
return (
<i>{translate('KMD_NATIVE.PLEASE_REFRESH')}...</i>
);
}
if (opid.status === 'executing') {
isWaitingStatus = false;
return (
<i>{translate('KMD_NATIVE.PLEASE_REFRESH')}...</i>
);
}
if (opid.status === 'failed') {
isWaitingStatus = false;
return (
<span>
<b>Error Code:</b> <span>{opid.error.code}</span>
<br />
<b>{translate('KMD_NATIVE.MESSAGE')}:</b> <span>{opid.error.message}</span>
</span>
);
}
if (opid.status === 'success') {
isWaitingStatus = false;
return (
<span>
<b>txid:</b> <span>{opid.result.txid}</span>
<br />
<b>{translate('KMD_NATIVE.EXECUTION_SECONDS')}:</b> <span>{opid.execution_secs}</span>
</span>
);
}
if (isWaitingStatus) {
return (
<span>Waiting...</span>
);
}
}
renderOPIDList() {
if (this.props.ActiveCoin.opids && this.props.ActiveCoin.opids.length) {
return this.props.ActiveCoin.opids.map((opid) =>
<tr key={opid.id}>
<td>{this.renderOPIDLabel(opid)}</td>
<td>{opid.id}</td>
<td>{secondsToString(opid.creation_time)}</td>
<td>{this.renderOPIDResult(opid)}</td>
</tr>
);
} else {
return null;
}
}
openDropMenu() {
this.setState(Object.assign({}, this.state, {
addressSelectorOpen: !this.state.addressSelectorOpen,
}));
}
updateAddressSelection(address, type, amount) {
this.setState(Object.assign({}, this.state, {
sendFrom: address,
addressType: type,
sendFromAmount: amount,
addressSelectorOpen: !this.state.addressSelectorOpen,
}));
}
updateInput(e) {
this.setState({
[e.target.name]: e.target.value,
});
}
handleSubmit() {
console.log(this.state);
Store.dispatch(sendNativeTx(this.props.ActiveCoin.coin, this.state));
setTimeout(function() {
Store.dispatch(getKMDOPID(null, this.props.ActiveCoin.coin));
}, 1000);
}
render() {
if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.nativeActiveSection === 'send') {
return (
@ -18,30 +199,30 @@ class WalletsNativeSend extends React.Component {
<div className="row">
<div className="col-xlg-12 form-group form-material">
<label className="control-label" data-extcoin="COIN" htmlFor="kmd_wallet_send_from">{translate('INDEX.SEND_FROM')}</label>
<select className="form-control form-material showkmdwalletaddrs show-tick" data-extcoin="COIN" id="kmd_wallet_send_from" title="Select Transparent or Private Address" data-size="5"></select>
{this.renderAddressList()}
</div>
<div className="col-xlg-12 form-group form-material">
<label className="control-label" data-extcoin="COIN" htmlFor="kmd_wallet_sendto">{translate('INDEX.SEND_TO')}</label>
<input type="text" className="form-control" data-extcoin="COIN" id="kmd_wallet_sendto" name="kmd_wallet_sendto" placeholder="Enter Transparent or Private address" autoComplete="off" required />
<input type="text" className="form-control" data-extcoin="COIN" name="sendTo" onChange={this.updateInput} id="kmd_wallet_sendto" placeholder="Enter Transparent or Private address" autoComplete="off" required />
</div>
<div className="col-lg-6 form-group form-material">
<label className="control-label" htmlFor="kmd_wallet_amount" data-extcoin="COIN" id="kmd_wallet_amount_label">
<span data-extcoinname="COIN"></span>
</label>
<input type="text" className="form-control" data-extcoin="COIN" id="kmd_wallet_amount" name="kmd_wallet_amount" placeholder="0.000" autoComplete="off" />
<input type="text" className="form-control" name="amount" onChange={this.updateInput} data-extcoin="COIN" id="kmd_wallet_amount" placeholder="0.000" autoComplete="off" />
</div>
<div className="col-lg-6 form-group form-material">
<label className="control-label" data-extcoin="COIN" htmlFor="kmd_wallet_fee">{translate('INDEX.FEE')}</label>
<input type="text" className="form-control" data-extcoin="COIN" id="kmd_wallet_fee" name="kmd_wallet_fee" placeholder="0.000" value="0.0001" autoComplete="off" />
<input type="text" className="form-control" name="fee" onChange={this.updateInput} data-extcoin="COIN" id="kmd_wallet_fee" placeholder="0.000" value={this.state.fee} autoComplete="off" />
</div>
<div className="col-lg-12">
<span data-extcoin="KMD">
<b>{translate('INDEX.TOTAL')} (<span data-extcoinname="COIN"></span> - txfee):</b> <span data-extcoin="COIN" id="kmd_wallet_total_value">0.000</span> <span data-extcoin="COIN" id="kmd_wallet_total_coinname" data-extcoinname="COIN"></span>
<b>{translate('INDEX.TOTAL')}:</b> {this.state.amount} - {this.state.fee}/kb = {Number(this.state.amount) - Number(this.state.fee)} {this.props.ActiveCoin.coin}
</span>
</div>
<div className="col-lg-12">
<button type="submit" className="btn btn-primary waves-effect waves-light pull-right" data-toggle="modal" id="kmd_wallet_send_coins_btn">
{translate('INDEX.SEND')} <span data-extcoinname="COIN"></span>
<button type="button" className="btn btn-primary waves-effect waves-light pull-right" data-toggle="modal" id="kmd_wallet_send_coins_btn" onClick={this.handleSubmit}>
{translate('INDEX.SEND')} {this.state.amount} {this.props.ActiveCoin.coin}
</button>
</div>
</div>
@ -74,6 +255,9 @@ class WalletsNativeSend extends React.Component {
<th>{translate('INDEX.RESULT')}</th>
</tr>
</thead>
<tbody>
{this.renderOPIDList()}
</tbody>
<tfoot>
<tr>
<th>{translate('INDEX.STATUS')}</th>

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

@ -10,6 +10,8 @@ class WalletsNativeTxHistory extends React.Component {
}
// TODO: implement sorting and pagination
// z transactions
// filter based on addr
toggleTxInfoModal(display, txIndex) {
Store.dispatch(toggleDashboardTxInfoModal(display, txIndex));
@ -61,7 +63,7 @@ class WalletsNativeTxHistory extends React.Component {
renderTxHistoryList() {
if (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory.length && this.props.ActiveCoin.nativeActiveSection === 'default') {
return this.props.ActiveCoin.txhistory.map((tx, index) =>
<tr key={tx.txid}>
<tr key={tx.txid + tx.amount}>
<td>
<span className="label label-default">
<i className="icon fa-eye"></i> {translate('IAPI.PUBLIC_SM')}

8
react/src/reducers/activeCoin.js

@ -8,7 +8,8 @@ import {
DASHBOARD_ACTIVE_TXINFO_MODAL,
ACTIVE_COIN_GET_ADDRESSES,
DASHBOARD_ACTIVE_COIN_NATIVE_BALANCE,
DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY
DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY,
DASHBOARD_ACTIVE_COIN_NATIVE_OPIDS
} from '../actions/actionCreators';
export function ActiveCoin(state = {
@ -21,6 +22,7 @@ export function ActiveCoin(state = {
showTransactionInfo: false,
showTransactionInfoTxIndex: null,
txhistory: [],
opids: null,
}, action) {
switch (action.type) {
case DASHBOARD_ACTIVE_COIN_CHANGE:
@ -68,6 +70,10 @@ export function ActiveCoin(state = {
return Object.assign({}, state, {
txhistory: action.txhistory,
});
case DASHBOARD_ACTIVE_COIN_NATIVE_OPIDS:
return Object.assign({}, state, {
opids: action.opids,
});
default:
return state;
}

4
react/src/util/time.js

@ -17,8 +17,8 @@ export function secondsToString(seconds) {
year = a.getFullYear(),
month = months[a.getMonth()],
date = a.getDate(),
hour = a.getHours(),
min = a.getMinutes(),
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;

Loading…
Cancel
Save