1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

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.
This commit is contained in:
Dan Finlay 2016-05-20 12:40:44 -07:00
parent b0f92e05b1
commit 7d5aaaa5bd
6 changed files with 89 additions and 7 deletions

View File

@ -182,6 +182,7 @@ function setupControllerConnection(stream){
setLocked: idStore.setLocked.bind(idStore), setLocked: idStore.setLocked.bind(idStore),
clearSeedWordCache: idStore.clearSeedWordCache.bind(idStore), clearSeedWordCache: idStore.clearSeedWordCache.bind(idStore),
exportAccount: idStore.exportAccount.bind(idStore), exportAccount: idStore.exportAccount.bind(idStore),
revealAccount: idStore.revealAccount.bind(idStore),
}) })
stream.pipe(dnode).pipe(stream) stream.pipe(dnode).pipe(stream)
dnode.on('remote', function(remote){ dnode.on('remote', function(remote){

View File

@ -115,6 +115,21 @@ IdentityStore.prototype.setSelectedAddress = function(address, cb){
if (cb) return cb(null, address) 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) { IdentityStore.prototype.getNetwork = function(tries) {
if (tries === 0) return if (tries === 0) return
this.web3.version.getNetwork((err, network) => { this.web3.version.getNetwork((err, network) => {

View File

@ -9,6 +9,7 @@ const EtherBalance = require('./components/eth-balance')
const valuesFor = require('./util').valuesFor const valuesFor = require('./util').valuesFor
const addressSummary = require('./util').addressSummary const addressSummary = require('./util').addressSummary
const formatBalance = require('./util').formatBalance const formatBalance = require('./util').formatBalance
const findDOMNode = require('react-dom').findDOMNode
module.exports = connect(mapStateToProps)(AccountsScreen) module.exports = connect(mapStateToProps)(AccountsScreen)
@ -20,6 +21,7 @@ function mapStateToProps(state) {
unconfTxs: state.metamask.unconfTxs, unconfTxs: state.metamask.unconfTxs,
selectedAddress: state.metamask.selectedAddress, selectedAddress: state.metamask.selectedAddress,
currentDomain: state.appState.currentDomain, currentDomain: state.appState.currentDomain,
scrollToBottom: state.appState.scrollToBottom,
} }
} }
@ -36,13 +38,19 @@ AccountsScreen.prototype.render = function() {
var actions = { var actions = {
onSelect: this.onSelect.bind(this), onSelect: this.onSelect.bind(this),
onShowDetail: this.onShowDetail.bind(this), onShowDetail: this.onShowDetail.bind(this),
revealAccount: this.onRevealAccount.bind(this),
} }
return ( return (
h('.accounts-section.flex-column.flex-grow', [ h('.accounts-section.flex-grow', [
// subtitle and nav // 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'), h('h2.page-subtitle', 'Select Account'),
]), ]),
@ -51,12 +59,32 @@ AccountsScreen.prototype.render = function() {
// identity selection // identity selection
h('section.identity-section.flex-column', { h('section.identity-section.flex-column', {
style: { style: {
height: '418px',
overflowY: 'auto', overflowY: 'auto',
overflowX: 'hidden', 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 ? ( unconfTxList.length ? (
@ -70,10 +98,7 @@ AccountsScreen.prototype.render = function() {
) : ( ) : (
null null
), ),
]) ])
) )
function renderAccountPanel(identity){ function renderAccountPanel(identity){
@ -90,6 +115,7 @@ AccountsScreen.prototype.render = function() {
return ( return (
h('.accounts-list-option.flex-row.flex-space-between.cursor-pointer', { h('.accounts-list-option.flex-row.flex-space-between.cursor-pointer', {
key: `account-panel-${identity.address}`,
style: { style: {
flex: '1 0 auto', flex: '1 0 auto',
background: isSelected ? 'white' : 'none', 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(){ AccountsScreen.prototype.navigateToConfTx = function(){
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.showConfTxPage()) this.props.dispatch(actions.showConfTxPage())
@ -136,3 +173,7 @@ AccountsScreen.prototype.onShowDetail = function(address, event){
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.showAccountDetail(address)) this.props.dispatch(actions.showAccountDetail(address))
} }
AccountsScreen.prototype.onRevealAccount = function() {
this.props.dispatch(actions.revealAccount())
}

View File

@ -48,6 +48,8 @@ var actions = {
SHOW_ACCOUNTS_PAGE: 'SHOW_ACCOUNTS_PAGE', SHOW_ACCOUNTS_PAGE: 'SHOW_ACCOUNTS_PAGE',
SHOW_CONF_TX_PAGE: 'SHOW_CONF_TX_PAGE', SHOW_CONF_TX_PAGE: 'SHOW_CONF_TX_PAGE',
SHOW_CONF_MSG_PAGE: 'SHOW_CONF_MSG_PAGE', SHOW_CONF_MSG_PAGE: 'SHOW_CONF_MSG_PAGE',
REVEAL_ACCOUNT: 'REVEAL_ACCOUNT',
revealAccount: revealAccount,
// account detail screen // account detail screen
SHOW_SEND_PAGE: 'SHOW_SEND_PAGE', SHOW_SEND_PAGE: 'SHOW_SEND_PAGE',
showSendPage: showSendPage, 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) { function signMsg(msgData) {
return (dispatch) => { return (dispatch) => {
dispatch(this.showLoadingIndication()) dispatch(this.showLoadingIndication())

View File

@ -107,6 +107,10 @@
user-select: none; user-select: none;
} }
.hover-white:hover {
background: white;
}
.pointer { .pointer {
cursor: pointer; cursor: pointer;
} }

View File

@ -191,6 +191,12 @@ function reduceApp(state, action) {
transForward: true, transForward: true,
isLoading: false, isLoading: false,
warning: null, warning: null,
scrollToBottom: false,
})
case actions.REVEAL_ACCOUNT:
return extend(appState, {
scrollToBottom: true,
}) })
case actions.SHOW_CONF_TX_PAGE: case actions.SHOW_CONF_TX_PAGE: