|
|
|
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 addressSummary = require('./util').addressSummary
|
|
|
|
const formatBalance = require('./util').formatBalance
|
|
|
|
const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
|
|
|
|
|
|
|
|
const AccountPanel = require('./components/account-panel')
|
|
|
|
const Identicon = require('./components/identicon')
|
|
|
|
const transactionList = require('./components/transaction-list')
|
|
|
|
const ExportAccountView = require('./components/account-export')
|
|
|
|
|
|
|
|
module.exports = connect(mapStateToProps)(AccountDetailScreen)
|
|
|
|
|
|
|
|
function mapStateToProps(state) {
|
|
|
|
return {
|
|
|
|
identities: state.metamask.identities,
|
|
|
|
accounts: state.metamask.accounts,
|
|
|
|
address: state.metamask.selectedAccount,
|
|
|
|
accountDetail: state.appState.accountDetail,
|
|
|
|
transactions: state.metamask.transactions,
|
|
|
|
networkVersion: state.metamask.network,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inherits(AccountDetailScreen, Component)
|
|
|
|
function AccountDetailScreen() {
|
|
|
|
Component.call(this)
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.render = function() {
|
|
|
|
var state = this.props
|
|
|
|
var selected = state.address || Object.keys(state.accounts)[0]
|
|
|
|
var identity = state.identities[selected]
|
|
|
|
var account = state.accounts[selected]
|
|
|
|
var accountDetail = state.accountDetail
|
|
|
|
var transactions = state.transactions
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
h('.account-detail-section.flex-column.flex-grow', {
|
|
|
|
style: {
|
|
|
|
width: 330,
|
|
|
|
'margin-top': 28,
|
|
|
|
},
|
|
|
|
}, [
|
|
|
|
|
|
|
|
h('.flex-row.flex-space-between', [
|
|
|
|
|
|
|
|
// invisible placeholder for later
|
|
|
|
h('i.fa.fa-users.fa-lg.color-orange', {
|
|
|
|
style: {
|
|
|
|
visibility: 'hidden',
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
|
|
|
|
// large identicon
|
|
|
|
h('.identicon-wrapper.flex-column.flex-center.select-none', [
|
|
|
|
h(Identicon, {
|
|
|
|
diameter: 62,
|
|
|
|
address: selected,
|
|
|
|
}),
|
|
|
|
]),
|
|
|
|
|
|
|
|
// small accounts nav
|
|
|
|
h('i.fa.fa-users.fa-lg.cursor-pointer.color-orange', {
|
|
|
|
onClick: this.navigateToAccounts.bind(this),
|
|
|
|
}),
|
|
|
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
h('h2.font-medium.color-forest.flex-center', {
|
|
|
|
style: {
|
|
|
|
'padding-top': 8,
|
|
|
|
'margin-bottom': 32,
|
|
|
|
},
|
|
|
|
}, identity && identity.name),
|
|
|
|
|
|
|
|
h('.flex-row.flex-space-between', {
|
|
|
|
style: {
|
|
|
|
'margin-bottom': 16,
|
|
|
|
},
|
|
|
|
}, [
|
|
|
|
|
|
|
|
h('div', {
|
|
|
|
style: {
|
|
|
|
'line-height': 16,
|
|
|
|
},
|
|
|
|
}, addressSummary(selected)),
|
|
|
|
|
|
|
|
h('i.fa.fa-download.fa-md.cursor-pointer.color-orange', {
|
|
|
|
onClick: () => this.requestAccountExport(account.address),
|
|
|
|
}),
|
|
|
|
|
|
|
|
h('i.fa.fa-qrcode.fa-md.cursor-disabled.color-orange', {
|
|
|
|
onClick: () => console.warn('QRCode not implented...'),
|
|
|
|
}),
|
|
|
|
|
|
|
|
h('i.fa.fa-clipboard.fa-md.cursor-pointer.color-orange', {
|
|
|
|
onClick: () => copyToClipboard(account.address),
|
|
|
|
}),
|
|
|
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
h('.flex-row.flex-space-between', [
|
|
|
|
|
|
|
|
h('div', {
|
|
|
|
style: {
|
|
|
|
'line-height': 50,
|
|
|
|
},
|
|
|
|
}, formatBalance(account.balance)),
|
|
|
|
|
|
|
|
h('button', {
|
|
|
|
onClick: () => this.props.dispatch(actions.showSendPage()),
|
|
|
|
}, 'SEND ETH'),
|
|
|
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
h(ReactCSSTransitionGroup, {
|
|
|
|
transitionName: "main",
|
|
|
|
transitionEnterTimeout: 300,
|
|
|
|
transitionLeaveTimeout: 300,
|
|
|
|
}, [
|
|
|
|
this.subview(),
|
|
|
|
]),
|
|
|
|
|
|
|
|
])
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
// only transactions that have a hash
|
|
|
|
.filter(tx => tx.hash)
|
|
|
|
// only transactions that are from the current address
|
|
|
|
.filter(tx => tx.txParams.from === state.address)
|
|
|
|
// only transactions that are on the current network
|
|
|
|
.filter(tx => tx.txParams.metamaskNetworkId === state.networkVersion)
|
|
|
|
// sort by recency
|
|
|
|
.sort((a, b) => b.time - a.time), state.networkVersion)
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.navigateToAccounts = function(event){
|
|
|
|
event.stopPropagation()
|
|
|
|
this.props.dispatch(actions.showAccountsPage())
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.requestAccountExport = function() {
|
|
|
|
this.props.dispatch(actions.requestExportAccount())
|
|
|
|
}
|
|
|
|
|