Browse Source

add coin shortcuts

v0.25
pbca26 7 years ago
parent
commit
ba4bcc92fd
  1. 297
      assets/mainWindow/js/loading.js
  2. 1
      react/package.json
  3. 35
      react/src/components/addcoin/addcoin.scss
  4. 103
      react/src/components/login/login.js
  5. 65
      react/src/components/login/login.render.js
  6. 48
      react/src/components/login/login.scss
  7. 42
      react/src/components/overrides.scss
  8. 5
      react/src/translate/en.js

297
assets/mainWindow/js/loading.js

@ -1,303 +1,6 @@
// TODO: merge into react app
let _configCopy;
function toggleMainWindowHelp() {
const _help = $('.agama-modes-help');
if (_help.is(':visible')) {
_help.hide();
} else {
_help.show();
}
}
function toggleDropdown(type) {
const _dropdown = $('.dropdown-menu.' + (type === 'lite' ? 'lite' : 'native'));
if (_dropdown.hasClass('hide')) {
_dropdown.removeClass('hide');
} else {
_dropdown.addClass('hide');
}
$('.dropdown-menu.' + (type === 'lite' ? 'native' : 'lite')).addClass('hide');
}
function initSettingsForm() {
const remote = require('electron').remote;
let appConf = remote.getCurrentWindow().appConfig;
let appConfSchema = remote.getCurrentWindow().appConfigSchema;
_configCopy = Object.assign({}, appConf);
let _htmlOut = '<table class="settings-table">';
for (let key in appConf) {
if (appConfSchema[key] &&
appConfSchema[key].initDisplay) {
_htmlOut = `
${_htmlOut}
<tr>
<td class="left">
${appConfSchema[key].displayName}`;
if (appConfSchema[key].info) {
_htmlOut = `
${_htmlOut}
<div
class="settings-help"
title="${appConfSchema[key].info}">
<img src="../EasyDEX-GUI/assets/mainWindow/img/fa-question.png" />
</div>`;
}
if (appConfSchema[key].type === 'number') {
_htmlOut = `
${_htmlOut}
</td>
<td class="right">
<input
type="number"
id="${key}"
pattern="[0-9]*"
onKeyup="handleInput('${key}')"
value="${_configCopy[key]}" />
</td>
</tr>`;
} else if (appConfSchema[key].type === 'string' || appConfSchema[key].type === 'folder') {
_htmlOut = `
${_htmlOut}
</td>
<td class="right">
<input
type="text"
id="${key}"
onKeyup="handleInput('${key}')"
value="${_configCopy[key]}" />
</td>
</tr>`;
} else if (appConfSchema[key].type === 'boolean') {
_htmlOut = `${_htmlOut}
</td>
<td class="right">
<label
class="switch"
id="${key}"
onClick="settingsToggle(\'${key}\')">
${(appConf[key] ? '<input type="checkbox" class="cb" checked />' : '<input type="checkbox" class="cb" />')}
<div class="slider"></div>
</label>
</td>
</tr>`;
}
}
}
_htmlOut = `
${_htmlOut}
</table>`;
$('#agamaConfigBlock').html(_htmlOut);
}
function hideToastImmediate() {
$('#toast-container').addClass('hide');
}
function hideToast() {
setTimeout(function() {
$('#toast-container').addClass('hide');
}, 5000);
}
function showToast(type, message) {
$('#toast-container .toast').removeClass('toast-success').removeClass('toast-error');
$('#toast-container .toast').addClass(`toast-${type}`);
$('#toast-container .toast-message').html(message);
$('#toast-container').removeClass('hide');
hideToast();
}
function setDefaultAppSettings() {
const remote = require('electron').remote;
remote.getCurrentWindow().setDefaultAppSettings();
remote.getCurrentWindow().appConfig = remote.getCurrentWindow().defaultAppSettings;
initSettingsForm();
showToast('success', 'App settings are reset to default');
}
function testBins(binName) {
const remote = require('electron').remote;
remote.getCurrentWindow().testBins(binName).
then(function(res) {
$('#debugOut').html(JSON.stringify(res, null, '\t'));
});
}
function handleSaveSettings() {
if (_configCopy.dataDir &&
_configCopy.dataDir.length) {
const remote = require('electron').remote;
remote.getCurrentWindow().testLocation(_configCopy.dataDir)
.then(function(res) {
if (res === -1) {
showToast('error', '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.');
} else if (res === false) {
showToast('error', 'Komodo datadir path is not a directory.<br>It must be an absolute path to an existing folder that doesn\'t contain spaces and/or any special characters.');
} else {
// save settings
remote.getCurrentWindow().updateAppSettings(_configCopy);
remote.getCurrentWindow().appConfig = _configCopy;
showToast('success', 'Settings saved');
}
});
} else {
// save settings
const remote = require('electron').remote;
remote.getCurrentWindow().updateAppSettings(_configCopy);
remote.getCurrentWindow().appConfig = _configCopy;
showToast('success', 'Settings saved');
}
}
function handleInput(key) {
const _value = $(`#${key}`).val();
_configCopy[key] = _value;
}
function settingsToggle(key) {
const _value = $(`#${key} .cb`).prop('checked');
_configCopy[key] = _value;
}
function closeSettingsWindow() {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
toggleDropdown();
window.destroyAppSettingsWindow();
}
function reloadSettingsWindow() {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
window.reloadSettingsWindow();
}
function openSettingsWindow() {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
$('.dropdown-menu.lite').addClass('hide');
$('.dropdown-menu.native').addClass('hide');
window.createAppSettingsWindow();
}
function startKMDPassive() {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
$('.dropdown-menu.lite').addClass('hide');
$('.dropdown-menu.native').addClass('hide');
disableModeButtons();
window.startKMDNative('KMD', true);
window.createWindow('open');
window.hide();
}
function startKMDPassive() {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
$('.dropdown-menu.lite').addClass('hide');
$('.dropdown-menu.native').addClass('hide');
disableModeButtons();
window.startKMDNative('KMD', true);
window.createWindow('open');
window.hide();
}
function startSPV(coin) {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
$('.dropdown-menu.lite').addClass('hide');
$('.dropdown-menu.native').addClass('hide');
disableModeButtons();
window.startSPV(coin);
window.createWindow('open');
window.hide();
}
function closeMainWindow(isKmdOnly, isCustom) {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
$('.dropdown-menu.lite').addClass('hide');
$('.dropdown-menu.native').addClass('hide');
disableModeButtons();
if (!isCustom) {
window.startKMDNative(isKmdOnly ? 'KMD' : null);
setTimeout(function() {
window.createWindow('open');
window.hide();
}, 3000);
} else {
window.createWindow('open');
window.hide();
}
}
function quitApp() {
const remote = require('electron').remote;
const window = remote.getCurrentWindow();
window.forseCloseApp();
}
function disableModeButtons() {
$('#nativeOnlyBtn').attr('disabled', true);
$('#normalStartBtn').attr('disabled', true);
$('#settingsBtn').attr('disabled', true);
$('#nativeOnlyBtnCarret').attr('disabled', true);
$('#spvBtn').attr('disabled', true);
$('#spvBtnCarret').attr('disabled', true);
}
function normalStart() {
const remote = require('electron').remote;
let appConf = remote.getCurrentWindow().appConfig;
appConf.iguanaLessMode = false;
$('.dropdown-menu.lite').addClass('hide');
$('.dropdown-menu.native').addClass('hide');
disableModeButtons();
}
function init() {
const remote = require('electron').remote;
var window = remote.getCurrentWindow();
var appConf = remote.getCurrentWindow().appConfig;
var arch = remote.getCurrentWindow().arch;
if (arch !== 'x64') {
$('.settings-help').hide();
$('#agamaModeStatusText').html('Choose a shortcut or custom selection');
$('#settingsBtn').hide();
$('.mode-desc.native').hide();
$('#nativeOnlyBtn').hide();
$('#nativeOnlyBtnCarret').hide();
$('.mode-desc.spv').css('left', '200px');
$('.dropdown-menu.lite').css('left', '180px');
}
}

