diff options
Diffstat (limited to 'ui/app/send.js')
-rw-r--r-- | ui/app/send.js | 209 |
1 files changed, 154 insertions, 55 deletions
diff --git a/ui/app/send.js b/ui/app/send.js index ff8ef4d65..ba4e5bfff 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -2,10 +2,13 @@ const inherits = require('util').inherits const Component = require('react').Component const h = require('react-hyperscript') const connect = require('react-redux').connect +const Identicon = require('./components/identicon') const actions = require('./actions') const util = require('./util') const numericBalance = require('./util').numericBalance -const AccountPanel = require('./components/account-panel') +const formatBalance = require('./util').formatBalance +const addressSummary = require('./util').addressSummary +const EtherBalance = require('./components/eth-balance') const ethUtil = require('ethereumjs-util') module.exports = connect(mapStateToProps)(SendTransactionScreen) @@ -18,6 +21,8 @@ function mapStateToProps(state) { warning: state.appState.warning, } + result.error = result.warning && result.warning.split('.')[0] + result.account = result.accounts[result.address] result.identity = result.identities[result.address] result.balance = result.account ? numericBalance(result.account.balance) : null @@ -32,95 +37,190 @@ function SendTransactionScreen() { SendTransactionScreen.prototype.render = function() { var state = this.props + var address = state.address var account = state.account var identity = state.identity return ( + h('.send-screen.flex-column.flex-grow', [ - // subtitle and nav - h('.section-title.flex-row.flex-center', [ - h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: this.back.bind(this), - }), - h('h2.page-subtitle', 'Send Transaction'), + // + // Sender Profile + // + + h('.account-data-subsection.flex-column.flex-grow', { + style: { + margin: '0 20px', + }, + }, [ + + // header - identicon + nav + h('.flex-row.flex-space-between', { + style: { + marginTop: 28, + }, + }, [ + + // invisible placeholder for later + h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', { + onClick: this.back.bind(this), + }), + + // large identicon + h('.identicon-wrapper.flex-column.flex-center.select-none', [ + h(Identicon, { + diameter: 62, + address: address, + }), + ]), + + // small accounts nav + h('i.fa.fa-users.fa-lg.cursor-pointer.color-orange', { + onClick: this.navigateToAccounts.bind(this), + }), + + ]), + + // account label + h('h2.font-medium.color-forest.flex-center', { + style: { + paddingTop: 8, + marginBottom: 8, + }, + }, identity && identity.name), + + // address and getter actions + h('.flex-row.flex-center', { + style: { + marginBottom: 8, + }, + }, [ + + h('div', { + style: { + lineHeight: '16px', + }, + }, addressSummary(address)), + + ]), + + // balance + h('.flex-row.flex-center', [ + + // h('div', formatBalance(account && account.balance)), + h(EtherBalance, { + value: account && account.balance, + }) + + ]), + + ]), + + // + // Required Fields + // + + h('h3.flex-center.text-transform-uppercase', { + style: { + background: '#EBEBEB', + color: '#AEAEAE', + marginTop: 32, + marginBottom: 16, + }, + }, [ + 'Send Transaction', ]), - h(AccountPanel, { - showFullAddress: true, - identity: identity, - account: account, - }), + // error message + state.error && h('span.error.flex-center', state.error), - h('section.recipient', [ - h('input.address', { + // 'to' field + h('section.flex-row.flex-center', [ + h('input.large-input', { + name: 'address', placeholder: 'Recipient Address', }) ]), - h('section.ammount', [ - h('input.ether', { + // 'amount' and send button + h('section.flex-row.flex-center', [ + + h('input.large-input', { + name: 'amount', placeholder: 'Amount', type: 'number', - style: { marginRight: '6px' } + style: { + marginRight: 6, + }, }), - h('select.currency', { - name: 'currency', - }, [ - h('option', { value: 'ether' }, 'Ether (1e18 wei)'), - h('option', { value: 'wei' }, 'Wei'), - ]), - ]), - h('section.data', [ - h('details', [ - h('summary', { - style: {cursor: 'pointer'}, - }, 'Advanced'), - h('textarea.txData', { - type: 'textarea', - placeholder: 'Transaction data (optional)', - style: { - height: '100px', - width: '100%', - resize: 'none', - } - }) - ]) + h('button.primary', { + onClick: this.onSubmit.bind(this), + style: { + textTransform: 'uppercase', + }, + }, 'Send') + ]), - h('section', { + // + // Optional Fields + // + + h('h3.flex-center.text-transform-uppercase', { + style: { + background: '#EBEBEB', + color: '#AEAEAE', + marginTop: 16, + marginBottom: 16, + }, }, [ - h('button', { - onClick: this.onSubmit.bind(this), - }, 'Send') + 'Tranasactional Data (optional)', + ]), + + // 'data' field + h('section.flex-row.flex-center', [ + h('input.large-input', { + name: 'txData', + placeholder: '0x01234', + style: { + width: '100%', + resize: 'none', + } + }), ]), - state.warning ? h('span.error', state.warning.split('.')[0]) : null, ]) + ) } +SendTransactionScreen.prototype.navigateToAccounts = function(event){ + event.stopPropagation() + this.props.dispatch(actions.showAccountsPage()) +} + SendTransactionScreen.prototype.back = function() { var address = this.props.address this.props.dispatch(actions.backToAccountDetail(address)) } -SendTransactionScreen.prototype.onSubmit = function(event) { - var recipient = document.querySelector('input.address').value +SendTransactionScreen.prototype.onSubmit = function() { - var inputAmount = parseFloat(document.querySelector('input.ether').value) - var currency = document.querySelector('select.currency').value - var value = util.normalizeNumberToWei(inputAmount, currency) - - var balance = this.props.balance + const recipient = document.querySelector('input[name="address"]').value + const input = document.querySelector('input[name="amount"]').value + const value = util.normalizeEthStringToWei(input) + const txData = document.querySelector('input[name="txData"]').value + const balance = this.props.balance if (value.gt(balance)) { var message = 'Insufficient funds.' return this.props.dispatch(actions.displayWarning(message)) } - if (recipient.length !== 42) { - var message = 'Recipient address is the incorrect length.' + + if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) { + var message = 'Recipient address is invalid.' return this.props.dispatch(actions.displayWarning(message)) } @@ -128,12 +228,11 @@ SendTransactionScreen.prototype.onSubmit = function(event) { this.props.dispatch(actions.showLoadingIndication()) var txParams = { - to: recipient, from: this.props.address, value: '0x' + value.toString(16), } - var txData = document.querySelector('textarea.txData').value + if (recipient) txParams.to = ethUtil.addHexPrefix(recipient) if (txData) txParams.data = txData this.props.dispatch(actions.signTx(txParams)) |