+
+
+
{ translate('INDEX.IMPORT_KEYS_DESC_P1') }
+
{ translate('INDEX.IMPORT_KEYS_DESC_P2') }
+
{ translate('INDEX.IMPORT_KEYS_DESC_P3') }
+
+
+ { translate('INDEX.PLEASE_KEEP_KEYS_SAFE') }
+
+
-
-
+
+
);
}
diff --git a/react/src/components/dashboard/settings/settings.js b/react/src/components/dashboard/settings/settings.js
index 32c276d..25a37e2 100644
--- a/react/src/components/dashboard/settings/settings.js
+++ b/react/src/components/dashboard/settings/settings.js
@@ -1,15 +1,10 @@
import React from 'react';
import { connect } from 'react-redux';
import { translate } from '../../../translate/translate';
-import Config from '../../../config';
import {
iguanaActiveHandle,
getAppConfig,
- getPeersList,
- addPeerNode,
getAppInfo,
- shepherdCli,
- triggerToaster,
} from '../../../actions/actionCreators';
import Store from '../../../store';
@@ -17,19 +12,6 @@ import {
SettingsRender,
} from './settings.render';
-import AppUpdatePanel from './settings.appUpdatePanel';
-import AppInfoPanel from './settings.appInfoPanel';
-import AddNodePanel from './settings.addNodePanel';
-import AppSettingsPanel from './settings.appSettingsPanel';
-import CliPanel from './settings.cliPanel';
-import DebugLogPanel from './settings.debugLogPanel';
-import FiatCurrencyPanel from './settings.fiatCurrencyPanel';
-import ExportKeysPanel from './settings.exportKeysPanel';
-import ImportKeysPanel from './settings.importKeysPanel';
-import SupportPanel from './settings.supportPanel';
-import WalletInfoPanel from './settings.walletInfoPanel';
-import WalletBackupPanel from './settings.walletBackupPanel';
-
/*
TODO:
1) pre-select active coin in add node tab
@@ -38,105 +20,20 @@ import WalletBackupPanel from './settings.walletBackupPanel';
4) batch export/import wallet addresses
*/
class Settings extends React.Component {
- constructor() {
- super();
- this.state = {
- activeTab: 0,
- tabElId: null,
- seedInputVisibility: false,
- nativeOnly: Config.iguanaLessMode,
- disableWalletSpecificUI: false,
- };
- this.updateInput = this.updateInput.bind(this);
+ constructor(props) {
+ super(props);
}
componentDidMount(props) {
if (!this.props.disableWalletSpecificUI) {
Store.dispatch(iguanaActiveHandle());
}
-
Store.dispatch(getAppConfig());
Store.dispatch(getAppInfo());
document.getElementById('section-iguana-wallet-settings').setAttribute('style', 'height:auto; min-height: 100%');
}
- componentWillReceiveProps(props) {
- if (this.state.tabElId) {
- this.setState(Object.assign({}, this.state, {
- activeTab: this.state.activeTab,
- tabElId: this.state.tabElId,
- disableWalletSpecificUI: this.props.disableWalletSpecificUI,
- }));
- }
- }
-
- openTab(elemId, tab) {
- this.setState(Object.assign({}, this.state, {
- activeTab: tab,
- tabElId: elemId,
- }));
- }
-
- updateInput(e) {
- this.setState({
- [e.target.name]: e.target.value,
- });
- }
-
- renderAppInfoTab() {
- const releaseInfo = this.props.Settings.appInfo && this.props.Settings.appInfo.releaseInfo;
-
- if (releaseInfo) {
- return
- }
-
- return null;
- }
-
- renderAppUpdateTab() {
- return
- }
-
- renderWalletInfo() {
- return
- }
- renderAddNode() {
- return
- }
-
- renderWalletBackup() {
- return
- }
-
- renderFiatCurrency() {
- return
- }
-
- renderExportKeys() {
- return
- }
-
- renderImportKeys() {
- return
- }
-
- renderDebugLog() {
- return
- }
-
- renderAppSettings() {
- return
- }
-
- renderCliPanel() {
- return
- }
-
- renderSupportPanel() {
- return
- }
-
render() {
return SettingsRender.call(this);
}
@@ -146,13 +43,7 @@ const mapStateToProps = (state) => {
return {
Main: {
coins: state.Main.coins,
- activeHandle: state.Main.activeHandle,
- },
- ActiveCoin: {
- coin: state.ActiveCoin.coin,
},
- Settings: state.Settings,
- Dashboard: state.Dashboard,
};
};
diff --git a/react/src/components/dashboard/settings/settings.panel.js b/react/src/components/dashboard/settings/settings.panel.js
new file mode 100644
index 0000000..44f8370
--- /dev/null
+++ b/react/src/components/dashboard/settings/settings.panel.js
@@ -0,0 +1,86 @@
+import React from 'react';
+import className from 'classnames';
+import * as Utils from './settings.panelUtils';
+
+class Panel extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.toggleSection = this.toggleSection.bind(this);
+ this.state = {
+ singleOpen: this.props.singleOpen,
+ openByDefault: this.props.openByDefault,
+ activeSections: [],
+ };
+ }
+
+ componentWillMount() {
+ const {
+ singleOpen,
+ openByDefault,
+ uniqId,
+ children } = this.props;
+
+ const settings = {
+ singleOpen,
+ openByDefault,
+ uniqId,
+ kids: children
+ };
+
+ const initialStateSections = Utils.setupAccordion(settings).activeSections;
+ this.setState({ activeSections: initialStateSections });
+ }
+
+ getChildrenWithProps() {
+ const {
+ children,
+ } = this.props;
+
+
+ const kids = React.Children.map(children, (child, i) => {
+ if(child) {
+ const unqId = `panel-sec-${i}`;
+ return React.cloneElement(child, {
+ toggle: (acId) => this.toggleSection(acId),
+ key: unqId,
+ unq: unqId,
+ active: (this.state.activeSections && this.state.activeSections.lastIndexOf(unqId) !== -1)
+ });
+ }
+ });
+
+
+ return kids;
+ }
+
+ toggleSection(sectionId) {
+ const newActive = Utils.toggleSection(
+ sectionId,
+ this.state.activeSections,
+ this.state.singleOpen);
+
+ this.setState({
+ activeSections: newActive
+ });
+ }
+
+ render() {
+ const {
+ className: propClasses,
+ uniqId: propId
+ } = this.props;
+
+ const childrenWithProps = this.getChildrenWithProps();
+ const accordionClasses = className('panel-group', propClasses);
+ const uniqId = propId || '';
+
+ return(
+
+ {childrenWithProps}
+
+ );
+ }
+}
+
+export default Panel;
\ No newline at end of file
diff --git a/react/src/components/dashboard/settings/settings.panelBody.js b/react/src/components/dashboard/settings/settings.panelBody.js
new file mode 100644
index 0000000..84a52fe
--- /dev/null
+++ b/react/src/components/dashboard/settings/settings.panelBody.js
@@ -0,0 +1,89 @@
+import React from 'react';
+import className from 'classnames';
+
+class PanelSection extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ sectionHeight: 0,
+ }
+ this.toggleSection = this.toggleSection.bind(this);
+ }
+
+ componentDidMount() {
+ const { active } = this.props;
+ if (active) this.setState({sectionHeight: this.accordionContent.scrollHeight});
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if(this.props.active) {
+ this.setState({
+ sectionHeight: 'auto',
+ });
+ }
+ if (nextProps.active !== this.props.active) {
+ this.toggleOpen(nextProps.active);
+ }
+ }
+
+ getHeight() {
+ const { active } = this.props;
+ return (active) ? this.accordionContent.scrollHeight : 0;
+ }
+
+ toggleSection() {
+ const {
+ unq,
+ toggle
+ } = this.props;
+ toggle(unq);
+ }
+
+ toggleOpen(active) {
+ const height = (active) ? `${this.accordionContent.scrollHeight}px` : 0;
+ this.setState({
+ sectionHeight: height,
+ });
+ }
+
+ render() {
+ const {
+ title,
+ icon,
+ children,
+ active,
+ className: propClasses
+ } = this.props;
+
+ const contentStyles = {
+ height: this.state.sectionHeight,
+ overflow: 'hidden',
+ transition: 'height .25s ease',
+ };
+
+ const triggerClasses = className('panel', {
+ active
+ });
+
+ const contentClasses = className('panel-collapse', {
+ active
+ });
+
+ return(
+
this.toggleSection()}>
+
+
this.accordionContent = ref}>
+
+ {children}
+
+
+
+ );
+ }
+}
+
+export default PanelSection;
diff --git a/react/src/components/dashboard/settings/settings.panelUtils.js b/react/src/components/dashboard/settings/settings.panelUtils.js
new file mode 100644
index 0000000..e07614f
--- /dev/null
+++ b/react/src/components/dashboard/settings/settings.panelUtils.js
@@ -0,0 +1,48 @@
+export function checkUndef(item) {
+ return (typeof item !== 'undefined');
+}
+
+export function toggleSection(sectionId, activeSections, singleOpen) {
+ let present = null;
+ let newActiveSections = activeSections;
+
+ newActiveSections.map((section) => {
+ if (section === sectionId) present = true;
+ return true;
+ });
+
+ if (!singleOpen) {
+ if (present) {
+ const pos = newActiveSections.indexOf(sectionId);
+ newActiveSections.splice(pos, 1);
+ } else {
+ newActiveSections.push(sectionId);
+ }
+ } else {
+ newActiveSections = [sectionId];
+ }
+
+ return newActiveSections;
+}
+
+export function setupAccordion(info) {
+ const singleOpen = (checkUndef(info.singleOpen)) ? info.singleOpen : false;
+ const activeSections = [];
+ const singleChild = typeof info.kids.length === 'undefined';
+
+ if (!singleChild) {
+ info.kids.forEach((child, i) => {
+ const { openByDefault } = child ? child.props : false;
+ if (singleOpen && activeSections.length === 0 && openByDefault) {
+ activeSections.push(`panel-sec-${i}`);
+ }
+ if (!singleOpen && openByDefault) {
+ activeSections.push(`panel-sec-${i}`);
+ }
+ });
+ }
+
+ return {
+ activeSections,
+ };
+}
\ No newline at end of file
diff --git a/react/src/components/dashboard/settings/settings.render.js b/react/src/components/dashboard/settings/settings.render.js
index 5a999d1..95fcf70 100644
--- a/react/src/components/dashboard/settings/settings.render.js
+++ b/react/src/components/dashboard/settings/settings.render.js
@@ -1,227 +1,111 @@
import React from 'react';
import { translate } from '../../../translate/translate';
+import PanelSection from './settings.panelBody';
+import Panel from './settings.panel';
+
+import AppUpdatePanel from './settings.appUpdatePanel';
+import AppInfoPanel from './settings.appInfoPanel';
+import AddNodePanel from './settings.addNodePanel';
+import AppSettingsPanel from './settings.appSettingsPanel';
+import CliPanel from './settings.cliPanel';
+import DebugLogPanel from './settings.debugLogPanel';
+import FiatCurrencyPanel from './settings.fiatCurrencyPanel';
+import ExportKeysPanel from './settings.exportKeysPanel';
+import ImportKeysPanel from './settings.importKeysPanel';
+import SupportPanel from './settings.supportPanel';
+import WalletInfoPanel from './settings.walletInfoPanel';
+import WalletBackupPanel from './settings.walletBackupPanel';
export const SettingsRender = function() {
return (
-
-
+
-
-
-
-
{ translate('INDEX.WALLET_SETTINGS') }
-
-
- { !this.props.disableWalletSpecificUI &&
-
this.openTab('WalletInfo', 0) }
- className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }>
-
-
- { this.renderWalletInfo() }
-
-
- }
- { !this.props.disableWalletSpecificUI &&
-
this.openTab('AddNodeforCoin', 1) }
- className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }>
-
-
- { this.renderAddNode() }
-
-
- }
- { !this.props.disableWalletSpecificUI &&
-
this.openTab('DumpWallet', 2) }
- className={ 'hide panel' + (this.state.nativeOnly ? ' hide' : '') }>
-
-
- { this.renderWalletBackup() }
-
-
- }
- { !this.props.disableWalletSpecificUI &&
-
this.openTab('FiatCurrencySettings', 3) }
- className={ 'hide panel' + (this.state.nativeOnly ? ' hide' : '') }>
-
-
- { this.renderFiatCurrency() }
-
-
- }
- { !this.props.disableWalletSpecificUI &&
-
this.openTab('ExportKeys', 4) }
- className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }>
-
-
- { this.renderExportKeys() }
-
-
- }
- { !this.props.disableWalletSpecificUI &&
-
this.openTab('ImportKeys', 5) }
- className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }>
-
-
- { this.renderImportKeys() }
-
-
- }
-
-
this.openTab('DebugLog', 6) }>
-
-
- { this.renderDebugLog() }
-
-
-
-
this.openTab('AppSettings', 7) }>
-
-
- { this.renderAppSettings() }
-
-
-
-
this.openTab('AppInfo', 8) }>
-
-
- { this.renderAppInfoTab() }
-
-
-
- { this.props.Main && this.props.Main.coins.native &&
-
this.openTab('Cli', 9) }
- className={ 'panel' + (!this.props.Main.coins.native.length ? ' hide' : '') }>
-
-
- { this.renderCliPanel() }
-
-
- }
-
-
this.openTab('AppUpdate', 10) }>
-
-
- { this.renderAppUpdateTab() }
-
-
-
-
this.openTab('Support', 11) }>
-
-
- { this.renderSupportPanel() }
-
-
-
-
-
+
+
{ translate('INDEX.WALLET_SETTINGS') }
+
+ { !this.props.disableWalletSpecificUI &&
+
+
+
+ }
+ { !this.props.disableWalletSpecificUI &&
+
+
+
+ }
+ { !this.props.disableWalletSpecificUI &&
+
+
+
+ }
+ { !this.props.disableWalletSpecificUI &&
+
+
+
+ }
+ { !this.props.disableWalletSpecificUI &&
+
+
+
+ }
+ { !this.props.disableWalletSpecificUI &&
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+ { this.props.Main && this.props.Main.coins.native &&
+
+
+
+ }
+
+
+
+
+
+
+
-
);
};
\ No newline at end of file
diff --git a/react/src/components/dashboard/settings/settings.scss b/react/src/components/dashboard/settings/settings.scss
index bc1a47c..e3a10c0 100644
--- a/react/src/components/dashboard/settings/settings.scss
+++ b/react/src/components/dashboard/settings/settings.scss
@@ -93,10 +93,17 @@
#SettingsAccordion {
.panel {
.panel-collapse {
- transition: all .3s;
-
+
&.collapse {
- height: 0;
+ max-height: 0;
+ overflow: hidden;
+
+ }
+ &.in {
+ animation-name: max-height;
+ animation-duration: 1s;
+ animation-iteration-count: 1;
+ max-height: none;
}
}
}
@@ -110,7 +117,7 @@
cursor: hand;
&:before {
- content: '\F273';
+ content: '\F278';
}
&.collapsed {
&:before {
@@ -118,4 +125,21 @@
}
}
}
+ .panel.active {
+ .panel-title:before {
+ content: '\F273';
+ }
+ }
+}
+
+@keyframes max-height {
+ from {
+ max-height: 0;
+ }
+ 99% {
+ max-height: 2000px;
+ }
+ 100% {
+ max-height: none;
+ }
}
\ No newline at end of file
diff --git a/react/src/components/dashboard/settings/settings.supportPanel.js b/react/src/components/dashboard/settings/settings.supportPanel.js
index a13f89b..be016c5 100644
--- a/react/src/components/dashboard/settings/settings.supportPanel.js
+++ b/react/src/components/dashboard/settings/settings.supportPanel.js
@@ -27,7 +27,7 @@ class SupportPanel extends React.Component {
render() {
return (
-
+
Wallet Backup section to be updated soon.
+
+
+
Wallet Backup section to be updated soon.
+
+
);
};
}
diff --git a/react/src/components/dashboard/settings/settings.walletInfoPanel.js b/react/src/components/dashboard/settings/settings.walletInfoPanel.js
index 29fda9d..ad255f9 100644
--- a/react/src/components/dashboard/settings/settings.walletInfoPanel.js
+++ b/react/src/components/dashboard/settings/settings.walletInfoPanel.js
@@ -9,8 +9,7 @@ class WalletInfoPanel extends React.Component {
render() {
return (
-
-
+
{ translate('INDEX.KEY') } |
@@ -44,7 +43,6 @@ class WalletInfoPanel extends React.Component {
-
);
};
}
diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
index 7efbcf0..e5acb5b 100644
--- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
+++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
@@ -81,10 +81,29 @@ class WalletsNativeSend extends React.Component {
}
setRecieverFromScan(receiver) {
- this.setState({
- sendTo: receiver,
- });
-
+ try {
+ const recObj = JSON.parse(receiver);
+
+ if (recObj &&
+ typeof recObj === 'object') {
+ if (recObj.coin === this.props.ActiveCoin.coin) {
+ if (recObj.amount) {
+ this.setState({
+ amount: recObj.amount,
+ });
+ }
+ if (recObj.address) {
+ this.setState({
+ sendTo: recObj.address,
+ });
+ }
+ }
+ }
+ } catch (e) {
+ this.setState({
+ sendTo: receiver,
+ });
+ }
document.getElementById('kmdWalletSendTo').focus();
}
@@ -99,9 +118,11 @@ class WalletsNativeSend extends React.Component {
}
checkZAddressCount() {
- if (this.props.ActiveCoin.addresses &&
- (!this.props.ActiveCoin.addresses.private ||
- this.props.ActiveCoin.addresses.private.length === 0)) {
+ const _addresses = this.props.ActiveCoin.addresses;
+
+ if (_addresses &&
+ (!_addresses.private ||
+ _addresses.private.length === 0)) {
this.setState({
renderAddressDropdown: false,
});
diff --git a/react/src/components/login/login.js b/react/src/components/login/login.js
index 9739b74..a5a3afb 100644
--- a/react/src/components/login/login.js
+++ b/react/src/components/login/login.js
@@ -18,6 +18,11 @@ import { PassPhraseGenerator } from '../../util/crypto/passphrasegenerator';
import SwallModalRender from './swall-modal.render';
import LoginRender from './login.render';
import { translate } from '../../translate/translate';
+import {
+ encryptPassphrase,
+ loadPinList,
+ loginWithPin
+} from '../../actions/actions/pin';
const IGUNA_ACTIVE_HANDLE_TIMEOUT = 3000;
const IGUNA_ACTIVE_COINS_TIMEOUT = 10000;
@@ -45,6 +50,11 @@ class Login extends React.Component {
trimPassphraseTimer: null,
displayLoginSettingsDropdown: false,
displayLoginSettingsDropdownSection: null,
+ shouldEncryptSeed: false,
+ encryptKey: '',
+ pubKey: '',
+ decryptKey: '',
+ selectedPin: '',
isExperimentalOn: false,
};
this.toggleActivateCoinForm = this.toggleActivateCoinForm.bind(this);
@@ -59,6 +69,10 @@ class Login extends React.Component {
this.execWalletCreate = this.execWalletCreate.bind(this);
this.resizeLoginTextarea = this.resizeLoginTextarea.bind(this);
this.toggleLoginSettingsDropdown = this.toggleLoginSettingsDropdown.bind(this);
+ this.updateEncryptKey = this.updateEncryptKey.bind(this);
+ this.updatePubKey = this.updatePubKey.bind(this);
+ this.updateDecryptKey = this.updateDecryptKey.bind(this);
+ this.loadPinList = this.loadPinList.bind(this);
}
// the setInterval handler for 'activeCoins'
@@ -98,6 +112,35 @@ class Login extends React.Component {
});
}
+ shouldEncryptSeed() {
+ return this.state.shouldEncryptSeed;
+ }
+
+ toggleShouldEncryptSeed() {
+ this.setState({
+ shouldEncryptSeed: !this.state.shouldEncryptSeed
+ });
+ }
+
+ updateEncryptKey(e) {
+ this.setState({
+ encryptKey: e.target.value
+ });
+ }
+
+ updatePubKey(e) {
+ this.setState({
+ pubKey: e.target.value
+ });
+ }
+
+
+ updateDecryptKey(e) {
+ this.setState({
+ decryptKey: e.target.value
+ });
+ }
+
openSyncOnlyModal() {
Store.dispatch(getSyncOnlyForks());
@@ -119,6 +162,8 @@ class Login extends React.Component {
componentDidMount() {
Store.dispatch(iguanaActiveHandle(true));
+ // this.loadPinList();
+
let appConfig;
try {
@@ -153,6 +198,9 @@ class Login extends React.Component {
}
componentWillReceiveProps(props) {
+ if (props.Login.pinList === 'no pins') {
+ props.Login.pinList = [];
+ }
if (props &&
props.Main &&
props.Main.isLoggedIn) {
@@ -255,9 +303,27 @@ class Login extends React.Component {
loginPassPhraseSeedType: null,
});
- Store.dispatch(
- iguanaWalletPassphrase(this.state.loginPassphrase)
- );
+ if (this.state.shouldEncryptSeed) {
+ Store.dispatch(encryptPassphrase(this.state.loginPassphrase, this.state.encryptKey, this.state.pubKey));
+ }
+
+ if (this.state.selectedPin) {
+ Store.dispatch(loginWithPin(this.state.decryptKey, this.state.selectedPin));
+ } else {
+ Store.dispatch(
+ iguanaWalletPassphrase(this.state.loginPassphrase)
+ );
+ }
+ }
+
+ loadPinList() {
+ Store.dispatch(loadPinList());
+ }
+
+ updateSelectedPin(e) {
+ this.setState({
+ selectedPin: e.target.value
+ });
}
getLoginPassPhraseSeedType(passPhrase) {
@@ -405,9 +471,9 @@ const mapStateToProps = (state) => {
},
Interval: {
interval: state.Interval.interval,
- }
+ },
+ Login: state.Login,
};
-
};
export default connect(mapStateToProps)(Login);
diff --git a/react/src/components/login/login.render.js b/react/src/components/login/login.render.js
index 0f70929..e6a5af4 100644
--- a/react/src/components/login/login.render.js
+++ b/react/src/components/login/login.render.js
@@ -52,6 +52,9 @@ const LoginRender = function () {
{ translate('INDEX.WELCOME_LOGIN') }
+ { this.props.Login.pinList.length > 0 &&
+ You can login be entering a login seed or by selecting a pin
+ }
{ this.state.loginPassPhraseSeedType }
}
+
+ { this.state.loginPassphrase &&
+
+
+
+
+ this.toggleShouldEncryptSeed() }>
+ { translate('LOGIN.ENCRYPT_SEED') }
+
+
+
+
+
+
+ }
+
+ { this.props.Login.pinList.length > 0 &&
+
+ }
+ { this.props.Login.pinList.length > 0 &&
+
+
+
+
+
+
+
+
+ }
+
diff --git a/react/src/components/login/login.scss b/react/src/components/login/login.scss
index beceabf..3a04ad0 100644
--- a/react/src/components/login/login.scss
+++ b/react/src/components/login/login.scss
@@ -154,6 +154,11 @@ input[type="password"] {
}
}
+option.login-option {
+ background-color: #757575;
+ color: #fff;
+}
+
.login-form,
.register-form {
width: 540px;
diff --git a/react/src/reducers/index.js b/react/src/reducers/index.js
index b6c4c76..afe3831 100644
--- a/react/src/reducers/index.js
+++ b/react/src/reducers/index.js
@@ -10,10 +10,12 @@ import { Atomic } from './atomic';
import { Settings } from './settings';
import { Interval } from './interval';
import { SyncOnly } from './syncOnly';
+import { Login } from "./login";
const appReducer = combineReducers({
AddCoin,
toaster,
+ Login,
Main,
Dashboard,
ActiveCoin,
diff --git a/react/src/reducers/login.js b/react/src/reducers/login.js
new file mode 100644
index 0000000..ffaabd9
--- /dev/null
+++ b/react/src/reducers/login.js
@@ -0,0 +1,18 @@
+import { GET_PIN_LIST } from "../actions/storeType";
+
+export function Login(state = {
+ pinList: [],
+}, action) {
+ if (state === null) state = { pinList: [] };
+
+ switch (action.type) {
+ case GET_PIN_LIST:
+ return Object.assign({}, state, {
+ pinList: action.pinList,
+ });
+ default:
+ return state;
+ }
+}
+
+export default Login;
diff --git a/react/src/translate/en.js b/react/src/translate/en.js
index fc02070..c95fd3f 100644
--- a/react/src/translate/en.js
+++ b/react/src/translate/en.js
@@ -307,6 +307,10 @@ export const _lang = {
'TOGGLE_ZERO_ADDRESSES': 'Toggle empty addresses',
'NEXT_PAGE': 'Next Page',
'PREVIOUS_PAGE': 'Previous Page',
+ 'CREATE_INVOICE': 'Create Invoice',
+ 'CREATE_INVOICE_QR': 'Create Invoice QR Code',
+ 'QR_CONTENT': 'QR Content',
+ 'CHOOSE_RECEIVING_ADDRESS': 'Choose Address',
},
'ATOMIC': {
'RAW_OUTPUT': 'Raw Output',
@@ -580,6 +584,10 @@ export const _lang = {
'NXT_SEED': 'NXT',
'SEED_COPIED': 'Seed copied',
'SEED_SUCCESSFULLY_COPIED': 'The seed was successfully copied',
+ 'ENCRYPT_SEED': 'Encrypt login seed',
+ 'PUBKEY': 'pubkey',
+ 'ENCRYPT_KEY': 'Encrypt key',
+ 'DECRYPT_KEY': 'Decrypt key'
},
'SIDEBAR': {
'EDEX_MOTTO': 'Most Secure, Easy and Native Decentralised Exchange',