Browse Source

Merge pull request #7 from SuperNETorg/v0.25

V0.25
v0.25
pbca26 7 years ago
committed by GitHub
parent
commit
581469433e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      react/src/actions/actions/coinList.js
  2. 1
      react/src/actions/actions/nativeSend.js
  3. 8
      react/src/components/addcoin/addcoinOptionsCrypto.js
  4. 1
      react/src/components/addcoin/payload.js
  5. 10
      react/src/components/dashboard/claimInterestModal/claimInterestModal.js
  6. 13
      react/src/components/dashboard/coinTile/coinTileItem.js
  7. 6
      react/src/components/dashboard/coinTile/coinTileItem.render.js
  8. 5
      react/src/components/dashboard/coindDownModal/coindDownModal.js
  9. 7
      react/src/components/dashboard/coindDownModal/coindDownModal.render.js
  10. 14
      react/src/components/dashboard/importKeyModal/importKeyModal.render.js
  11. 6
      react/src/components/dashboard/jumblr/jumblr.js
  12. 18
      react/src/components/dashboard/jumblr/jumblr.render.js
  13. 4
      react/src/components/dashboard/navbar/navbar.render.js
  14. 2
      react/src/components/dashboard/qrModal/qrModal.render.js
  15. 5
      react/src/components/dashboard/receiveCoin/receiveCoin.js
  16. 14
      react/src/components/dashboard/sendCoin/sendCoin.js
  17. 24
      react/src/components/dashboard/sendCoin/sendCoin.render.js
  18. 9
      react/src/components/dashboard/settings/settings.addNodePanel.js
  19. 4
      react/src/components/dashboard/settings/settings.appInfoPanel.js
  20. 44
      react/src/components/dashboard/settings/settings.bip39KeysPanel.js
  21. 1
      react/src/components/dashboard/settings/settings.cliPanel.js
  22. 20
      react/src/components/dashboard/settings/settings.coindClearDataDirPanel.js
  23. 2
      react/src/components/dashboard/settings/settings.debugLogPanel.js
  24. 2
      react/src/components/dashboard/settings/settings.exportKeysPanel.js
  25. 8
      react/src/components/dashboard/settings/settings.importKeysPanel.js
  26. 13
      react/src/components/dashboard/settings/settings.nativeWalletDatKeysPanel.js
  27. 10
      react/src/components/dashboard/settings/settings.panel.js
  28. 22
      react/src/components/dashboard/settings/settings.panelBody.js
  29. 21
      react/src/components/dashboard/settings/settings.render.js
  30. 9
      react/src/components/dashboard/settings/settings.supportPanel.js
  31. 20
      react/src/components/dashboard/walletsData/walletsData.js
  32. 56
      react/src/components/dashboard/walletsInfo/walletsInfo.render.js
  33. 2
      react/src/components/dashboard/walletsNav/walletsNav.js
  34. 13
      react/src/components/login/login.render.js
  35. 3
      react/src/components/main/main.js
  36. 79
      react/src/translate/en.js
  37. 6
      react/src/util/coinHelper.js

3
react/src/actions/actions/coinList.js

