mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
Merge pull request #171 from MetaMask/MoveAccountExportToSubview
Move account export into own view
This commit is contained in:
commit
895fa023d1
@ -3,6 +3,9 @@
|
||||
## Current Master
|
||||
|
||||
- Add support for calls to `eth.sign`.
|
||||
- Moved account exporting within transitioning subview on the account detail view.
|
||||
- Added buttons to the account export process.
|
||||
- Improved visual appearance of account detail transition where button heights would change.
|
||||
|
||||
## 1.7.0 2016-04-29
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
const inherits = require('util').inherits
|
||||
const extend = require('xtend')
|
||||
const Component = require('react').Component
|
||||
const h = require('react-hyperscript')
|
||||
const connect = require('react-redux').connect
|
||||
const copyToClipboard = require('copy-to-clipboard')
|
||||
const actions = require('./actions')
|
||||
const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
|
||||
|
||||
const AccountPanel = require('./components/account-panel')
|
||||
const transactionList = require('./components/transaction-list')
|
||||
const ExportAccountView = require('./components/account-export')
|
||||
|
||||
module.exports = connect(mapStateToProps)(AccountDetailScreen)
|
||||
|
||||
@ -35,7 +39,11 @@ AccountDetailScreen.prototype.render = function() {
|
||||
|
||||
return (
|
||||
|
||||
h('.account-detail-section.flex-column.flex-grow', [
|
||||
h('.account-detail-section.flex-column.flex-grow', {
|
||||
style: {
|
||||
width: '330px',
|
||||
},
|
||||
}, [
|
||||
|
||||
// subtitle and nav
|
||||
h('.section-title.flex-row.flex-center', [
|
||||
@ -78,12 +86,13 @@ AccountDetailScreen.prototype.render = function() {
|
||||
}, 'EXPORT'),
|
||||
]),
|
||||
|
||||
transactionList(transactions
|
||||
.filter(tx => tx.txParams.from === state.address)
|
||||
.filter(tx => tx.txParams.metamaskNetworkId === state.networkVersion)
|
||||
.sort((a, b) => b.time - a.time), state.networkVersion),
|
||||
this.exportedAccount(accountDetail),
|
||||
|
||||
h(ReactCSSTransitionGroup, {
|
||||
transitionName: "main",
|
||||
transitionEnterTimeout: 300,
|
||||
transitionLeaveTimeout: 300,
|
||||
}, [
|
||||
this.subview(),
|
||||
]),
|
||||
// transaction table
|
||||
/*
|
||||
h('section.flex-column', [
|
||||
@ -94,72 +103,41 @@ AccountDetailScreen.prototype.render = function() {
|
||||
)
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.subview = function() {
|
||||
var subview
|
||||
try {
|
||||
subview = this.props.accountDetail.subview
|
||||
} catch (e) {
|
||||
subview = null
|
||||
}
|
||||
|
||||
switch (subview) {
|
||||
case 'transactions':
|
||||
return this.transactionList()
|
||||
case 'export':
|
||||
var state = extend({key: 'export'}, this.props)
|
||||
return h(ExportAccountView, state)
|
||||
default:
|
||||
return this.transactionList()
|
||||
}
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.transactionList = function() {
|
||||
var state = this.props
|
||||
var transactions = state.transactions
|
||||
|
||||
return transactionList(transactions
|
||||
.filter(tx => tx.txParams.from === state.address)
|
||||
.filter(tx => tx.txParams.metamaskNetworkId === state.networkVersion)
|
||||
.sort((a, b) => b.time - a.time), state.networkVersion)
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.navigateToAccounts = function(event){
|
||||
event.stopPropagation()
|
||||
this.props.dispatch(actions.showAccountsPage())
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.exportAccount = function(address) {
|
||||
this.props.dispatch(actions.exportAccount(address))
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.requestAccountExport = function() {
|
||||
this.props.dispatch(actions.requestExportAccount())
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.exportedAccount = function(accountDetail) {
|
||||
if (!accountDetail) return
|
||||
var accountExport = accountDetail.accountExport
|
||||
|
||||
var notExporting = accountExport === 'none'
|
||||
var exportRequested = accountExport === 'requested'
|
||||
var accountExported = accountExport === 'completed'
|
||||
|
||||
if (notExporting) return
|
||||
|
||||
if (exportRequested) {
|
||||
var warning = `Exporting your private key is very dangerous,
|
||||
and you should only do it if you know what you're doing.`
|
||||
var confirmation = `If you're absolutely sure, type "I understand" below and
|
||||
hit Enter.`
|
||||
return h('div', {}, [
|
||||
h('p.error', warning),
|
||||
h('p', confirmation),
|
||||
h('input#exportAccount', {
|
||||
onKeyPress: this.onExportKeyPress.bind(this),
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
if (accountExported) {
|
||||
return h('div.privateKey', {
|
||||
|
||||
}, [
|
||||
h('label', 'Your private key (click to copy):'),
|
||||
h('p.error.cursor-pointer', {
|
||||
style: {
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
webkitUserSelect: 'text',
|
||||
width: '100%',
|
||||
},
|
||||
onClick: function(event) {
|
||||
copyToClipboard(accountDetail.privateKey)
|
||||
}
|
||||
}, accountDetail.privateKey),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.onExportKeyPress = function(event) {
|
||||
if (event.key !== 'Enter') return
|
||||
event.preventDefault()
|
||||
|
||||
var input = document.getElementById('exportAccount')
|
||||
if (input.value === 'I understand') {
|
||||
this.props.dispatch(actions.exportAccount(this.props.address))
|
||||
} else {
|
||||
input.value = ''
|
||||
input.placeholder = 'Please retype "I understand" exactly.'
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,6 @@ function tryUnlockMetamask(password) {
|
||||
return (dispatch) => {
|
||||
dispatch(this.unlockInProgress())
|
||||
_accountManager.submitPassword(password, (err, selectedAccount) => {
|
||||
dispatch(this.hideLoadingIndication())
|
||||
if (err) {
|
||||
dispatch(this.unlockFailed())
|
||||
} else {
|
||||
|
@ -65,7 +65,7 @@ App.prototype.render = function() {
|
||||
h('.flex-column.flex-grow.full-height', {
|
||||
style: {
|
||||
// Windows was showing a vertical scroll bar:
|
||||
overflowY: 'hidden',
|
||||
overflow: 'hidden',
|
||||
}
|
||||
},
|
||||
[
|
||||
@ -82,6 +82,7 @@ App.prototype.render = function() {
|
||||
h('.app-primary.flex-grow' + (transForward ? '.from-right' : '.from-left'), {
|
||||
style: {
|
||||
height: '380px',
|
||||
width: '360px',
|
||||
}
|
||||
}, [
|
||||
h(ReactCSSTransitionGroup, {
|
||||
|
87
ui/app/components/account-export.js
Normal file
87
ui/app/components/account-export.js
Normal file
@ -0,0 +1,87 @@
|
||||
const Component = require('react').Component
|
||||
const h = require('react-hyperscript')
|
||||
const inherits = require('util').inherits
|
||||
const actions = require('../actions')
|
||||
|
||||
module.exports = ExportAccountView
|
||||
|
||||
|
||||
inherits(ExportAccountView, Component)
|
||||
function ExportAccountView() {
|
||||
Component.call(this)
|
||||
}
|
||||
|
||||
ExportAccountView.prototype.render = function() {
|
||||
console.log("EXPORT VIEW")
|
||||
console.dir(this.props)
|
||||
var state = this.props
|
||||
var accountDetail = state.accountDetail
|
||||
|
||||
if (!accountDetail) return h('div')
|
||||
var accountExport = accountDetail.accountExport
|
||||
|
||||
var notExporting = accountExport === 'none'
|
||||
var exportRequested = accountExport === 'requested'
|
||||
var accountExported = accountExport === 'completed'
|
||||
|
||||
if (notExporting) return h('div')
|
||||
|
||||
if (exportRequested) {
|
||||
var warning = `Exporting your private key is very dangerous,
|
||||
and you should only do it if you know what you're doing.`
|
||||
var confirmation = `If you're absolutely sure, type "I understand" below and
|
||||
submit.`
|
||||
return h('div', { key: 'exporting' }, [
|
||||
h('p.error', warning),
|
||||
h('p', confirmation),
|
||||
h('input#exportAccount', {
|
||||
onKeyPress: this.onExportKeyPress.bind(this),
|
||||
}),
|
||||
h('button', {
|
||||
onClick: () => this.onExportKeyPress({ key: 'Enter', preventDefault: () => {} }),
|
||||
}, 'Submit'),
|
||||
h('button', {
|
||||
onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address))
|
||||
}, 'Cancel'),
|
||||
])
|
||||
}
|
||||
|
||||
if (accountExported) {
|
||||
return h('div.privateKey', {
|
||||
|
||||
}, [
|
||||
h('label', 'Your private key (click to copy):'),
|
||||
h('p.error.cursor-pointer', {
|
||||
style: {
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
webkitUserSelect: 'text',
|
||||
width: '100%',
|
||||
},
|
||||
onClick: function(event) {
|
||||
copyToClipboard(accountDetail.privateKey)
|
||||
}
|
||||
}, accountDetail.privateKey),
|
||||
h('button', {
|
||||
onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address))
|
||||
}, 'Done'),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
ExportAccountView.prototype.onExportKeyPress = function(event) {
|
||||
if (event.key !== 'Enter') return
|
||||
event.preventDefault()
|
||||
|
||||
var input = document.getElementById('exportAccount')
|
||||
if (input.value === 'I understand') {
|
||||
this.props.dispatch(actions.exportAccount(this.props.address))
|
||||
} else {
|
||||
input.value = ''
|
||||
input.placeholder = 'Please retype "I understand" exactly.'
|
||||
}
|
||||
}
|
||||
|
||||
ExportAccountView.prototype.exportAccount = function(address) {
|
||||
this.props.dispatch(actions.exportAccount(address))
|
||||
}
|
@ -4,7 +4,7 @@ const addressSummary = require('../util').addressSummary
|
||||
const explorerLink = require('../../lib/explorer-link')
|
||||
|
||||
module.exports = function(transactions, network) {
|
||||
return h('details', [
|
||||
return h('details', { key: 'transaction-list' }, [
|
||||
|
||||
h('summary', [
|
||||
h('div.font-small', {style: {display: 'inline'}}, 'Transactions'),
|
||||
|
@ -19,6 +19,7 @@
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
transition: transform 300ms ease-in-out;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* final positions */
|
||||
|
@ -23,6 +23,9 @@ function reduceApp(state, action) {
|
||||
|
||||
var appState = extend({
|
||||
currentView: seedWords ? seedConfView : defaultView,
|
||||
accountDetail: {
|
||||
subview: 'transactions',
|
||||
},
|
||||
currentDomain: 'example.com',
|
||||
transForward: true, // Used to render transition direction
|
||||
isLoading: false, // Used to display loading indicator
|
||||
@ -109,7 +112,9 @@ function reduceApp(state, action) {
|
||||
case actions.UNLOCK_METAMASK:
|
||||
return extend(appState, {
|
||||
currentView: {},
|
||||
detailView: {},
|
||||
transForward: true,
|
||||
isLoading: false,
|
||||
warning: null,
|
||||
})
|
||||
|
||||
@ -131,6 +136,7 @@ function reduceApp(state, action) {
|
||||
return extend(appState, {
|
||||
currentView: {},
|
||||
accountDetail: {
|
||||
subview: 'transactions',
|
||||
accountExport: 'none',
|
||||
privateKey: '',
|
||||
},
|
||||
@ -144,6 +150,7 @@ function reduceApp(state, action) {
|
||||
context: action.value || account,
|
||||
},
|
||||
accountDetail: {
|
||||
subview: 'transactions',
|
||||
accountExport: 'none',
|
||||
privateKey: '',
|
||||
},
|
||||
@ -157,6 +164,7 @@ function reduceApp(state, action) {
|
||||
context: action.value,
|
||||
},
|
||||
accountDetail: {
|
||||
subview: 'transactions',
|
||||
accountExport: 'none',
|
||||
privateKey: '',
|
||||
},
|
||||
@ -218,6 +226,9 @@ function reduceApp(state, action) {
|
||||
name: 'accountDetail',
|
||||
context: state.metamask.selectedAddress,
|
||||
},
|
||||
accountDetail: {
|
||||
subview: 'transactions',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -285,7 +296,13 @@ function reduceApp(state, action) {
|
||||
|
||||
case actions.REQUEST_ACCOUNT_EXPORT:
|
||||
return extend(appState, {
|
||||
transForward: true,
|
||||
currentView: {
|
||||
name: 'accountDetail',
|
||||
context: appState.currentView.context,
|
||||
},
|
||||
accountDetail: {
|
||||
subview: 'export',
|
||||
accountExport: 'requested',
|
||||
},
|
||||
})
|
||||
@ -293,6 +310,7 @@ function reduceApp(state, action) {
|
||||
case actions.EXPORT_ACCOUNT:
|
||||
return extend(appState, {
|
||||
accountDetail: {
|
||||
subview: 'export',
|
||||
accountExport: 'completed',
|
||||
},
|
||||
})
|
||||
@ -300,6 +318,7 @@ function reduceApp(state, action) {
|
||||
case actions.SHOW_PRIVATE_KEY:
|
||||
return extend(appState, {
|
||||
accountDetail: {
|
||||
subview: 'export',
|
||||
accountExport: 'completed',
|
||||
privateKey: action.value,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user