2017-11-14 08:04:23 -08:00
|
|
|
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
|
2017-11-15 09:35:18 -08:00
|
|
|
const actions = require('../../ui/app/actions')
|
2017-11-14 08:04:23 -08:00
|
|
|
const valuesFor = require('./util').valuesFor
|
|
|
|
const Identicon = require('./components/identicon')
|
|
|
|
const EthBalance = require('./components/eth-balance')
|
|
|
|
const TransactionList = require('./components/transaction-list')
|
|
|
|
const ExportAccountView = require('./components/account-export')
|
|
|
|
const ethUtil = require('ethereumjs-util')
|
|
|
|
const EditableLabel = require('./components/editable-label')
|
|
|
|
const TabBar = require('./components/tab-bar')
|
|
|
|
const TokenList = require('./components/token-list')
|
|
|
|
const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
|
|
|
|
|
|
|
|
module.exports = connect(mapStateToProps)(AccountDetailScreen)
|
|
|
|
|
|
|
|
function mapStateToProps (state) {
|
|
|
|
return {
|
|
|
|
metamask: state.metamask,
|
|
|
|
identities: state.metamask.identities,
|
|
|
|
accounts: state.metamask.accounts,
|
|
|
|
address: state.metamask.selectedAddress,
|
|
|
|
accountDetail: state.appState.accountDetail,
|
|
|
|
network: state.metamask.network,
|
|
|
|
unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
|
|
|
|
shapeShiftTxList: state.metamask.shapeShiftTxList,
|
|
|
|
transactions: state.metamask.selectedAddressTxList || [],
|
|
|
|
conversionRate: state.metamask.conversionRate,
|
|
|
|
currentCurrency: state.metamask.currentCurrency,
|
|
|
|
currentAccountTab: state.metamask.currentAccountTab,
|
|
|
|
tokens: state.metamask.tokens,
|
|
|
|
computedBalances: state.metamask.computedBalances,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inherits(AccountDetailScreen, Component)
|
|
|
|
function AccountDetailScreen () {
|
|
|
|
Component.call(this)
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.render = function () {
|
|
|
|
var props = this.props
|
|
|
|
var selected = props.address || Object.keys(props.accounts)[0]
|
|
|
|
var checksumAddress = selected && ethUtil.toChecksumAddress(selected)
|
|
|
|
var identity = props.identities[selected]
|
|
|
|
var account = props.accounts[selected]
|
|
|
|
const { network, conversionRate, currentCurrency } = props
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
h('.account-detail-section.full-flex-height', [
|
|
|
|
|
|
|
|
// identicon, label, balance, etc
|
|
|
|
h('.account-data-subsection', {
|
|
|
|
style: {
|
2018-08-07 14:28:23 -07:00
|
|
|
padding: '30px',
|
2017-11-14 08:04:23 -08:00
|
|
|
flex: '1 0 auto',
|
2018-07-26 11:15:51 -07:00
|
|
|
background: 'linear-gradient(rgb(84, 36, 147), rgb(104, 45, 182))',
|
2018-08-07 14:28:23 -07:00
|
|
|
width: '100%',
|
2017-11-14 08:04:23 -08:00
|
|
|
},
|
|
|
|
}, [
|
|
|
|
|
|
|
|
// header - identicon + nav
|
|
|
|
h('div', {
|
|
|
|
style: {
|
|
|
|
display: 'flex',
|
|
|
|
justifyContent: 'flex-start',
|
|
|
|
alignItems: 'flex-start',
|
|
|
|
},
|
|
|
|
}, [
|
|
|
|
|
|
|
|
// large identicon and addresses
|
|
|
|
h('.identicon-wrapper.select-none', [
|
|
|
|
h(Identicon, {
|
2018-07-31 06:12:12 -07:00
|
|
|
diameter: 60,
|
2017-11-14 08:04:23 -08:00
|
|
|
address: selected,
|
|
|
|
}),
|
|
|
|
]),
|
2018-01-16 18:17:28 -08:00
|
|
|
h('flex-column', {
|
2017-11-14 08:04:23 -08:00
|
|
|
style: {
|
|
|
|
lineHeight: '10px',
|
2018-08-07 14:28:23 -07:00
|
|
|
marginLeft: '20px',
|
2017-11-14 08:04:23 -08:00
|
|
|
width: '100%',
|
|
|
|
},
|
|
|
|
}, [
|
|
|
|
h(EditableLabel, {
|
|
|
|
textValue: identity ? identity.name : '',
|
|
|
|
state: {
|
|
|
|
isEditingLabel: false,
|
|
|
|
},
|
|
|
|
saveText: (text) => {
|
2018-04-18 20:33:51 -07:00
|
|
|
props.dispatch(actions.setAccountLabel(selected, text))
|
2017-11-14 08:04:23 -08:00
|
|
|
},
|
|
|
|
}, [
|
|
|
|
|
|
|
|
// What is shown when not editing + edit text:
|
|
|
|
h('label.editing-label', [h('.edit-text', 'edit')]),
|
|
|
|
h(
|
|
|
|
'div',
|
|
|
|
{
|
|
|
|
style: {
|
|
|
|
display: 'flex',
|
2018-01-16 18:17:28 -08:00
|
|
|
justifyContent: 'flex-start',
|
2017-11-14 08:04:23 -08:00
|
|
|
alignItems: 'center',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[
|
|
|
|
h(
|
|
|
|
'div.font-medium.color-forest',
|
|
|
|
{
|
|
|
|
name: 'edit',
|
|
|
|
style: {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[
|
|
|
|
h('h2', {
|
|
|
|
style: {
|
|
|
|
maxWidth: '180px',
|
|
|
|
overflow: 'hidden',
|
|
|
|
textOverflow: 'ellipsis',
|
|
|
|
padding: '5px 0px',
|
|
|
|
lineHeight: '25px',
|
2018-07-26 11:15:51 -07:00
|
|
|
color: '#ffffff',
|
2017-11-14 08:04:23 -08:00
|
|
|
},
|
|
|
|
}, [
|
|
|
|
identity && identity.name,
|
|
|
|
]),
|
|
|
|
]
|
|
|
|
),
|
|
|
|
h(
|
|
|
|
AccountDropdowns,
|
|
|
|
{
|
|
|
|
style: {
|
2018-08-07 14:28:23 -07:00
|
|
|
marginRight: '10px',
|
2018-01-16 18:17:28 -08:00
|
|
|
marginLeft: 'auto',
|
2017-11-14 08:04:23 -08:00
|
|
|
cursor: 'pointer',
|
|
|
|
},
|
|
|
|
selected,
|
|
|
|
network,
|
|
|
|
identities: props.identities,
|
|
|
|
enableAccountOptions: true,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
]
|
|
|
|
),
|
|
|
|
]),
|
|
|
|
h('.flex-row', {
|
|
|
|
style: {
|
2018-01-16 18:17:28 -08:00
|
|
|
width: '15em',
|
2017-11-14 08:04:23 -08:00
|
|
|
justifyContent: 'space-between',
|
|
|
|
alignItems: 'baseline',
|
|
|
|
},
|
|
|
|
}, [
|
|
|
|
|
|
|
|
// address
|
|
|
|
|
|
|
|
h('div', {
|
|
|
|
style: {
|
|
|
|
overflow: 'hidden',
|
|
|
|
textOverflow: 'ellipsis',
|
|
|
|
paddingTop: '3px',
|
|
|
|
width: '5em',
|
2018-01-16 18:17:28 -08:00
|
|
|
height: '15px',
|
2018-07-30 10:31:25 -07:00
|
|
|
fontSize: '14px',
|
|
|
|
fontFamily: 'Nunito Bold',
|
2017-11-14 08:04:23 -08:00
|
|
|
textRendering: 'geometricPrecision',
|
|
|
|
marginBottom: '15px',
|
2018-07-26 11:15:51 -07:00
|
|
|
color: 'rgba(255, 255, 255, 0.7)',
|
2017-11-14 08:04:23 -08:00
|
|
|
},
|
|
|
|
}, checksumAddress),
|
|
|
|
]),
|
|
|
|
|
2018-07-26 11:15:51 -07:00
|
|
|
// account ballance
|
2017-11-14 08:04:23 -08:00
|
|
|
|
|
|
|
]),
|
|
|
|
]),
|
|
|
|
h('.flex-row', {
|
|
|
|
style: {
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
alignItems: 'flex-start',
|
|
|
|
},
|
|
|
|
}, [
|
|
|
|
|
|
|
|
h(EthBalance, {
|
|
|
|
value: account && account.balance,
|
|
|
|
conversionRate,
|
|
|
|
currentCurrency,
|
2018-07-19 04:12:21 -07:00
|
|
|
network,
|
2017-11-14 08:04:23 -08:00
|
|
|
style: {
|
|
|
|
lineHeight: '7px',
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
|
2018-01-16 18:17:28 -08:00
|
|
|
h('.flex-grow'),
|
2017-11-14 08:04:23 -08:00
|
|
|
|
2018-01-16 18:17:28 -08:00
|
|
|
h('button', {
|
|
|
|
onClick: () => props.dispatch(actions.buyEthView(selected)),
|
|
|
|
style: { marginRight: '10px' },
|
2018-07-26 04:42:04 -07:00
|
|
|
}, 'Buy'),
|
2017-11-14 08:04:23 -08:00
|
|
|
|
2018-01-16 18:17:28 -08:00
|
|
|
h('button', {
|
|
|
|
onClick: () => props.dispatch(actions.showSendPage()),
|
2018-07-26 04:42:04 -07:00
|
|
|
}, 'Send'),
|
2017-11-14 08:04:23 -08:00
|
|
|
|
|
|
|
]),
|
|
|
|
]),
|
|
|
|
|
|
|
|
// subview (tx history, pk export confirm, buy eth warning)
|
|
|
|
this.subview(),
|
|
|
|
|
|
|
|
])
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.subview = function () {
|
|
|
|
var subview
|
|
|
|
try {
|
|
|
|
subview = this.props.accountDetail.subview
|
|
|
|
} catch (e) {
|
|
|
|
subview = null
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (subview) {
|
|
|
|
case 'transactions':
|
|
|
|
return this.tabSections()
|
|
|
|
case 'export':
|
|
|
|
var state = extend({key: 'export'}, this.props)
|
|
|
|
return h(ExportAccountView, state)
|
|
|
|
default:
|
|
|
|
return this.tabSections()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.tabSections = function () {
|
|
|
|
const { currentAccountTab } = this.props
|
|
|
|
|
2018-07-30 06:09:33 -07:00
|
|
|
return h('section.tabSection.full-flex-height.grow-tenx', [
|
2017-11-14 08:04:23 -08:00
|
|
|
|
|
|
|
h(TabBar, {
|
|
|
|
tabs: [
|
|
|
|
{ content: 'Sent', key: 'history' },
|
|
|
|
{ content: 'Tokens', key: 'tokens' },
|
|
|
|
],
|
|
|
|
defaultTab: currentAccountTab || 'history',
|
|
|
|
tabSelected: (key) => {
|
|
|
|
this.props.dispatch(actions.setCurrentAccountTab(key))
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
|
|
|
|
this.tabSwitchView(),
|
|
|
|
])
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.tabSwitchView = function () {
|
|
|
|
const props = this.props
|
|
|
|
const { address, network } = props
|
|
|
|
const { currentAccountTab, tokens } = this.props
|
|
|
|
|
|
|
|
switch (currentAccountTab) {
|
|
|
|
case 'tokens':
|
|
|
|
return h(TokenList, {
|
|
|
|
userAddress: address,
|
|
|
|
network,
|
|
|
|
tokens,
|
|
|
|
addToken: () => this.props.dispatch(actions.showAddTokenPage()),
|
2018-07-24 04:59:24 -07:00
|
|
|
removeToken: (token) => this.props.dispatch(actions.showRemoveTokenPage(token)),
|
2017-11-14 08:04:23 -08:00
|
|
|
})
|
|
|
|
default:
|
|
|
|
return this.transactionList()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AccountDetailScreen.prototype.transactionList = function () {
|
|
|
|
const {transactions, unapprovedMsgs, address,
|
|
|
|
network, shapeShiftTxList, conversionRate } = this.props
|
|
|
|
|
|
|
|
return h(TransactionList, {
|
|
|
|
transactions: transactions.sort((a, b) => b.time - a.time),
|
|
|
|
network,
|
|
|
|
unapprovedMsgs,
|
|
|
|
conversionRate,
|
|
|
|
address,
|
|
|
|
shapeShiftTxList,
|
|
|
|
viewPendingTx: (txId) => {
|
|
|
|
this.props.dispatch(actions.viewPendingTx(txId))
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|