1
react/package.json

@ -47,6 +47,7 @@
"react-router-redux": "^4.0.4",
"react-select": "^1.1.0",
"react-table": "~6.5.1",
"react-tooltip": "^3.4.0",
"react-transform-catch-errors": "^1.0.2",
"react-transform-hmr": "^1.0.4",
"redux": "^3.6.0",

35
react/src/components/addcoin/addcoin.scss

@ -38,41 +38,6 @@
}
}
}
.Select {
cursor: pointer;
* { color: #757575 !important; }
.Select-clear {
display: none;
}
.Select-control {
height: 40px !important;
.Select-placeholder,
.Select-value {
line-height: 36px !important;
}
}
}
.Select-menu-outer {
max-height: 253px !important;
}
.Select-menu {
max-height: 250px !important;
}
.Select.is-open,
.Select.is-focused {
.Select-control {
border-color: #FF6600 !important;
box-shadow: none !important;
}
.Select-menu-outer {
border-color: #FF6600 !important;
border-top-color: #d9d9d9 !important;
}
}
}
.vertical-margin-20 {

103
react/src/components/login/login.js

@ -10,10 +10,13 @@ import {
toggleLoginSettingsModal,
stopInterval,
dashboardChangeActiveCoin,
toggleZcparamsFetchModal,
activeHandle,
} from '../../actions/actionCreators';
import Config from '../../config';
import Store from '../../store';
import { PassPhraseGenerator } from '../../util/crypto/passphrasegenerator';
import { zcashParamsCheckErrors } from '../../util/zcashParams';
import SwallModalRender from './swall-modal.render';
import LoginRender from './login.render';
import { translate } from '../../translate/translate';
@ -57,6 +60,8 @@ class Login extends React.Component {
selectedPin: '',
isExperimentalOn: false,
enableEncryptSeed: false,
selectedShortcutNative: '',
selectedShortcutSPV: '',
};
this.toggleActivateCoinForm = this.toggleActivateCoinForm.bind(this);
this.updateRegisterConfirmPassPhraseInput = this.updateRegisterConfirmPassPhraseInput.bind(this);
@ -73,6 +78,7 @@ class Login extends React.Component {
this.updatePubKey = this.updatePubKey.bind(this);
this.updateDecryptKey = this.updateDecryptKey.bind(this);
this.loadPinList = this.loadPinList.bind(this);
this.updateSelectedShortcut = this.updateSelectedShortcut.bind(this);
}
// the setInterval handler for 'activeCoins'
@ -452,6 +458,68 @@ class Login extends React.Component {
);
}
updateSelectedShortcut(e, type) {
this.setState({
[type === 'native' ? 'selectedShortcutNative' : 'selectedShortcutSPV'] : e.value,
});
if (type === 'native') {
const _res = mainWindow.zcashParamsExist;
const __errors = zcashParamsCheckErrors(_res);
if (__errors) {
mainWindow.zcashParamsExistPromise()
.then((res) => {
const _errors = zcashParamsCheckErrors(res);
mainWindow.zcashParamsExist = res;
if (_errors) {
Store.dispatch(
triggerToaster(
_errors,
'Komodod',
'error',
false
)
);
Store.dispatch(toggleZcparamsFetchModal(true));
} else {
mainWindow.startKMDNative(e.value.toUpperCase());
}
});
} else {
mainWindow.startKMDNative(e.value.toUpperCase());
}
console.warn('native');
} else {
mainWindow.startSPV(e.value.toUpperCase());
console.warn('spv');
}
setTimeout(() => {
Store.dispatch(activeHandle());
if (type === 'native') {
Store.dispatch(shepherdElectrumCoins());
}
Store.dispatch(getDexCoins());
}, 500);
setTimeout(() => {
Store.dispatch(activeHandle());
if (type === 'native') {
Store.dispatch(shepherdElectrumCoins());
}
Store.dispatch(getDexCoins());
}, 1000);
setTimeout(() => {
Store.dispatch(activeHandle());
if (type === 'native') {
Store.dispatch(shepherdElectrumCoins());
}
Store.dispatch(getDexCoins());
}, type === 'native' ? 5000 : 2000);
}
renderSwallModal() {
if (this.state.displaySeedBackupModal) {
return SwallModalRender.call(this);
@ -460,6 +528,41 @@ class Login extends React.Component {
return null;
}
renderShortcutOption(option) {
if (option.value.indexOf('+') > -1) {
const _comps = option.value.split('+');
let _items = [];
for (let i = 0; i < _comps.length; i++) {
_items.push(
<span key={ `addcoin-shortcut-icons-${i}` }>
<img
src={ `assets/images/cryptologo/${_comps[i].toLowerCase()}.png` }
alt={ _comps[i].toUpperCase() }
width="30px"
height="30px" />
{ i !== _comps.length - 1 &&
<span className="margin-left-10 margin-right-10">+</span>
}
</span>
);
}
return _items;
} else {
return (
<div>
<img
src={ `assets/images/cryptologo/${option.value.toLowerCase()}.png` }
alt={ option.value.toUpperCase() }
width="30px"
height="30px" />
<span className="margin-left-10">{ option.value.toUpperCase() }</span>
</div>
);
}
}
render() {
if ((this.state && this.state.display) ||
!this.props.Main) {

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

@ -2,6 +2,8 @@ import React from 'react';
import { translate } from '../../translate/translate';
import LoginSettingsModal from '../dashboard/loginSettingsModal/loginSettingsModal';
import ZcparamsFetchModal from '../dashboard/zcparamsFetchModal/zcparamsFetchModal';
import Select from 'react-select';
import ReactTooltip from 'react-tooltip';
const LoginRender = function() {
return (
@ -142,7 +144,8 @@ const LoginRender = function() {
<hr/>
</div>
<div className="pin-block-two">
<span>{ translate('INDEX.OR') }</span></div>
<span>{ translate('INDEX.OR') }</span>
</div>
<div className="pin-block-three">
<hr/>
</div>
@ -187,12 +190,16 @@ const LoginRender = function() {
type="button"
className="btn btn-primary btn-block margin-top-20"
onClick={ this.loginSeed }
disabled={ !this.state.loginPassphrase || !this.state.loginPassphrase.length }>{ translate('INDEX.SIGN_IN') }</button>
disabled={ !this.state.loginPassphrase || !this.state.loginPassphrase.length }>
{ translate('INDEX.SIGN_IN') }
</button>
<div className="form-group form-material floating">
<button
className="btn btn-lg btn-flat btn-block waves-effect"
id="register-btn"
onClick={ () => this.updateActiveLoginSection('signup') }>{ translate('INDEX.CREATE_WALLET') }</button>
onClick={ () => this.updateActiveLoginSection('signup') }>
{ translate('INDEX.CREATE_WALLET') }
</button>
<button
className="btn btn-lg btn-flat btn-block waves-effect hide"
id="logint-another-wallet">{ translate('INDEX.LOGIN_ANOTHER_WALLET') }</button>
@ -221,6 +228,58 @@ const LoginRender = function() {
{ translate('INDEX.ACTIVATE_COIN') }
</span>
</button>
<div className="line">{ translate('LOGIN.OR_USE_A_SHORTCUT') }</div>
<div className="addcoin-shortcut">
<div>
<i className="icon fa-cube margin-right-5"></i>
{ translate('INDEX.NATIVE_MODE') }
<i
className="icon fa-question-circle login-help"
data-tip="<strong>Be aware:</strong> <u>Native mode</u> requires to download the whole blockchain data to a local disk before you can start using it.<br/>This may take from <strong>several hours to a day</strong> depending on your connection and hardware.<br/>Please <u>try to keep Agama running</u> until the whole process is finished."
data-html={ true }></i>
<ReactTooltip effect="solid" className="text-left" />
</div>
<Select
name="selectedShortcutNative"
value={ this.state.selectedShortcutNative }
onChange={ (event) => this.updateSelectedShortcut(event, 'native') }
optionRenderer={ this.renderShortcutOption }
valueRenderer={ this.renderShortcutOption }
options={[
{ value: 'kmd', label: 'kmd' },
{ value: 'mnz', label: 'mnz' },
{ value: 'btch', label: 'btch' },
{ value: 'revs', label: 'revs' },
{ value: 'jumblr', label: 'jumblr' },
{ value: 'kmd+revs+jumblr', label: 'kmd+revs+jumblr' },
]} />
</div>
<div className="addcoin-shortcut">
<div>
<i className="icon fa-flash margin-right-5"></i>
{ translate('INDEX.SPV_MODE') }
<i
className="icon fa-question-circle login-help"
data-tip="If you need a quick and easy access to your funds try <u>Lite (SPV) mode</u> which doesn't require any blockchain to be loaded locally.<br/>All data is requested on demand from Electrum servers."
data-html={ true }></i>
<ReactTooltip effect="solid" className="text-left" />
</div>
<Select
name="selectedShortcutSPV"
value={ this.state.selectedShortcutSPV }
onChange={ (event) => this.updateSelectedShortcut(event, 'spv') }
optionRenderer={ this.renderShortcutOption }
valueRenderer={ this.renderShortcutOption }
options={[
{ value: 'kmd', label: 'kmd' },
{ value: 'chips', label: 'chips' },
{ value: 'btch', label: 'btch' },
{ value: 'mnz', label: 'mnz' },
{ value: 'revs', label: 'revs' },
{ value: 'jumblr', label: 'jumblr' },
{ value: 'kmd+revs+jumblr', label: 'kmd+revs+jumblr' },
]} />
</div>
</div>
</div>

48
react/src/components/login/login.scss

@ -184,4 +184,52 @@ option.login-option {
.pin-block-three {
width: 10%;
float: left;
}
.page-login {
.addcoin-shortcut {
display: inline-block;
width: 46%;
&:last-child {
margin-left: 8%;
}
> div {
margin-bottom: 10px;
}
}
.line {
padding: 60px 0 40px 0;
text-transform: uppercase;
font-weight: bold;
white-space: nowrap;
&:before {
content: '';
display: inline-block;
height: 1px;
width: 33%;
background: #ccc;
margin-right: 10px;
position: relative;
top: -4px;
}
&:after {
content: '';
display: inline-block;
height: 1px;
width: 33%;
background: #ccc;
margin-left: 10px;
position: relative;
top: -4px;
}
}
.login-help {
font-size: 20px;
position: relative;
top: 2px;
left: 15px;
color: #fff;
}
}

42
react/src/components/overrides.scss

@ -282,4 +282,46 @@ select{
.no-margin {
margin: 0 !important;
}
.Select {
cursor: pointer;
text-align: left;
* { color: #757575 !important; }
.Select-clear {
display: none;
}
.Select-control {
height: 40px !important;
.Select-placeholder,
.Select-value {
line-height: 36px !important;
}
}
}
.Select-menu-outer {
max-height: 253px !important;
}
.Select-menu {
max-height: 250px !important;
}
.Select.is-open,
.Select.is-focused {
.Select-control {
border-color: #FF6600 !important;
box-shadow: none !important;
}
.Select-menu-outer {
border-color: #FF6600 !important;
border-top-color: #d9d9d9 !important;
}
}
.__react_component_tooltip {
&.type-dark {
background-color: #000;
}
}

5
react/src/translate/en.js

@ -626,6 +626,7 @@ export const LANG_EN = {
'ZCASH_PARAMS_MISSING_VERIFYING_KEY_SIZE': '- verifying key size is incorrect',
},
'LOGIN': {
'OR_USE_A_SHORTCUT': 'or use a shortcut',
'PIN_LOGIN_INFO': 'You can login be entering a login seed or by selecting a pin',
'QUICK_ACCESS': 'Quick access',
'PWD_REQ': 'Password is required.',
@ -742,6 +743,10 @@ export const LANG_EN = {
'DOWNLOAD': 'Download',
},
'SEND': {
'BAD_TXN_SPENT_ERR1': 'This particular error can happen in the following cases:',
'BAD_TXN_SPENT_ERR2': 'Your machine\'s clock is not set properly',
'BAD_TXN_SPENT_ERR3': 'SPV server is temporary out of sync. Try to switch over to another one.',
'BAD_TXN_SPENT_ERR4': 'Double spend in case you just made another transaction',
'MIN_AMOUNT_IS': 'min @template@ amount is',
'AMOUNT_IS_TOO_SMALL': 'Amount @template@ is too small',
'MAX_AVAIL_BALANCE': 'max available balance is',

Loading…
Cancel
Save