From 7d5aaaa5bd8a0f34694eb3e8ce5ba6bbecf03d71 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 20 May 2016 12:40:44 -0700 Subject: [PATCH 1/3] Add ability to add account to vault Scrolling to the bottom of the accounts page now reveals a downward-facing chevron button. Pressing this button shows loading indication, adds a new account to the identity vault, displays it in the list, and scrolls the list to the bottom of the page. Any number of accounts can be generated in this way, and the UX feels intuitive without having to overly explain how HD paths work. --- app/scripts/background.js | 1 + app/scripts/lib/idStore.js | 15 +++++++++++ ui/app/accounts.js | 55 +++++++++++++++++++++++++++++++++----- ui/app/actions.js | 15 +++++++++++ ui/app/css/lib.css | 4 +++ ui/app/reducers/app.js | 6 +++++ 6 files changed, 89 insertions(+), 7 deletions(-) diff --git a/app/scripts/background.js b/app/scripts/background.js index a52eab2d3dc5..e77df1519f50 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -182,6 +182,7 @@ function setupControllerConnection(stream){ setLocked: idStore.setLocked.bind(idStore), clearSeedWordCache: idStore.clearSeedWordCache.bind(idStore), exportAccount: idStore.exportAccount.bind(idStore), + revealAccount: idStore.revealAccount.bind(idStore), }) stream.pipe(dnode).pipe(stream) dnode.on('remote', function(remote){ diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js index 6d3d0c0aa156..0604c4bca2b5 100644 --- a/app/scripts/lib/idStore.js +++ b/app/scripts/lib/idStore.js @@ -115,6 +115,21 @@ IdentityStore.prototype.setSelectedAddress = function(address, cb){ if (cb) return cb(null, address) } +IdentityStore.prototype.revealAccount = function(cb) { + let addresses = this._getAddresses() + const derivedKey = this._idmgmt.derivedKey + const keyStore = this._keyStore + + keyStore.setDefaultHdDerivationPath(this.hdPathString) + keyStore.generateNewAddress(derivedKey, 1) + configManager.setWallet(keyStore.serialize()) + + addresses = this._getAddresses() + this._loadIdentities() + this._didUpdate() + cb(null) +} + IdentityStore.prototype.getNetwork = function(tries) { if (tries === 0) return this.web3.version.getNetwork((err, network) => { diff --git a/ui/app/accounts.js b/ui/app/accounts.js index e609e742470c..0f3030829b7d 100644 --- a/ui/app/accounts.js +++ b/ui/app/accounts.js @@ -9,6 +9,7 @@ const EtherBalance = require('./components/eth-balance') const valuesFor = require('./util').valuesFor const addressSummary = require('./util').addressSummary const formatBalance = require('./util').formatBalance +const findDOMNode = require('react-dom').findDOMNode module.exports = connect(mapStateToProps)(AccountsScreen) @@ -20,6 +21,7 @@ function mapStateToProps(state) { unconfTxs: state.metamask.unconfTxs, selectedAddress: state.metamask.selectedAddress, currentDomain: state.appState.currentDomain, + scrollToBottom: state.appState.scrollToBottom, } } @@ -36,13 +38,19 @@ AccountsScreen.prototype.render = function() { var actions = { onSelect: this.onSelect.bind(this), onShowDetail: this.onShowDetail.bind(this), + revealAccount: this.onRevealAccount.bind(this), } return ( - h('.accounts-section.flex-column.flex-grow', [ + h('.accounts-section.flex-grow', [ // subtitle and nav - h('.section-title.flex-column.flex-center', [ + h('.section-title.flex-center', [ + h('i.fa.fa-arrow-left.fa-lg.pointer.hover-white', { + onClick: (event) => { + state.dispatch(actions.goHome()) + } + }), h('h2.page-subtitle', 'Select Account'), ]), @@ -51,12 +59,32 @@ AccountsScreen.prototype.render = function() { // identity selection h('section.identity-section.flex-column', { style: { + height: '418px', overflowY: 'auto', overflowX: 'hidden', } }, - identityList.map(renderAccountPanel) - ), + [ + identityList.map(renderAccountPanel), + + h('hr.horizontal-line', {key: 'horizontal-line1'}), + h('div.footer.hover-white.pointer', { + key: 'reveal-account-bar', + onClick:() => { + actions.revealAccount() + }, + style: { + display: 'flex', + flex: '1 0 auto', + height: '40px', + paddint: '10px', + justifyContent: 'center', + alignItems: 'center', + } + }, [ + h('i.fa.fa-chevron-down.fa-lg', {key: ''}), + ]), + ]), unconfTxList.length ? ( @@ -70,10 +98,7 @@ AccountsScreen.prototype.render = function() { ) : ( null ), - - ]) - ) function renderAccountPanel(identity){ @@ -90,6 +115,7 @@ AccountsScreen.prototype.render = function() { return ( h('.accounts-list-option.flex-row.flex-space-between.cursor-pointer', { + key: `account-panel-${identity.address}`, style: { flex: '1 0 auto', background: isSelected ? 'white' : 'none', @@ -120,6 +146,17 @@ AccountsScreen.prototype.render = function() { } } +// If a new account was revealed, scroll to the bottom +AccountsScreen.prototype.componentDidUpdate = function(){ + const scrollToBottom = this.props.scrollToBottom + + if (scrollToBottom) { + var container = findDOMNode(this) + var scrollable = container.querySelector('.identity-section') + scrollable.scrollTop = scrollable.scrollHeight + } +} + AccountsScreen.prototype.navigateToConfTx = function(){ event.stopPropagation() this.props.dispatch(actions.showConfTxPage()) @@ -136,3 +173,7 @@ AccountsScreen.prototype.onShowDetail = function(address, event){ event.stopPropagation() this.props.dispatch(actions.showAccountDetail(address)) } + +AccountsScreen.prototype.onRevealAccount = function() { + this.props.dispatch(actions.revealAccount()) +} diff --git a/ui/app/actions.js b/ui/app/actions.js index ee5e417d41c7..5d6f503e21ff 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -48,6 +48,8 @@ var actions = { SHOW_ACCOUNTS_PAGE: 'SHOW_ACCOUNTS_PAGE', SHOW_CONF_TX_PAGE: 'SHOW_CONF_TX_PAGE', SHOW_CONF_MSG_PAGE: 'SHOW_CONF_MSG_PAGE', + REVEAL_ACCOUNT: 'REVEAL_ACCOUNT', + revealAccount: revealAccount, // account detail screen SHOW_SEND_PAGE: 'SHOW_SEND_PAGE', showSendPage: showSendPage, @@ -175,6 +177,19 @@ function setSelectedAddress(address) { } } +function revealAccount() { + return (dispatch) => { + dispatch(this.showLoadingIndication()) + _accountManager.revealAccount((err) => { + dispatch(this.hideLoadingIndication()) + if (err) return dispatch(this.displayWarning(err.message)) + dispatch({ + type: this.REVEAL_ACCOUNT, + }) + }) + } +} + function signMsg(msgData) { return (dispatch) => { dispatch(this.showLoadingIndication()) diff --git a/ui/app/css/lib.css b/ui/app/css/lib.css index 1eba7465b49d..97ff02c4698a 100644 --- a/ui/app/css/lib.css +++ b/ui/app/css/lib.css @@ -107,6 +107,10 @@ user-select: none; } +.hover-white:hover { + background: white; +} + .pointer { cursor: pointer; } diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 1c0154cd5570..a29a8f79c477 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -191,6 +191,12 @@ function reduceApp(state, action) { transForward: true, isLoading: false, warning: null, + scrollToBottom: false, + }) + + case actions.REVEAL_ACCOUNT: + return extend(appState, { + scrollToBottom: true, }) case actions.SHOW_CONF_TX_PAGE: From 18304fa46c9c172336e5402e273d8078c1e16db7 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 20 May 2016 12:49:33 -0700 Subject: [PATCH 2/3] Made account list hover styles more consistent --- ui/app/accounts.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/app/accounts.js b/ui/app/accounts.js index 0f3030829b7d..45594f3c0d69 100644 --- a/ui/app/accounts.js +++ b/ui/app/accounts.js @@ -46,7 +46,7 @@ AccountsScreen.prototype.render = function() { // subtitle and nav h('.section-title.flex-center', [ - h('i.fa.fa-arrow-left.fa-lg.pointer.hover-white', { + h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { onClick: (event) => { state.dispatch(actions.goHome()) } @@ -114,7 +114,7 @@ AccountsScreen.prototype.render = function() { }) return ( - h('.accounts-list-option.flex-row.flex-space-between.cursor-pointer', { + h('.accounts-list-option.flex-row.flex-space-between.pointer.hover-white', { key: `account-panel-${identity.address}`, style: { flex: '1 0 auto', From 4386fdd097efd03214783aad42eabf1737b8ef8c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Fri, 20 May 2016 12:53:53 -0700 Subject: [PATCH 3/3] Bump changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8681c951713d..955917cf2161 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Fixed glitchy transitions. - Added support for capitalization-based address checksums. - Send value is no longer limited by javascript number precision, and is always in ETH. +- Added ability to generate new accounts. ## 1.8.4 2016-05-13