@ -1,6 +1,7 @@
import { triggerToaster } from '../actionCreators'; import { triggerToaster } from '../actionCreators';
import Config from '../../config'; import Config from '../../config';
import Store from '../../store'; import Store from '../../store';
import { translate } from '../../translate/translate';
export function shepherdElectrumLock() { export function shepherdElectrumLock() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -104,7 +105,7 @@ export function shepherdRemoveCoin(coin, mode) {
if (mode === 'native') { if (mode === 'native') {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${coin} daemon is still running. If you want to completely stop it and remove use stop icon next time.`, `${coin} ${translate('API.DAEMON_IS_STILL_RUNNING')}`,
'Warning', 'Warning',
'warning' 'warning'
) )

1
react/src/actions/actions/nativeSend.js

@ -11,7 +11,6 @@ export function sendNativeTx(coin, _payload) {
let payload; let payload;
let _apiMethod; let _apiMethod;
// iguana core
if ((_payload.addressType === 'public' && // transparent if ((_payload.addressType === 'public' && // transparent
_payload.sendTo.length !== 95) || !_payload.sendFrom) { _payload.sendTo.length !== 95) || !_payload.sendFrom) {
_apiMethod = 'sendtoaddress'; _apiMethod = 'sendtoaddress';

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

@ -80,6 +80,14 @@ const addCoinOptionsCrypto = () => {
label: 'Dogecoin (DOGE)', label: 'Dogecoin (DOGE)',
icon: 'DOGE', icon: 'DOGE',
value: `DOGE|spv`, value: `DOGE|spv`,
}, {
label: 'Zcash (ZEC)',
icon: 'ZEC',
value: `ZEC|spv`,
}, {
label: 'Hush (HUSH)',
icon: 'HUSH',
value: `HUSH|spv`,
}); });
} }

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

@ -214,5 +214,6 @@ export function startAssetChain(confpath, coin, mode, getSuppyOnly) {
export function startCrypto(confpath, coin, mode) { export function startCrypto(confpath, coin, mode) {
const assetChainPorts = window.require('electron').remote.getCurrentWindow().assetChainPorts; const assetChainPorts = window.require('electron').remote.getCurrentWindow().assetChainPorts;
coin = coin === 'KMD' ? 'komodod' : coin;
return assetChainPorts[coin]; return assetChainPorts[coin];
} }

10
react/src/components/dashboard/claimInterestModal/claimInterestModal.js

@ -204,7 +204,7 @@ class ClaimInterestModal extends React.Component {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
res.result, res.result,
'Error', translate('TOASTR.ERROR'),
'error' 'error'
) )
); );
@ -270,7 +270,7 @@ class ClaimInterestModal extends React.Component {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
json.error.message, json.error.message,
'Error', translate('TOASTR.ERROR'),
'error' 'error'
) )
); );
@ -285,7 +285,7 @@ class ClaimInterestModal extends React.Component {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
json.error.message, json.error.message,
'Error', translate('TOASTR.ERROR'),
'error' 'error'
) )
); );
@ -304,8 +304,8 @@ class ClaimInterestModal extends React.Component {
} else { } else {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`Failed to verify address ${this.state.selectedAddress}`, `${translate('TOASTR.FAILED_TO_VERIFY_ADDR')} ${this.state.selectedAddress}`,
'Error', translate('TOASTR.ERROR'),
'error' 'error'
) )
); );

13
react/src/components/dashboard/coinTile/coinTileItem.js

@ -30,6 +30,7 @@ import {
import Store from '../../../store'; import Store from '../../../store';
import Config from '../../../config'; import Config from '../../../config';
import mainWindow from '../../../util/mainWindow'; import mainWindow from '../../../util/mainWindow';
import { translate } from '../../../translate/translate';
import CoinTileItemRender from './coinTileItem.render'; import CoinTileItemRender from './coinTileItem.render';
@ -146,8 +147,8 @@ class CoinTileItem extends React.Component {
.then((res) => { .then((res) => {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${coin} is removed`, `${coin} ${translate('TOASTR.COIN_IS_REMOVED')}`,
'Coin notification', translate('TOASTR.COIN_NOTIFICATION'),
'success' 'success'
) )
); );
@ -167,16 +168,16 @@ class CoinTileItem extends React.Component {
if (res.msg === 'error') { if (res.msg === 'error') {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`Unable to stop ${coin}. Try again.`, translate('TOASTR.COIN_UNABLE_TO_STOP', coin),
'Error', translate('TOASTR.ERROR'),
'error' 'error'
) )
); );
} else { } else {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${coin} is stopped`, `${coin} ${translate('TOASTR.COIN_IS_STOPPED')}`,
'Coin notification', translate('TOASTR.COIN_NOTIFICATION'),
'success' 'success'
) )
); );

6
react/src/components/dashboard/coinTile/coinTileItem.render.js

@ -27,13 +27,13 @@ const CoinTileItemRender = function() {
{ this.renderStopCoinButton() && { this.renderStopCoinButton() &&
<i <i
onClick={ () => this.stopCoind(item.coin, item.mode) } onClick={ () => this.stopCoind(item.coin, item.mode) }
title="Stop" title={ translate('DASHBOARD.STOP') }
className="icon fa-stop-circle coind-stop-icon"></i> className="icon fa-stop-circle coind-stop-icon"></i>
} }
{ this.renderRemoveCoinButton() && { this.renderRemoveCoinButton() &&
<i <i
onClick={ () => this.removeCoin(item.coin, item.mode) } onClick={ () => this.removeCoin(item.coin, item.mode) }
title="Remove" title={ translate('DASHBOARD.REMOVE') }
className={ 'icon fa-plus-circle coind-remove-icon' + (item.mode === 'spv' ? ' coind-remove-icon-spv' : '') }></i> className={ 'icon fa-plus-circle coind-remove-icon' + (item.mode === 'spv' ? ' coind-remove-icon-spv' : '') }></i>
} }
{ this.props.Dashboard && { this.props.Dashboard &&
@ -49,7 +49,7 @@ const CoinTileItemRender = function() {
!this.props.ActiveCoin.rescanInProgress && !this.props.ActiveCoin.rescanInProgress &&
<i <i
onClick={ this.openCoindDownModal } onClick={ this.openCoindDownModal }
title={ `Unable to establish RPC connection! Retries count: ${this.props.ActiveCoin.getinfoFetchFailures}.` } title={ `${translate('DASHBOARD.RPC_CONN_FAILURE')}: ${this.props.ActiveCoin.getinfoFetchFailures}.` }
className="icon fa-warning icon-native-connection-warning"></i> className="icon fa-warning icon-native-connection-warning"></i>
} }
</div> </div>

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

@ -7,6 +7,7 @@ import {
} from '../../../actions/actionCreators'; } from '../../../actions/actionCreators';
import Store from '../../../store'; import Store from '../../../store';
import mainWindow from '../../../util/mainWindow'; import mainWindow from '../../../util/mainWindow';
import { translate } from '../../../translate/translate';
import CoindDownModalRender from './coindDownModal.render'; import CoindDownModalRender from './coindDownModal.render';
@ -18,7 +19,7 @@ class CoindDownModal extends React.Component {
this.state = { this.state = {
display: false, display: false,
kmdMainPassiveMode: false, kmdMainPassiveMode: false,
coindStdOut: 'Loading...', coindStdOut: translate('INDEX.LOADING') + '...',
toggleDebugLog: true, toggleDebugLog: true,
}; };
this.dismiss = this.dismiss.bind(this); this.dismiss = this.dismiss.bind(this);
@ -51,7 +52,7 @@ class CoindDownModal extends React.Component {
coindGetStdout(this.props.ActiveCoin.coin) coindGetStdout(this.props.ActiveCoin.coin)
.then((res) => { .then((res) => {
this.setState({ this.setState({
coindStdOut: res.msg === 'success' ? res.result : `Error reading ${this.props.ActiveCoin.coin} stdout`, coindStdOut: res.msg === 'success' ? res.result : `${translate('INDEX.ERROR_READING')} ${this.props.ActiveCoin.coin} stdout`,
}); });
}); });
} }

7
react/src/components/dashboard/coindDownModal/coindDownModal.render.js

@ -28,7 +28,10 @@ const CoindDownModalRender = function() {
onClick={ this.dismiss }> onClick={ this.dismiss }>
<span>×</span> <span>×</span>
</button> </button>
<h4 className="modal-title white">{ this.props.ActiveCoin.coin === 'KMD' ? 'Komodod' : `Komodod / ${this.props.ActiveCoin.coin}` } { translate('INDEX.IS_DOWN') }!</h4> <h4 className="modal-title white">
{ this.props.ActiveCoin.coin === 'KMD' ? 'Komodod' : `Komodod / ${this.props.ActiveCoin.coin}` }&nbsp;
{ translate('INDEX.IS_DOWN') }!
</h4>
</div> </div>
<div className="modal-body"> <div className="modal-body">
<div className="vertical-align text-center"> <div className="vertical-align text-center">
@ -49,7 +52,7 @@ const CoindDownModalRender = function() {
<div <div
className="toggle-label margin-right-15 pointer" className="toggle-label margin-right-15 pointer"
onClick={ this.toggleDebugLog }> onClick={ this.toggleDebugLog }>
Show debug.log { translate('INDEX.SHOW') } debug.log
</div> </div>
</div> </div>
{ !this.state.toggleDebugLog && { !this.state.toggleDebugLog &&

14
react/src/components/dashboard/importKeyModal/importKeyModal.render.js

@ -24,7 +24,11 @@ export const ImportKeyModalRender = function() {
</div> </div>
<div className="modal-body"> <div className="modal-body">
<div className="padding-bottom-40"> <div className="padding-bottom-40">
{ translate('IMPORT_KEY.TWO_FORMS_BELOW_P1') } <strong>Iguana Core / ICO</strong> { translate('IMPORT_KEY.TWO_FORMS_BELOW_P2') } <strong>WIF (Wallet Import Format)</strong> { translate('IMPORT_KEY.TWO_FORMS_BELOW_P3') }. { translate('IMPORT_KEY.TWO_FORMS_BELOW_P1') }&nbsp;
<strong>Iguana Core / ICO</strong>&nbsp;
{ translate('IMPORT_KEY.TWO_FORMS_BELOW_P2') }&nbsp;
<strong>WIF (Wallet Import Format)</strong>&nbsp;
{ translate('IMPORT_KEY.TWO_FORMS_BELOW_P3') }.
</div> </div>
<div> <div>
<strong>{ translate('IMPORT_KEY.PASSPHRASE') }</strong> <strong>{ translate('IMPORT_KEY.PASSPHRASE') }</strong>
@ -111,10 +115,10 @@ export const ImportKeyModalRender = function() {
<div <div
className="toggle-label" className="toggle-label"
onClick={ this.toggleImportWithRescan }> onClick={ this.toggleImportWithRescan }>
{ translate('IMPORT_KEY.TRIGGER_RESCAN') } { translate('IMPORT_KEY.TRIGGER_RESCAN') }
<i <i
className="icon fa-question-circle settings-help" className="icon fa-question-circle settings-help"
title={ translate('IMPORT_KEY.RESCAN_TIP') }></i> title={ translate('IMPORT_KEY.RESCAN_TIP') }></i>
</div> </div>
</span> </span>
</div> </div>

6
react/src/components/dashboard/jumblr/jumblr.js

@ -18,7 +18,7 @@ import Store from '../../../store';
import Config from '../../../config'; import Config from '../../../config';
import { import {
JumblrRender, JumblrRender,
JumblrRenderSecretAddressList JumblrRenderSecretAddressList,
} from './jumblr.render'; } from './jumblr.render';
import { PassPhraseGenerator } from '../../../util/crypto/passphrasegenerator'; import { PassPhraseGenerator } from '../../../util/crypto/passphrasegenerator';
@ -91,7 +91,7 @@ class Jumblr extends React.Component {
} else if (json.result && json.result.result && json.result.result === 'paused') { } else if (json.result && json.result.result && json.result.result === 'paused') {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
'Jumblr paused', translate('JUMBLR.JUMBLR_PAUSED'),
'Jumblr', 'Jumblr',
'success' 'success'
) )
@ -115,7 +115,7 @@ class Jumblr extends React.Component {
} else if (json.result && json.result.result && json.result.result === 'resumed') { } else if (json.result && json.result.result && json.result.result === 'resumed') {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
'Jumblr resumed', translate('JUMBLR.JUMBLR_RESUMED'),
'Jumblr', 'Jumblr',
'success' 'success'
) )

18
react/src/components/dashboard/jumblr/jumblr.render.js

@ -137,14 +137,14 @@ export const JumblrRender = function() {
className="btn btn-jumblr-warning waves-effect waves-light" className="btn btn-jumblr-warning waves-effect waves-light"
onClick={ this._pauseJumblr }> onClick={ this._pauseJumblr }>
<i className="fa fa-pause margin-right-10"></i> <i className="fa fa-pause margin-right-10"></i>
Pause { translate('JUMBLR.PAUSE') }
</button> </button>
<button <button
type="button" type="button"
className="btn btn-success waves-effect waves-light margin-left-20" className="btn btn-success waves-effect waves-light margin-left-20"
onClick={ this._resumeJumblr }> onClick={ this._resumeJumblr }>
<i className="fa fa-play margin-right-10"></i> <i className="fa fa-play margin-right-10"></i>
Resume { translate('JUMBLR.RESUME') }
</button> </button>
</div> </div>
</div> </div>
@ -281,11 +281,15 @@ export const JumblrRender = function() {
<p>{ translate('JUMBLR.JUMBLR_SECRET_DESC_P2') }</p> <p>{ translate('JUMBLR.JUMBLR_SECRET_DESC_P2') }</p>
<p>{ translate('JUMBLR.JUMBLR_SECRET_DESC_P3') }</p> <p>{ translate('JUMBLR.JUMBLR_SECRET_DESC_P3') }</p>
<p>{ translate('JUMBLR.JUMBLR_SECRET_DESC_P4') }</p> <p>{ translate('JUMBLR.JUMBLR_SECRET_DESC_P4') }</p>
<p>{ translate('JUMBLR.JUMBLR_SECRET_DESC_P5') } <code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer XXX</code>. { translate('JUMBLR.JUMBLR_SECRET_DESC_P6') }.</p> <p>
{ translate('JUMBLR.JUMBLR_SECRET_DESC_P5') }&nbsp;
<code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer XXX</code>.&nbsp;
{ translate('JUMBLR.JUMBLR_SECRET_DESC_P6') }.
</p>
{ this.state.jumblrDepositAddressPBased && { this.state.jumblrDepositAddressPBased &&
<div className="padding-bottom-20 padding-top-20"> <div className="padding-bottom-20 padding-top-20">
<label>Passphrase</label> <label>{ translate('JUMBLR.PASSPHRASE') }</label>
<input <input
type="text" type="text"
className="form-control" className="form-control"
@ -388,10 +392,12 @@ export const JumblrRender = function() {
onClick={ () => this.openTab(1) }>{ translate('INDEX.NEXT') }</button> onClick={ () => this.openTab(1) }>{ translate('INDEX.NEXT') }</button>
<div className="col-xlg-12 col-md-12 nofloat"> <div className="col-xlg-12 col-md-12 nofloat">
<p>{ translate('JUMBLR.SECRET_REGEN_DESC_P1') }</p> <p>{ translate('JUMBLR.SECRET_REGEN_DESC_P1') }</p>
<p>{ translate('JUMBLR.SECRET_REGEN_DESC_P2') }: <code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer</code>.</p> <p>
{ translate('JUMBLR.SECRET_REGEN_DESC_P2') }:&nbsp;
<code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer</code>.
</p>
<p>{ translate('JUMBLR.SECRET_REGEN_DESC_P3') }</p> <p>{ translate('JUMBLR.SECRET_REGEN_DESC_P3') }</p>
<p>{ translate('JUMBLR.SECRET_REGEN_DESC_P4') }</p> <p>{ translate('JUMBLR.SECRET_REGEN_DESC_P4') }</p>
{ this.state.jumblrDepositAddressPBased && { this.state.jumblrDepositAddressPBased &&
<div className="padding-bottom-20 padding-top-20"> <div className="padding-bottom-20 padding-top-20">
<label>{ translate('INDEX.PASSPHRASE') }</label> <label>{ translate('INDEX.PASSPHRASE') }</label>

4
react/src/components/dashboard/navbar/navbar.render.js

@ -122,14 +122,14 @@ const NavbarRender = function() {
{ this.isRenderSpvLockLogout() && { this.isRenderSpvLockLogout() &&
<li> <li>
<a onClick={ this.spvLock }> <a onClick={ this.spvLock }>
<i className="icon fa-lock"></i> Soft logout <i className="icon fa-lock"></i> { translate('DASHBOARD.SOFT_LOGOUT') }
</a> </a>
</li> </li>
} }
{ this.isRenderSpvLockLogout() && { this.isRenderSpvLockLogout() &&
<li> <li>
<a onClick={ this.spvLogout }> <a onClick={ this.spvLogout }>
<i className="icon fa-power-off"></i> Complete logout <i className="icon fa-power-off"></i> { translate('DASHBOARD.COMPLETE_LOGOUT') }
</a> </a>
</li> </li>
} }

2
react/src/components/dashboard/qrModal/qrModal.render.js

@ -9,7 +9,7 @@ export const QRModalRender = function() {
className="qrcode-modal" className="qrcode-modal"
title={ translate('INDEX.QRCODE') } title={ translate('INDEX.QRCODE') }
onClick={ this.openModal }> onClick={ this.openModal }>
<i className="icon fa-qrcode margin-right-5"></i> generate QR-code <i className="icon fa-qrcode margin-right-5"></i> { translate('DASHBOARD.GENERATE_SM') } QR-code
</span> </span>
<div <div
className={ 'modal modal-3d-sign ' + (this.state.modalIsOpen ? 'show in' : 'fade hide') } className={ 'modal modal-3d-sign ' + (this.state.modalIsOpen ? 'show in' : 'fade hide') }

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

@ -11,8 +11,9 @@ import {
AddressActionsNonBasiliskModeRender, AddressActionsNonBasiliskModeRender,
AddressItemRender, AddressItemRender,
ReceiveCoinRender, ReceiveCoinRender,
_ReceiveCoinTableRender _ReceiveCoinTableRender,
} from './receiveCoin.render'; } from './receiveCoin.render';
import { translate } from '../../../translate/translate';
// TODO: implement balance/interest sorting // TODO: implement balance/interest sorting
@ -66,7 +67,7 @@ class ReceiveCoin extends React.Component {
.then((json) => { .then((json) => {
if (json.length && if (json.length &&
json.length > 10) { json.length > 10) {
Store.dispatch(copyString(json, 'WIF address copied to clipboard')); Store.dispatch(copyString(json, 'WIF ' + translate('DASHBOARD.RECEIVE_ADDR_COPIED')));
} }
}); });
} }

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

@ -59,7 +59,7 @@ class SendCoin extends React.Component {
} }
copyTXID(txid) { copyTXID(txid) {
Store.dispatch(copyString(txid, 'TXID copied to clipboard')); Store.dispatch(copyString(txid, translate('SEND.TXID_COPIED')));
} }
openExplorerWindow(txid) { openExplorerWindow(txid) {
@ -216,7 +216,8 @@ class SendCoin extends React.Component {
this.props.ActiveCoin.addresses[type] && this.props.ActiveCoin.addresses[type] &&
this.props.ActiveCoin.addresses[type].length) { this.props.ActiveCoin.addresses[type].length) {
this.props.ActiveCoin.addresses[type].map((address) => { this.props.ActiveCoin.addresses[type].map((address) => {
if (address.amount > 0 && (type !== 'public' || (address.canspend && type === 'public'))) { if (address.amount > 0 &&
(type !== 'public' || (address.canspend && type === 'public'))) {
_items.push( _items.push(
<li <li
className="selected" className="selected"
@ -498,7 +499,7 @@ class SendCoin extends React.Component {
if (Number(_amountSats) + _fees[this.props.ActiveCoin.coin] > _balanceSats) { if (Number(_amountSats) + _fees[this.props.ActiveCoin.coin] > _balanceSats) {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${translate('SEND.INSUFFICIENT_FUNDS')} max available balance is ${(0.00000001 * (_balanceSats - _fees[this.props.ActiveCoin.coin])).toFixed(8)} ${this.props.ActiveCoin.coin}`, `${translate('SEND.INSUFFICIENT_FUNDS')} ${translate('SEND.MAX_AVAIL_BALANCE')} ${(0.00000001 * (_balanceSats - _fees[this.props.ActiveCoin.coin])).toFixed(8)} ${this.props.ActiveCoin.coin}`,
translate('TOASTR.WALLET_NOTIFICATION'), translate('TOASTR.WALLET_NOTIFICATION'),
'error' 'error'
) )
@ -507,7 +508,7 @@ class SendCoin extends React.Component {
} else if (Number(_amountSats) < _fees[this.props.ActiveCoin.coin]) { } else if (Number(_amountSats) < _fees[this.props.ActiveCoin.coin]) {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`Amount ${this.state.amount} is too small, min ${this.props.ActiveCoin.coin} amount is ${_fees[this.props.ActiveCoin.coin] * 0.00000001}`, `${translate('SEND.AMOUNT_IS_TOO_SMALL', this.state.amount)}, ${translate('SEND.MIN_AMOUNT_IS', this.props.ActiveCoin.coin)} ${_fees[this.props.ActiveCoin.coin] * 0.00000001}`,
translate('TOASTR.WALLET_NOTIFICATION'), translate('TOASTR.WALLET_NOTIFICATION'),
'error' 'error'
) )
@ -555,7 +556,7 @@ class SendCoin extends React.Component {
Number(Number(this.state.amount) + 0.0001) > Number(this.state.sendFromAmount))) { Number(Number(this.state.amount) + 0.0001) > Number(this.state.sendFromAmount))) {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${translate('SEND.INSUFFICIENT_FUNDS')} max available balance is ${Number(this.state.sendFromAmount || this.props.ActiveCoin.balance.transparent)} ${this.props.ActiveCoin.coin}`, `${translate('SEND.INSUFFICIENT_FUNDS')} ${translate('SEND.MAX_AVAIL_BALANCE')} ${Number(this.state.sendFromAmount || this.props.ActiveCoin.balance.transparent)} ${this.props.ActiveCoin.coin}`,
translate('TOASTR.WALLET_NOTIFICATION'), translate('TOASTR.WALLET_NOTIFICATION'),
'error' 'error'
) )
@ -564,7 +565,8 @@ class SendCoin extends React.Component {
} }
if (this.state.sendTo.length > 34 && if (this.state.sendTo.length > 34 &&
(!this.state.sendFrom || this.state.sendFrom.length < 34)) { (!this.state.sendFrom || this.state.sendFrom.length < 34) &&
this.props.ActiveCoin.mode === 'native') {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
translate('SEND.SELECT_SOURCE_ADDRESS'), translate('SEND.SELECT_SOURCE_ADDRESS'),

24
react/src/components/dashboard/sendCoin/sendCoin.render.js

@ -275,6 +275,30 @@ export const SendRender = function() {
<span className="label label-success">{ translate('SEND.SUCCESS_SM') }</span> <span className="label label-success">{ translate('SEND.SUCCESS_SM') }</span>
</td> </td>
</tr> </tr>
<tr>
<td className="padding-left-30">
{ translate('INDEX.SEND_FROM') }
</td>
<td className="padding-left-30">
{ this.props.ActiveCoin.mode === 'spv' ? this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].pub : this.state.sendFrom }
</td>
</tr>
<tr>
<td className="padding-left-30">
{ translate('INDEX.SEND_TO') }
</td>
<td className="padding-left-30">
{ this.state.sendTo }
</td>
</tr>
<tr>
<td className="padding-left-30">
{ translate('INDEX.AMOUNT') }
</td>
<td className="padding-left-30">
{ this.state.amount }
</td>
</tr>
<tr> <tr>
<td className="padding-left-30">{ translate('SEND.TRANSACTION_ID') }</td> <td className="padding-left-30">{ translate('SEND.TRANSACTION_ID') }</td>
<td className="padding-left-30"> <td className="padding-left-30">

9
react/src/components/dashboard/settings/settings.addNodePanel.js

@ -78,7 +78,8 @@ class AddNodePanel extends React.Component {
} }
addNode() { addNode() {
if (this.state.addNodeCoin && this.state.addPeerIP) { if (this.state.addNodeCoin &&
this.state.addPeerIP) {
Store.dispatch( Store.dispatch(
addPeerNode( addPeerNode(
this.state.addNodeCoin.split('|')[0], this.state.addNodeCoin.split('|')[0],
@ -89,9 +90,9 @@ class AddNodePanel extends React.Component {
} }
updateInput(e) { updateInput(e) {
this.setState({ this.setState({
[e.target.name]: e.target.value, [e.target.name]: e.target.value,
}); });
} }
render() { render() {

4
react/src/components/dashboard/settings/settings.appInfoPanel.js

@ -15,7 +15,7 @@ class AppInfoPanel extends React.Component {
return null return null
} else { } else {
let _items = []; let _items = [];
let _ports = mainWindow.getAssetChainPorts() let _ports = mainWindow.getAssetChainPorts();
for (let key in _ports) { for (let key in _ports) {
_items.push( _items.push(
@ -69,7 +69,7 @@ class AppInfoPanel extends React.Component {
</p> </p>
} }
{ mainWindow.arch === 'x64' && { mainWindow.arch === 'x64' &&
<h5>Daemon ports</h5> <h5>{ translate('SETTINGS.DAEMON_PORTS') }</h5>
} }
{ mainWindow.arch === 'x64' && { mainWindow.arch === 'x64' &&
<p>{ _items }</p> <p>{ _items }</p>

44
react/src/components/dashboard/settings/settings.bip39KeysPanel.js

@ -154,13 +154,13 @@ class Bip39KeysPanel extends React.Component {
autoComplete="off" autoComplete="off"
name="match" name="match"
onChange={ this.updateInput } onChange={ this.updateInput }
placeholder="Search key pattern" placeholder={ translate('SETTINGS.SEARCH_KEY_PATTERN') }
value={ this.state.match } /> value={ this.state.match } />
<button <button
type="button" type="button"
className="btn btn-primary waves-effect waves-light margin-top-20" className="btn btn-primary waves-effect waves-light margin-top-20"
disabled={ !this.state.match || !this.state.passphrase || this.state.passphrase.length < 2 } disabled={ !this.state.match || !this.state.passphrase || this.state.passphrase.length < 2 }
onClick={ this._getBip39Keys }>Get key</button> onClick={ this._getBip39Keys }>{ translate('SETTINGS.GET_KEY') }</button>
</div> </div>
<div className="col-sm-2 no-padding-left text-center margin-top-10 margin-left-50"> <div className="col-sm-2 no-padding-left text-center margin-top-10 margin-left-50">
<select <select
@ -169,16 +169,16 @@ class Bip39KeysPanel extends React.Component {
value={ this.state.accounts } value={ this.state.accounts }
onChange={ (event) => this.updateInput(event) } onChange={ (event) => this.updateInput(event) }
autoFocus> autoFocus>
<option value="1">1 account</option> <option value="1">1 { translate('SETTINGS.ACCOUNT') }</option>
<option value="2">2 accounts</option> <option value="2">2 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="3">3 accounts</option> <option value="3">3 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="4">4 accounts</option> <option value="4">4 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="5">5 accounts</option> <option value="5">5 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="6">6 accounts</option> <option value="6">6 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="7">7 accounts</option> <option value="7">7 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="8">8 accounts</option> <option value="8">8 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="9">9 accounts</option> <option value="9">9 { translate('SETTINGS.ACCOUNTS') }</option>
<option value="10">10 accounts</option> <option value="10">10 { translate('SETTINGS.ACCOUNTS') }</option>
</select> </select>
</div> </div>
<div className="col-sm-2 no-padding-left text-center margin-top-10"> <div className="col-sm-2 no-padding-left text-center margin-top-10">
@ -188,15 +188,15 @@ class Bip39KeysPanel extends React.Component {
value={ this.state.addressdepth } value={ this.state.addressdepth }
onChange={ (event) => this.updateInput(event) } onChange={ (event) => this.updateInput(event) }
autoFocus> autoFocus>
<option value="20">20 addresses</option> <option value="20">20 { translate('SETTINGS.ADDRESSES') }</option>
<option value="30">30 addresses</option> <option value="30">30 { translate('SETTINGS.ADDRESSES') }</option>
<option value="40">40 addresses</option> <option value="40">40 { translate('SETTINGS.ADDRESSES') }</option>
<option value="50">50 addresses</option> <option value="50">50 { translate('SETTINGS.ADDRESSES') }</option>
<option value="60">60 addresses</option> <option value="60">60 { translate('SETTINGS.ADDRESSES') }</option>
<option value="70">70 addresses</option> <option value="70">70 { translate('SETTINGS.ADDRESSES') }</option>
<option value="80">80 addresses</option> <option value="80">80 { translate('SETTINGS.ADDRESSES') }</option>
<option value="90">90 addresses</option> <option value="90">90 { translate('SETTINGS.ADDRESSES') }</option>
<option value="100">100 addresses</option> <option value="100">100 { translate('SETTINGS.ADDRESSES') }</option>
</select> </select>
</div> </div>
</div> </div>
@ -215,7 +215,7 @@ class Bip39KeysPanel extends React.Component {
</div> </div>
} }
{ this.state.keys === 'empty' && { this.state.keys === 'empty' &&
<strong>Key is not found</strong> <strong>{ translate('SETTINGS.KEY_IS_NOT_FOUND') }</strong>
} }
</div> </div>
} }

1
react/src/components/dashboard/settings/settings.cliPanel.js

@ -19,7 +19,6 @@ class CliPanel extends React.Component {
renderActiveCoinsList(mode) { renderActiveCoinsList(mode) {
const modes = [ const modes = [
'native', 'native',
'basilisk',
'full' 'full'
]; ];

20
react/src/components/dashboard/settings/settings.coindClearDataDirPanel.js

@ -2,7 +2,7 @@ import React from 'react';
import { translate } from '../../../translate/translate'; import { translate } from '../../../translate/translate';
import { import {
shepherdClearCoindFolder, shepherdClearCoindFolder,
triggerToaster triggerToaster,
} from '../../../actions/actionCreators'; } from '../../../actions/actionCreators';
import { coindList } from '../../../util/coinHelper'; import { coindList } from '../../../util/coinHelper';
import Store from '../../../store'; import Store from '../../../store';
@ -47,7 +47,7 @@ class CoindClearDataDirPanel extends React.Component {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${_coin} data folder is cleared`, `${_coin} ${translate('TOASTR.DATADIR_CLEARED')}`,
translate('TOASTR.WALLET_NOTIFICATION'), translate('TOASTR.WALLET_NOTIFICATION'),
'success' 'success'
) )
@ -55,7 +55,7 @@ class CoindClearDataDirPanel extends React.Component {
} else { } else {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`Unable to clear ${_coin}`, `${translate('TOASTR.DATADIR_UNABLE_TO_CLEAR')} ${_coin}`,
translate('TOASTR.WALLET_NOTIFICATION'), translate('TOASTR.WALLET_NOTIFICATION'),
'error' 'error'
) )
@ -84,7 +84,7 @@ class CoindClearDataDirPanel extends React.Component {
_items.push( _items.push(
<option <option
key={ `coind-clear-data-coins-none` } key={ `coind-clear-data-coins-none` }
value="none">Pick a coin</option> value="none">{ translate('SETTINGS.PICK_A_COIN') }</option>
); );
for (let i = 0; i < _nativeCoins.length; i++) { for (let i = 0; i < _nativeCoins.length; i++) {
if (_nativeCoins[i] !== 'CHIPS') { if (_nativeCoins[i] !== 'CHIPS') {
@ -105,7 +105,7 @@ class CoindClearDataDirPanel extends React.Component {
<div className="row"> <div className="row">
<div className="col-sm-12 padding-bottom-10"> <div className="col-sm-12 padding-bottom-10">
<h4 className="col-red"> <h4 className="col-red">
<i className="fa fa-warning"></i> Warning: the following form will wipe out all native coin data!<br />Don't touch anything if you're not sure what you're doing. <i className="fa fa-warning"></i> { translate('SETTINGS.COIND_DATADIR_CLEAR_P1') }<br />{ translate('SETTINGS.COIND_DATADIR_CLEAR_P2') }
</h4> </h4>
<div> <div>
<div className="col-sm-4 no-padding-left text-center"> <div className="col-sm-4 no-padding-left text-center">
@ -130,29 +130,29 @@ class CoindClearDataDirPanel extends React.Component {
</label> </label>
<span <span
className="title" className="title"
onClick={ this.toggleKeepWalletDat }>Keep wallet.dat</span> onClick={ this.toggleKeepWalletDat }>{ translate('SETTINGS.KEEP') } wallet.dat</span>
</span> </span>
{ !this.state.displayYesNo && { !this.state.displayYesNo &&
<button <button
type="button" type="button"
className="btn btn-primary waves-effect waves-light margin-top-20" className="btn btn-primary waves-effect waves-light margin-top-20"
disabled={ this.state.loading || this.state.coin === 'none' } disabled={ this.state.loading || this.state.coin === 'none' }
onClick={ this.displayYesNo }>{ this.state.loading ? `Deleting ${this.state.coin} data...` : 'Delete' }</button> onClick={ this.displayYesNo }>{ this.state.loading ? translate('SETTINGS.COIND_DELETING', this.state.coin) : translate('SETTINGS.COIND_DELETE') }</button>
} }
{ this.state.displayYesNo && { this.state.displayYesNo &&
<div className="margin-top-20">Are you sure you want to clear {this.state.coin} data folder?</div> <div className="margin-top-20">{ translate('SETTINGS.DATADIR_DELETE_PROMPT', this.state.coin) }</div>
} }
{ this.state.displayYesNo && { this.state.displayYesNo &&
<button <button
type="button" type="button"
className="btn btn-primary waves-effect waves-light margin-top-20 margin-right-20" className="btn btn-primary waves-effect waves-light margin-top-20 margin-right-20"
onClick={ this.removeCoindData }>Yes</button> onClick={ this.removeCoindData }>{ translate('SETTINGS.YES') }</button>
} }
{ this.state.displayYesNo && { this.state.displayYesNo &&
<button <button
type="button" type="button"
className="btn btn-primary waves-effect waves-light margin-top-20" className="btn btn-primary waves-effect waves-light margin-top-20"
onClick={ this.displayYesNo }>No</button> onClick={ this.displayYesNo }>{ translate('SETTINGS.NO') }</button>
} }
</div> </div>
</div> </div>

2
react/src/components/dashboard/settings/settings.debugLogPanel.js

@ -120,7 +120,7 @@ class DebugLogPanel extends React.Component {
_items.push( _items.push(
<option <option
key={ `coind-walletdat-coins-none` } key={ `coind-walletdat-coins-none` }
value="none">Pick a coin</option> value="none">{ translate('SETTINGS.PICK_A_COIN') }</option>
); );
for (let i = 0; i < _nativeCoins.length; i++) { for (let i = 0; i < _nativeCoins.length; i++) {
if (_nativeCoins[i] === 'KMD') { if (_nativeCoins[i] === 'KMD') {

2
react/src/components/dashboard/settings/settings.exportKeysPanel.js

@ -81,7 +81,7 @@ class ExportKeysPanel extends React.Component {
items.push( items.push(
<tr key={ _key }> <tr key={ _key }>
<td className="padding-bottom-30"> <td className="padding-bottom-30">
<strong className="padding-right-20">{_key}</strong>{ _wifKeys[_key].pub } <strong className="padding-right-20">{ _key }</strong>{ _wifKeys[_key].pub }
<button <button
className="btn btn-default btn-xs clipboard-edexaddr margin-left-10" className="btn btn-default btn-xs clipboard-edexaddr margin-left-10"
title={ translate('INDEX.COPY_TO_CLIPBOARD') } title={ translate('INDEX.COPY_TO_CLIPBOARD') }

8
react/src/components/dashboard/settings/settings.importKeysPanel.js

@ -41,11 +41,7 @@ class ImportKeysPanel extends React.Component {
</div> </div>
<div className="row"> <div className="row">
<div className="col-sm-12"> <div className="col-sm-12">
<form <div className="wifkeys-import-form">
className="wifkeys-import-form"
method="post"
action="javascript:"
autoComplete="off">
<div className="form-group form-material floating"> <div className="form-group form-material floating">
<input <input
type="text" type="text"
@ -63,7 +59,7 @@ class ImportKeysPanel extends React.Component {
className="btn btn-primary waves-effect waves-light" className="btn btn-primary waves-effect waves-light"
onClick={ this.importWifKey }>{ translate('INDEX.IMPORT_PRIV_KEY') }</button> onClick={ this.importWifKey }>{ translate('INDEX.IMPORT_PRIV_KEY') }</button>
</div> </div>
</form> </div>
</div> </div>
</div> </div>
</div> </div>

13
react/src/components/dashboard/settings/settings.nativeWalletDatKeysPanel.js

@ -69,7 +69,7 @@ class NativeWalletDatKeysPanel extends React.Component {
_items.push( _items.push(
<option <option
key={ `coind-walletdat-coins-none` } key={ `coind-walletdat-coins-none` }
value="none">Pick a coin</option> value="none">{ translate('SETTINGS.PICK_A_COIN') }</option>
); );
for (let i = 0; i < _nativeCoins.length; i++) { for (let i = 0; i < _nativeCoins.length; i++) {
_items.push( _items.push(
@ -83,9 +83,8 @@ class NativeWalletDatKeysPanel extends React.Component {
} }
renderKeys() { renderKeys() {
let _items = [];
const _keys = this.state.keys; const _keys = this.state.keys;
let _items = [];
if (_keys.msg === 'error') { if (_keys.msg === 'error') {
return ( return (
@ -103,12 +102,12 @@ class NativeWalletDatKeysPanel extends React.Component {
return ( return (
<div> <div>
<div className="col-sm-12 margin-bottom-20"> <div className="col-sm-12 margin-bottom-20">
Found <strong>{ _keys.result.length }</strong> keys { translate('SETTINGS.FOUND') } <strong>{ _keys.result.length }</strong> { translate('SETTINGS.KEYS_SM') }
</div> </div>
{ _keys.result.length > 0 && { _keys.result.length > 0 &&
<div className="col-sm-6"> <div className="col-sm-6">
<div> <div>
<strong>Address</strong> <strong>{ translate('SETTINGS.ADDRESS') }</strong>
</div> </div>
<textarea <textarea
readOnly readOnly
@ -155,13 +154,13 @@ class NativeWalletDatKeysPanel extends React.Component {
autoComplete="off" autoComplete="off"
name="keyMatchPattern" name="keyMatchPattern"
onChange={ this.updateInput } onChange={ this.updateInput }
placeholder="Search key pattern" placeholder={ translate('SETTINGS.SEARCH_KEY_PATTERN') }
value={ this.state.keyMatchPattern } /> value={ this.state.keyMatchPattern } />
<button <button
type="button" type="button"
className="btn btn-primary waves-effect waves-light margin-top-20" className="btn btn-primary waves-effect waves-light margin-top-20"
disabled={ this.state.loading || this.state.coin === 'none' } disabled={ this.state.loading || this.state.coin === 'none' }
onClick={ this._getWalletDatKeys }>{ this.state.loading ? 'Fetching keys...' : 'Get keys' }</button> onClick={ this._getWalletDatKeys }>{ this.state.loading ? translate('SETTINGS.FETCHING_KEYS') + '...' : translate('SETTINGS.GET_KEYS') }</button>
</div> </div>
</div> </div>
</div> </div>

10
react/src/components/dashboard/settings/settings.panel.js

@ -18,14 +18,14 @@ class Panel extends React.Component {
singleOpen, singleOpen,
openByDefault, openByDefault,
uniqId, uniqId,
children children,
} = this.props; } = this.props;
const settings = { const settings = {
singleOpen, singleOpen,
openByDefault, openByDefault,
uniqId, uniqId,
kids: children kids: children,
}; };
const initialStateSections = Utils.setupAccordion(settings).activeSections; const initialStateSections = Utils.setupAccordion(settings).activeSections;
@ -87,9 +87,9 @@ class Panel extends React.Component {
return( return(
<div <div
className={accordionClasses} className={ accordionClasses }
id={uniqId}> id={ uniqId }>
{childrenWithProps} { childrenWithProps }
</div> </div>
); );
} }

22
react/src/components/dashboard/settings/settings.panelBody.js

@ -56,7 +56,7 @@ class PanelSection extends React.Component {
toggleSection() { toggleSection() {
const { const {
unq, unq,
toggle toggle,
} = this.props; } = this.props;
toggle(unq); toggle(unq);
} }
@ -75,7 +75,7 @@ class PanelSection extends React.Component {
icon, icon,
children, children,
active, active,
className: propClasses className: propClasses,
} = this.props; } = this.props;
const contentStyles = { const contentStyles = {
@ -85,28 +85,28 @@ class PanelSection extends React.Component {
}; };
const triggerClasses = className('panel', { const triggerClasses = className('panel', {
active active,
}); });
const contentClasses = className('panel-collapse', { const contentClasses = className('panel-collapse', {
active active,
}); });
return( return(
<div className={triggerClasses}> <div className={ triggerClasses }>
<div <div
onClick={() => this.toggleSection()} onClick={ () => this.toggleSection() }
className="panel-heading"> className="panel-heading">
<a className="panel-title"> <a className="panel-title">
<i className={icon}></i> {title} <i className={ icon }></i> { title }
</a> </a>
</div> </div>
<div <div
className={contentClasses} className={ contentClasses }
style={contentStyles} style={ contentStyles }
ref={(ref) => this.accordionContent = ref}> ref={ (ref) => this.accordionContent = ref }>
<div className="panel-body"> <div className="panel-body">
{children} { children }
</div> </div>
</div> </div>
</div> </div>

21
react/src/components/dashboard/settings/settings.render.js

@ -20,18 +20,9 @@ import CoindClearDataDirPanel from './settings.coindClearDataDirPanel';
import Bip39KeysPanel from './settings.bip39KeysPanel'; import Bip39KeysPanel from './settings.bip39KeysPanel';
import mainWindow from '../../../util/mainWindow'; import mainWindow from '../../../util/mainWindow';
// import WalletInfoPanel from './settings.walletInfoPanel';
// import WalletBackupPanel from './settings.walletBackupPanel'; // import WalletBackupPanel from './settings.walletBackupPanel';
/* /*
{ !this.props.disableWalletSpecificUI &&
<PanelSection
title={ translate('INDEX.WALLET_INFO') }
icon="icon md-balance-wallet"
openByDefault={!this.props.disableWalletSpecificUI}>
<WalletInfoPanel />
</PanelSection>
}
{ !this.props.disableWalletSpecificUI && { !this.props.disableWalletSpecificUI &&
<PanelSection <PanelSection
title={ translate('INDEX.ADD_NODE') } title={ translate('INDEX.ADD_NODE') }
@ -71,13 +62,13 @@ export const SettingsRender = function() {
<div className="col-sm-12"> <div className="col-sm-12">
<h4 className="font-size-14 text-uppercase">{ translate('INDEX.WALLET_SETTINGS') }</h4> <h4 className="font-size-14 text-uppercase">{ translate('INDEX.WALLET_SETTINGS') }</h4>
<Panel <Panel
uniqId={'SettingsAccordion'} uniqId={ 'SettingsAccordion' }
singleOpen={true}> singleOpen={ true }>
{ mainWindow.arch === 'x64' && { mainWindow.arch === 'x64' &&
<PanelSection <PanelSection
title={ translate('INDEX.DEBUG_LOG') } title={ translate('INDEX.DEBUG_LOG') }
icon="icon fa-bug" icon="icon fa-bug"
openByDefault={this.props.disableWalletSpecificUI}> openByDefault={ this.props.disableWalletSpecificUI }>
<DebugLogPanel /> <DebugLogPanel />
</PanelSection> </PanelSection>
} }
@ -114,19 +105,19 @@ export const SettingsRender = function() {
} }
{ mainWindow.arch === 'x64' && { mainWindow.arch === 'x64' &&
<PanelSection <PanelSection
title={ 'Wallet.dat keys' } title={ `Wallet.dat ${translate('SETTINGS.KEYS_SM')}` }
icon="icon md-key"> icon="icon md-key">
<NativeWalletDatKeysPanel /> <NativeWalletDatKeysPanel />
</PanelSection> </PanelSection>
} }
<PanelSection <PanelSection
title="BIP39 Keys" title={ `BIP39 ${translate('SETTINGS.KEYS_CAP')}` }
icon="icon fa-usb"> icon="icon fa-usb">
<Bip39KeysPanel /> <Bip39KeysPanel />
</PanelSection> </PanelSection>
{ mainWindow.arch === 'x64' && { mainWindow.arch === 'x64' &&
<PanelSection <PanelSection
title={ 'Clear native coin data dir' } title={ translate('SETTINGS.CLEAR_NATIVE_DATADIR') }
icon="icon fa-trash"> icon="icon fa-trash">
<CoindClearDataDirPanel /> <CoindClearDataDirPanel />
</PanelSection> </PanelSection>

9
react/src/components/dashboard/settings/settings.supportPanel.js

@ -9,7 +9,6 @@ class SupportPanel extends React.Component {
openExternalWindow(url) { openExternalWindow(url) {
const remote = window.require('electron').remote; const remote = window.require('electron').remote;
const BrowserWindow = remote.BrowserWindow; const BrowserWindow = remote.BrowserWindow;
const externalWindow = new BrowserWindow({ const externalWindow = new BrowserWindow({
width: 1280, width: 1280,
height: 800, height: 800,
@ -18,8 +17,8 @@ class SupportPanel extends React.Component {
}); });
externalWindow.loadURL(url); externalWindow.loadURL(url);
externalWindow.webContents.on('did-finish-load', function() { externalWindow.webContents.on('did-finish-load', () => {
setTimeout(function() { setTimeout(() => {
externalWindow.show(); externalWindow.show();
}, 40); }, 40);
}); });
@ -65,12 +64,12 @@ class SupportPanel extends React.Component {
<div className="support-box-wrapper"> <div className="support-box-wrapper">
<div <div
className="support-box" className="support-box"
onClick={ () => this.openExternalWindow('https://github.com/SuperNETorg/Agama') }> onClick={ () => this.openExternalWindow('https://github.com/KomodoPlatform/Agama') }>
<img <img
src="assets/images/support/github-icon.png" src="assets/images/support/github-icon.png"
alt="Github" /> alt="Github" />
<div className="support-box-title">Github</div> <div className="support-box-title">Github</div>
<div className="support-box-link">github.com/SuperNETorg/Agama</div> <div className="support-box-link">github.com/KomodoPlatform/Agama</div>
</div> </div>
</div> </div>
</div> </div>

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

@ -346,7 +346,7 @@ class WalletsData extends React.Component {
.then((serverSetRes) => { .then((serverSetRes) => {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${this.props.ActiveCoin.coin} SPV server set to ${_randomServer.ip}:${_randomServer.port}`, `${this.props.ActiveCoin.coin} SPV {translate('DASHBOARD.SERVER_SET_TO')} ${_randomServer.ip}:${_randomServer.port}`,
translate('TOASTR.WALLET_NOTIFICATION'), translate('TOASTR.WALLET_NOTIFICATION'),
'success' 'success'
) )
@ -356,7 +356,7 @@ class WalletsData extends React.Component {
} else { } else {
Store.dispatch( Store.dispatch(
triggerToaster( triggerToaster(
`${this.props.ActiveCoin.coin} SPV server ${_randomServer.ip}:${_randomServer.port} is unreachable!`, `${this.props.ActiveCoin.coin} SPV {translate('DASHBOARD.SERVER_SM')} ${_randomServer.ip}:${_randomServer.port} {translate('DASHBOARD.IS_UNREACHABLE')}!`,
translate('TOASTR.WALLET_NOTIFICATION'), translate('TOASTR.WALLET_NOTIFICATION'),
'error' 'error'
) )
@ -416,9 +416,9 @@ class WalletsData extends React.Component {
{ translate('DASHBOARD.SPV_CONN_ERROR') } { translate('DASHBOARD.SPV_CONN_ERROR') }
</div> </div>
<div className={ this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].serverList !== 'none' ? '' : 'hide' }> <div className={ this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].serverList !== 'none' ? '' : 'hide' }>
<div className="color-warning">Trying to switch to another server...</div> <div className="color-warning">{ translate('DASHBOARD.SPV_AUTO_SWITCH') }...</div>
<br /> <br />
<strong>How to switch manually:</strong> <strong>{ translate('DASHBOARD.HOW_TO_SWITCH_MANUALLY') }:</strong>
<br/>{ translate('DASHBOARD.SPV_CONN_ERROR_P1') } <br/>{ translate('DASHBOARD.SPV_CONN_ERROR_P1') }
</div> </div>
</td> </td>
@ -435,7 +435,7 @@ class WalletsData extends React.Component {
this.setState(Object.assign({}, this.state, { this.setState(Object.assign({}, this.state, {
pageSize: pageSize, pageSize: pageSize,
showPagination: this.state.itemsList && this.state.itemsList.length >= this.state.defaultPageSize, showPagination: this.state.itemsList && this.state.itemsList.length >= this.state.defaultPageSize,
})) }));
} }
updateAddressSelection(address) { updateAddressSelection(address) {
@ -556,11 +556,11 @@ class WalletsData extends React.Component {
return true; return true;
} }
return this.contains(tx.address, term) return this.contains(tx.address, term) ||
|| this.contains(tx.confirmations, term) this.contains(tx.confirmations, term) ||
|| this.contains(tx.amount, term) this.contains(tx.amount, term) ||
|| this.contains(tx.type, term) this.contains(tx.type, term) ||
|| this.contains(secondsToString(tx.blocktime || tx.timestamp || tx.time), term); this.contains(secondsToString(tx.blocktime || tx.timestamp || tx.time), term);
} }
contains(value, property) { contains(value, property) {

56
react/src/components/dashboard/walletsInfo/walletsInfo.render.js

@ -22,115 +22,109 @@ const WalletsInfoRender = function() {
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>Address</td> <td>{ translate('WALLETS_INFO.ADDRESS') }</td>
<td> <td>
{ _netPeers[i].addr } { _netPeers[i].addr }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Address local</td> <td>{ translate('WALLETS_INFO.ADRESS_LOCAL') }</td>
<td> <td>
{ _netPeers[i].addrlocal } { _netPeers[i].addrlocal }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Services</td> <td>{ translate('WALLETS_INFO.SERVICES') }</td>
<td> <td>
{ _netPeers[i].services } { _netPeers[i].services }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Version</td> <td>{ translate('WALLETS_INFO.VERSION') }</td>
<td> <td>
{ _netPeers[i].version } { _netPeers[i].version }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Subversion</td> <td>{ translate('WALLETS_INFO.SUBVERSION') }</td>
<td> <td>
{ _netPeers[i].subver } { _netPeers[i].subver }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Whitelisted</td> <td>{ translate('WALLETS_INFO.WHITELISTED') }</td>
<td> <td>
{ _netPeers[i].whitelisted ? 'true' : 'false' } { _netPeers[i].whitelisted ? 'true' : 'false' }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Inbound</td> <td>{ translate('WALLETS_INFO.INBOUND') }</td>
<td> <td>
{ _netPeers[i].inbound ? 'true' : 'false' } { _netPeers[i].inbound ? 'true' : 'false' }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Time offset</td> <td>{ translate('WALLETS_INFO.TIME_OFFSET') }</td>
<td> <td>
{ _netPeers[i].timeoffset } { _netPeers[i].timeoffset }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Ping time</td> <td>{ translate('WALLETS_INFO.PING_TIME') }</td>
<td> <td>
{ _netPeers[i].pingtime } { _netPeers[i].pingtime }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Connection time</td> <td>{ translate('WALLETS_INFO.CONNECTION_TIME') }</td>
<td> <td>
{ secondsToString(_netPeers[i].conntime) } { secondsToString(_netPeers[i].conntime) }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Last send</td> <td>{ translate('WALLETS_INFO.LAST_SEND') }</td>
<td> <td>
{ secondsToString(_netPeers[i].lastsend) } { secondsToString(_netPeers[i].lastsend) }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Last received</td> <td>{ translate('WALLETS_INFO.LAST_RECEIVED') }</td>
<td> <td>
{ secondsToString(_netPeers[i].lastrecv) } { secondsToString(_netPeers[i].lastrecv) }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Data sent</td> <td>{ translate('WALLETS_INFO.DATA_SENT') }</td>
<td> <td>
{ formatBytes(_netPeers[i].bytessent) } { formatBytes(_netPeers[i].bytessent) }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Data received</td> <td>{ translate('WALLETS_INFO.DATA_RECEIVED') }</td>
<td> <td>
{ formatBytes(_netPeers[i].bytesrecv) } { formatBytes(_netPeers[i].bytesrecv) }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Ban score</td> <td>{ translate('WALLETS_INFO.BAN_SCORE') }</td>
<td> <td>
{ _netPeers[i].banscore } { _netPeers[i].banscore }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Starting height</td> <td>{ translate('WALLETS_INFO.STARTING_HEIGHT') }</td>
<td> <td>
{ _netPeers[i].startingheight } { _netPeers[i].startingheight }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Synced headers</td> <td>{ translate('WALLETS_INFO.SYNCED_HEADERS') }</td>
<td> <td>
{ _netPeers[i].synced_headers } { _netPeers[i].synced_headers }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Synced blocks</td> <td>{ translate('WALLETS_INFO.SYNCED_BLOCKS') }</td>
<td>
{ _netPeers[i].synced_blocks }
</td>
</tr>
<tr>
<td>Synced blocks</td>
<td> <td>
{ _netPeers[i].synced_blocks } { _netPeers[i].synced_blocks }
</td> </td>
@ -196,26 +190,26 @@ const WalletsInfoRender = function() {
} }
<div className="panel"> <div className="panel">
<div className="panel-heading"> <div className="panel-heading">
<h3 className="panel-title">Network totals</h3> <h3 className="panel-title">{ translate('WALLETS_INFO.NETWORK_TOTALS') }</h3>
</div> </div>
<div className="table-responsive"> <div className="table-responsive">
{ _netTotals && { _netTotals &&
<table className="table table-striped"> <table className="table table-striped">
<tbody> <tbody>
<tr> <tr>
<td>Time</td> <td>{ translate('WALLETS_INFO.TIME') }</td>
<td> <td>
{ secondsToString(_netTotals.timemillis, true) } { secondsToString(_netTotals.timemillis, true) }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Data received</td> <td>{ translate('WALLETS_INFO.DATA_RECEIVED') }</td>
<td> <td>
{ formatBytes(_netTotals.totalbytesrecv) } { formatBytes(_netTotals.totalbytesrecv) }
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Data sent</td> <td>{ translate('WALLETS_INFO.DATA_SENT') }</td>
<td> <td>
{ formatBytes(_netTotals.totalbytessent) } { formatBytes(_netTotals.totalbytessent) }
</td> </td>
@ -224,7 +218,7 @@ const WalletsInfoRender = function() {
</table> </table>
} }
{ !_netTotals && { !_netTotals &&
<div>Loading...</div> <div>{ translate('WALLETS_INFO.LOADING') }</div>
} }
</div> </div>
</div> </div>
@ -333,11 +327,11 @@ const WalletsInfoRender = function() {
<div className="panel"> <div className="panel">
<div className="panel-heading"> <div className="panel-heading">
<h3 className="panel-title"> <h3 className="panel-title">
Peers { translate('WALLETS_INFO.PEERS') }
</h3> </h3>
</div> </div>
{ !_netPeers && { !_netPeers &&
<div>Loading...</div> <div>{ translate('WALLETS_INFO.LOADING') }</div>
} }
{ _netPeers && { _netPeers &&
<div className="table-responsive"> <div className="table-responsive">

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

@ -33,8 +33,8 @@ class WalletsNav extends React.Component {
} }
checkTotalBalance() { checkTotalBalance() {
let _balance = '0';
const _mode = this.props.ActiveCoin.mode; const _mode = this.props.ActiveCoin.mode;
let _balance = '0';
if (this.props.ActiveCoin.balance && if (this.props.ActiveCoin.balance &&
this.props.ActiveCoin.balance.total && this.props.ActiveCoin.balance.total &&

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

@ -170,11 +170,11 @@ const LoginRender = function() {
className="login-option" className="login-option"
value="">{ translate('INDEX.SELECT') }</option> value="">{ translate('INDEX.SELECT') }</option>
{ this.props.Login.pinList.map((pin) => { { this.props.Login.pinList.map((pin) => {
return <option return <option
className="login-option" className="login-option"
value={pin} value={pin}
key={pin}>{ pin }</option> key={pin}>{ pin }</option>
}) })
} }
</select> </select>
</div> </div>
@ -311,7 +311,8 @@ const LoginRender = function() {
value={ this.state.randomSeed } value={ this.state.randomSeed }
onChange={ (e) => this.updateWalletSeed(e) } onChange={ (e) => this.updateWalletSeed(e) }
readOnly={ !this.isCustomWalletSeed() }></textarea> readOnly={ !this.isCustomWalletSeed() }></textarea>
<button className="copy-floating-label" <button
className="copy-floating-label"
htmlFor="walletseed" htmlFor="walletseed"
onClick={ () => this.copyPassPhraseToClipboard() }>{ translate('INDEX.COPY') }</button> onClick={ () => this.copyPassPhraseToClipboard() }>{ translate('INDEX.COPY') }</button>
<span className={ this.state.isCustomSeedWeak ? 'tooltiptext' : 'hide' }> <span className={ this.state.isCustomSeedWeak ? 'tooltiptext' : 'hide' }>

3
react/src/components/main/main.js

@ -23,6 +23,9 @@ class Main extends React.Component {
if (appVersion) { if (appVersion) {
document.title = `${appVersion.name} (v${appVersion.version.replace('version=', '')}${mainWindow.arch === 'x64' ? '' : '-32bit'}-beta)`; document.title = `${appVersion.name} (v${appVersion.version.replace('version=', '')}${mainWindow.arch === 'x64' ? '' : '-32bit'}-beta)`;
} }
document.addEventListener('dragover', event => event.preventDefault());
document.addEventListener('drop', event => event.preventDefault());
} }
componentWillMount() { componentWillMount() {

79
react/src/translate/en.js

@ -2,6 +2,30 @@
export const _lang = { export const _lang = {
'EN': { 'EN': {
'WALLETS_INFO': {
'ADDRESS': 'Address',
'ADDRESS_LOCAL': 'Address local',
'SERVICES': 'Services',
'VERSION': 'Version',
'SUBVERSION': 'Subversion',
'WHITELISTED': 'Whitelisted',
'INBOUND': 'Inbound',
'TIME_OFFSET': 'Time offset',
'PING_TIME': 'Ping time',
'CONNECTION_TIME': 'Connection time',
'LAST_SEND': 'Last send',
'LAST_RECEIVED': 'Last received',
'DATA_SENT': 'Data sent',
'DATA_RECEIVED': 'Data received',
'BAN_SCORE': 'Ban score',
'STARTING_HEIGHT': 'Starting height',
'SYNCED_HEADERS': 'Synced headers',
'SYNCED_BLOCKS': 'Synced blocks',
'NETWORK_TOTALS': 'Network totals',
'TIME': 'Time',
'PEERS': 'Peers',
'LOADING': 'Loading...',
},
'IMPORT_KEY': { 'IMPORT_KEY': {
'IMPORT': 'Import', 'IMPORT': 'Import',
'IMPORT_KEY': 'Import key', 'IMPORT_KEY': 'Import key',
@ -56,6 +80,7 @@ export const _lang = {
'GET_AN_INVITE_P2': 'to our slack if you\'re not registered yet' 'GET_AN_INVITE_P2': 'to our slack if you\'re not registered yet'
}, },
'API': { 'API': {
'DAEMON_IS_STILL_RUNNING': 'daemon is still running. If you want to completely stop it and remove use stop icon next time.',
'CONN_ERROR': 'Connection error', 'CONN_ERROR': 'Connection error',
'KMD_PASSIVE_ERROR': 'Please make sure to run komodod manually', 'KMD_PASSIVE_ERROR': 'Please make sure to run komodod manually',
'ERROR_SM': 'error', 'ERROR_SM': 'error',
@ -72,6 +97,8 @@ export const _lang = {
'NO_ACTIVE_COIN': 'No active coin', 'NO_ACTIVE_COIN': 'No active coin',
}, },
'INDEX': { 'INDEX': {
'ERROR_READING': 'Error reading',
'SHOW': 'Show',
'SPV_SERVER_IP': 'Server IP', 'SPV_SERVER_IP': 'Server IP',
'SPV_SERVER_PORT': 'Server Port', 'SPV_SERVER_PORT': 'Server Port',
'SPV_SERVER_CON_TYPE': 'Connection type', 'SPV_SERVER_CON_TYPE': 'Connection type',
@ -336,6 +363,9 @@ export const _lang = {
'LITE_MODE_DESC': 'Lite mode doesn\'t require any blockchain to be loaded locally. All data is requested on demand from Electrum servers. Lite mode has higher network latency compared to native mode.', 'LITE_MODE_DESC': 'Lite mode doesn\'t require any blockchain to be loaded locally. All data is requested on demand from Electrum servers. Lite mode has higher network latency compared to native mode.',
}, },
'JUMBLR': { 'JUMBLR': {
'PASSPHRASE': 'Passphrase',
'PAUSE': 'Pause',
'STOP': 'Stop',
'TO_SM': 'to', 'TO_SM': 'to',
'ABOUT': 'About Jumblr', 'ABOUT': 'About Jumblr',
'JUMBLR_FUNCTIONS': 'Jumblr functions all locally which means no middle man is required to jumble your funds. ' + 'JUMBLR_FUNCTIONS': 'Jumblr functions all locally which means no middle man is required to jumble your funds. ' +
@ -434,6 +464,18 @@ export const _lang = {
'ERROR': 'Error', 'ERROR': 'Error',
}, },
'DASHBOARD': { 'DASHBOARD': {
'RPC_CONN_FAILURE': 'Unable to establish RPC connection! Retries count',
'REMOVE': 'Remove',
'STOP': 'Stop',
'SOFT_LOGOUT': 'Soft logout',
'COMPLETE_LOGOUT': 'Complete logout',
'GENERATE_SM': 'generate',
'RECEIVE_ADDR_COPIED': 'address copied to clipboard',
'SERVER_SM': 'server',
'IS_UNREACHABLE': 'is unreachable',
'SERVER_SET_TO': 'server is set to',
'SPV_AUTO_SWITCH': 'Trying to switch to another server',
'HOW_TO_SWITCH_MANUALLY': 'How to switch manually',
'SELECT_ADDRESS': '- Select Address -', 'SELECT_ADDRESS': '- Select Address -',
'SEND_TOADDR_REQ': 'To Address is required.', 'SEND_TOADDR_REQ': 'To Address is required.',
'SEND_FROMADDR_REQ': 'From Address is required.', 'SEND_FROMADDR_REQ': 'From Address is required.',
@ -471,6 +513,15 @@ export const _lang = {
'CURRENT_BLOCK_SM': 'current block', 'CURRENT_BLOCK_SM': 'current block',
}, },
'TOASTR': { 'TOASTR': {
'ERROR': 'Error',
'FAILED_TO_VERIFY_ADDR': 'Failed to verify address',
'COIN_UNABLE_TO_STOP': 'Unable to stop @template@. Try again.',
'COIN_IS_STOPED': 'is stopped',
'COIN_IS_REMOVED': 'is removed',
'JUMBLR_RESUMED': 'Jumblr resumed',
'JUMBLR_PAUSED': 'Jumblr paused',
'DATADIR_UNABLE_TO_CLEAR': 'Unable to clear',
'DATADIR_CLEARED': 'data folder is cleared',
'PORT_IS_TAKEN': 'Port @template@ is already taken!', 'PORT_IS_TAKEN': 'Port @template@ is already taken!',
'ERROR_STARTING_DAEMON': 'Error starting @template@ daemon.', 'ERROR_STARTING_DAEMON': 'Error starting @template@ daemon.',
'KOMODO_DATADIR_INVALID': 'Komodo datadir path is invalid.<br>It must be an absolute path to an existing folder that doesn\'t contain spaces and/or any special characters.', 'KOMODO_DATADIR_INVALID': 'Komodo datadir path is invalid.<br>It must be an absolute path to an existing folder that doesn\'t contain spaces and/or any special characters.',
@ -602,6 +653,30 @@ export const _lang = {
'JUMBLR_MOTTO': 'Secure, Native and Decentralised Coin Anonymizer', 'JUMBLR_MOTTO': 'Secure, Native and Decentralised Coin Anonymizer',
}, },
'SETTINGS': { 'SETTINGS': {
'DAEMON_PORTS': 'Daemon ports',
'KEY_IS_NOT_FOUND': 'Key is not found',
'ADDRESSES_SM': 'addresses',
'ACCOUNT_SM': 'account',
'ACCOUNTS_SM': 'accounts',
'GET_KEY': 'Get key',
'DATADIR_DELETE_PROMPT': 'Are you sure you want to clear @template@ data folder?',
'YES': 'Yes',
'NO': 'No',
'KEEP': 'Keep',
'DELETE': 'Delete',
'COIND_DELETING': 'Deleting @template@ data..',
'COIND_DATADIR_CLEAR_P1': 'Warning: the following form will wipe out all native coin data!',
'COIND_DATADIR_CLEAR_P2': 'Don\'t touch anything if you\'re not sure what you\'re doing.',
'GET_KEYS': 'Get keys',
'FETCHING_KEYS': 'Fetching keys',
'SEARCH_KEY_PATTERN': 'Search key pattern',
'ADDRESS': 'Address',
'KEYS_SM': 'keys',
'FOUND': 'Found',
'PICK_A_COIN': 'Pick a coin',
'CLEAR_NATIVE_DATADIR': 'Clear native coin data dir',
'KEYS_SM': 'keys',
'KEYS_CAP': 'Keys',
'BIP39_DISC': 'Hardware wallets disclaimer: by using this form you\'re acknowledging risks of exposing your seed', 'BIP39_DISC': 'Hardware wallets disclaimer: by using this form you\'re acknowledging risks of exposing your seed',
'BIP39_DESC_P1': 'Description: the form below is going to search for a pub key depending on a range of key path combinations is chosen (No of accounts * account address path depth).', 'BIP39_DESC_P1': 'Description: the form below is going to search for a pub key depending on a range of key path combinations is chosen (No of accounts * account address path depth).',
'BIP39_DESC_P2': 'The app might temporary freeze for several seconds during search procedure.', 'BIP39_DESC_P2': 'The app might temporary freeze for several seconds during search procedure.',
@ -662,6 +737,10 @@ export const _lang = {
'DOWNLOAD': 'Download', 'DOWNLOAD': 'Download',
}, },
'SEND': { 'SEND': {
'MIN_AMOUNT_IS': 'min @template@ amount is',
'AMOUNT_IS_TOO_SMALL': 'Amount @template@ is too small',
'MAX_AVAIL_BALANCE': 'max available balance is',
'TXID_COPIED': 'TXID copied to clipboard',
'RESULT': 'Result', 'RESULT': 'Result',
'PROCESSING_TX': 'Processing transaction', 'PROCESSING_TX': 'Processing transaction',
'TRANSACTION_ID': 'Transaction ID', 'TRANSACTION_ID': 'Transaction ID',

6
react/src/util/coinHelper.js

@ -6,6 +6,10 @@ export function getCoinTitle(coin) {
let hideTitle = false; let hideTitle = false;
switch (coin) { switch (coin) {
case 'HUSH':
coinlogo = 'hush';
coinname = 'Hush';
break;
case 'BCH': case 'BCH':
coinlogo = 'bch'; coinlogo = 'bch';
coinname = 'BitcoinCash'; coinname = 'BitcoinCash';
@ -75,7 +79,7 @@ export function getCoinTitle(coin) {
coinname = 'Syscoin'; coinname = 'Syscoin';
break; break;
case 'ZEC': case 'ZEC':
coinlogo = 'zcash'; coinlogo = 'zec';
coinname = 'Zcash'; coinname = 'Zcash';
break; break;
case 'NMC': case 'NMC':

Loading…
Cancel
Save