aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/components/send_/send-content
diff options
context:
space:
mode:
authorDan <danjm.com@gmail.com>2018-05-01 10:42:57 +0800
committerDan <danjm.com@gmail.com>2018-05-01 10:42:57 +0800
commit2f78fffbdbb0e41d73bcde2c15c88fff095614b7 (patch)
tree24d68a267304d085ee1b7c705ce5ade53c9439c3 /ui/app/components/send_/send-content
parentf96c13d616e429447ac0a6a24c6aeee902162b88 (diff)
parent954394f81090b1a6a4afe55243caa3671b88addc (diff)
downloadtangerine-wallet-browser-2f78fffbdbb0e41d73bcde2c15c88fff095614b7.tar.gz
tangerine-wallet-browser-2f78fffbdbb0e41d73bcde2c15c88fff095614b7.tar.zst
tangerine-wallet-browser-2f78fffbdbb0e41d73bcde2c15c88fff095614b7.zip
Merge branch 'i3725-refactor-send-component-' into i3725-refactor-send-component-2
Diffstat (limited to 'ui/app/components/send_/send-content')
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js54
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js40
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js9
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js22
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js96
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js69
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js9
-rw-r--r--ui/app/components/send_/send-content/send-content.component.js23
-rw-r--r--ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js75
-rw-r--r--ui/app/components/send_/send-content/send-from-row/send-from-row.component.js29
-rw-r--r--ui/app/components/send_/send-content/send-from-row/send-from-row.container.js34
-rw-r--r--ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js4
-rw-r--r--ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js49
-rw-r--r--ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js26
-rw-r--r--ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js9
-rw-r--r--ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js10
-rw-r--r--ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js3
-rw-r--r--ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js22
-rw-r--r--ui/app/components/send_/send-content/send-to-row/send-to-row.component.js48
-rw-r--r--ui/app/components/send_/send-content/send-to-row/send-to-row.container.js28
-rw-r--r--ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js2
-rw-r--r--ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js12
22 files changed, 552 insertions, 121 deletions
diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js
index e69de29bb..bdf12b738 100644
--- a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js
+++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.component.js
@@ -0,0 +1,54 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+
+export default class AmountMaxButton extends Component {
+
+ static propTypes = {
+ balance: PropTypes.string,
+ gasTotal: PropTypes.string,
+ maxModeOn: PropTypes.bool,
+ selectedToken: PropTypes.object,
+ setAmountToMax: PropTypes.func,
+ setMaxModeTo: PropTypes.func,
+ tokenBalance: PropTypes.string,
+ };
+
+ setMaxAmount () {
+ const {
+ balance,
+ gasTotal,
+ selectedToken,
+ setAmountToMax,
+ tokenBalance,
+ } = this.props
+
+ setAmountToMax({
+ balance,
+ gasTotal,
+ selectedToken,
+ tokenBalance,
+ })
+ }
+
+ render () {
+ const { setMaxModeTo, maxModeOn } = this.props
+
+ return (
+ <div
+ className="send-v2__amount-max"
+ onClick={(event) => {
+ event.preventDefault()
+ setMaxModeTo(true)
+ this.setMaxAmount()
+ }}
+ >
+ {!maxModeOn ? this.context.t('max') : ''}
+ </div>
+ )
+ }
+
+}
+
+AmountMaxButton.contextTypes = {
+ t: PropTypes.func,
+}
diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js
index e69de29bb..a72f41775 100644
--- a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js
+++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.container.js
@@ -0,0 +1,40 @@
+import { connect } from 'react-redux'
+import {
+ getGasTotal,
+ getSelectedToken,
+ getSendFromBalance,
+ getTokenBalance,
+} from '../../../send.selectors.js'
+import { getMaxModeOn } from './amount-max-button.selectors.js'
+import { calcMaxAmount } from './amount-max-button.utils.js'
+import {
+ updateSendAmount,
+ setMaxModeTo,
+} from '../../../../../actions'
+import AmountMaxButton from './amount-max-button.component'
+import {
+ updateSendErrors,
+} from '../../../../../ducks/send'
+
+export default connect(mapStateToProps, mapDispatchToProps)(AmountMaxButton)
+
+function mapStateToProps (state) {
+
+ return {
+ balance: getSendFromBalance(state),
+ gasTotal: getGasTotal(state),
+ maxModeOn: getMaxModeOn(state),
+ selectedToken: getSelectedToken(state),
+ tokenBalance: getTokenBalance(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ setAmountToMax: maxAmountDataObject => {
+ dispatch(updateSendErrors({ amount: null }))
+ dispatch(updateSendAmount(calcMaxAmount(maxAmountDataObject)))
+ },
+ setMaxModeTo: bool => dispatch(setMaxModeTo(bool)),
+ }
+}
diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js
index e69de29bb..69fec1994 100644
--- a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js
+++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js
@@ -0,0 +1,9 @@
+const selectors = {
+ getMaxModeOn,
+}
+
+module.exports = selectors
+
+function getMaxModeOn (state) {
+ return state.metamask.send.maxModeOn
+}
diff --git a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js
index e69de29bb..b490a7fd7 100644
--- a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js
+++ b/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.utils.js
@@ -0,0 +1,22 @@
+const {
+ multiplyCurrencies,
+ subtractCurrencies,
+} = require('../../../../../conversion-util')
+const ethUtil = require('ethereumjs-util')
+
+function calcMaxAmount ({ balance, gasTotal, selectedToken, tokenBalance }) {
+ const { decimals } = selectedToken || {}
+ const multiplier = Math.pow(10, Number(decimals || 0))
+
+ return selectedToken
+ ? multiplyCurrencies(tokenBalance, multiplier, {toNumericBase: 'hex'})
+ : subtractCurrencies(
+ ethUtil.addHexPrefix(balance),
+ ethUtil.addHexPrefix(gasTotal),
+ { toNumericBase: 'hex' }
+ )
+}
+
+module.exports = {
+ calcMaxAmount,
+}
diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js
index e69de29bb..8e201ae41 100644
--- a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js
+++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.component.js
@@ -0,0 +1,96 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import SendRowWrapper from '../send-row-wrapper/send-row-wrapper.component'
+import AmountMaxButton from './amount-max-button/amount-max-button.container'
+import CurrencyDisplay from '../../../send/currency-display'
+
+export default class SendAmountRow extends Component {
+
+ static propTypes = {
+ amount: PropTypes.string,
+ amountConversionRate: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.number,
+ ]),
+ balance: PropTypes.string,
+ conversionRate: PropTypes.number,
+ convertedCurrency: PropTypes.string,
+ gasTotal: PropTypes.string,
+ inError: PropTypes.bool,
+ primaryCurrency: PropTypes.string,
+ selectedToken: PropTypes.object,
+ setMaxModeTo: PropTypes.func,
+ tokenBalance: PropTypes.string,
+ updateSendAmount: PropTypes.func,
+ updateSendAmountError: PropTypes.func,
+ }
+
+ validateAmount (amount) {
+ const {
+ amountConversionRate,
+ balance,
+ conversionRate,
+ gasTotal,
+ primaryCurrency,
+ selectedToken,
+ tokenBalance,
+ updateSendAmountError,
+ } = this.props
+
+ updateSendAmountError({
+ amount,
+ amountConversionRate,
+ balance,
+ conversionRate,
+ gasTotal,
+ primaryCurrency,
+ selectedToken,
+ tokenBalance,
+ })
+ }
+
+ handleAmountChange (amount) {
+ const { updateSendAmount, setMaxModeTo } = this.props
+
+ setMaxModeTo(false)
+ this.validateAmount(amount)
+ updateSendAmount(amount)
+ }
+
+ render () {
+ const {
+ amount,
+ amountConversionRate,
+ convertedCurrency,
+ gasTotal,
+ inError,
+ primaryCurrency = 'ETH',
+ selectedToken,
+ } = this.props
+
+ return (
+ <SendRowWrapper
+ label={`${this.context.t('amount')}:`}
+ showError={inError}
+ errorType={'amount'}
+ >
+ {!inError && gasTotal && <AmountMaxButton />}
+ <CurrencyDisplay
+ conversionRate={amountConversionRate}
+ convertedCurrency={convertedCurrency}
+ handleChange={newAmount => this.handleAmountChange(newAmount)}
+ inError={inError}
+ primaryCurrency={primaryCurrency}
+ selectedToken={selectedToken}
+ value={amount || '0x0'}
+ />
+ </SendRowWrapper>
+ )
+ }
+
+}
+
+SendAmountRow.contextTypes = {
+ t: PropTypes.func,
+}
+
diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js
index 6ae80e7f2..13888ec53 100644
--- a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js
+++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js
@@ -1,48 +1,51 @@
+import { connect } from 'react-redux'
import {
- getSelectedToken,
- getPrimaryCurrency,
getAmountConversionRate,
+ getConversionRate,
getConvertedCurrency,
- getSendAmount,
getGasTotal,
- getSelectedBalance,
+ getPrimaryCurrency,
+ getSelectedToken,
+ getSendAmount,
+ getSendFromBalance,
getTokenBalance,
-} from '../../send.selectors.js'
+} from '../../send.selectors'
import {
- getMaxModeOn,
- getSendAmountError,
-} from './send-amount-row.selectors.js'
-import { getAmountErrorObject } from './send-to-row.utils.js'
+ sendAmountIsInError,
+} from './send-amount-row.selectors'
+import { getAmountErrorObject } from '../../send.utils'
import {
- updateSendErrors,
- updateSendTo,
-} from '../../../actions'
+ setMaxModeTo,
+ updateSendAmount,
+} from '../../../../actions'
import {
- openToDropdown,
- closeToDropdown,
-} from '../../../ducks/send'
-import SendToRow from './send-to-row.component'
+ updateSendErrors,
+} from '../../../../ducks/send'
+import SendAmountRow from './send-amount-row.component'
-export default connect(mapStateToProps, mapDispatchToProps)(SendToRow)
+export default connect(mapStateToProps, mapDispatchToProps)(SendAmountRow)
function mapStateToProps (state) {
-updateSendTo
-return {
- to: getSendTo(state),
- toAccounts: getSendToAccounts(state),
- toDropdownOpen: getToDropdownOpen(state),
- inError: sendToIsInError(state),
- network: getCurrentNetwork(state),
-}
+ return {
+ amount: getSendAmount(state),
+ amountConversionRate: getAmountConversionRate(state),
+ balance: getSendFromBalance(state),
+ conversionRate: getConversionRate(state),
+ convertedCurrency: getConvertedCurrency(state),
+ gasTotal: getGasTotal(state),
+ inError: sendAmountIsInError(state),
+ primaryCurrency: getPrimaryCurrency(state),
+ selectedToken: getSelectedToken(state),
+ tokenBalance: getTokenBalance(state),
+ }
}
function mapDispatchToProps (dispatch) {
-return {
- updateSendToError: (to) => {
- dispatch(updateSendErrors(getToErrorObject(to)))
- },
- updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
- openToDropdown: () => dispatch(()),
- closeToDropdown: () => dispatch(()),
+ return {
+ setMaxModeTo: bool => dispatch(setMaxModeTo(bool)),
+ updateSendAmount: newAmount => dispatch(updateSendAmount(newAmount)),
+ updateSendAmountError: (amountDataObject) => {
+ dispatch(updateSendErrors(getAmountErrorObject(amountDataObject)))
+ },
+ }
}
-} \ No newline at end of file
diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js
index e69de29bb..fb08c7ed7 100644
--- a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js
+++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js
@@ -0,0 +1,9 @@
+const selectors = {
+ sendAmountIsInError,
+}
+
+module.exports = selectors
+
+function sendAmountIsInError (state) {
+ return Boolean(state.send.errors.amount)
+}
diff --git a/ui/app/components/send_/send-content/send-content.component.js b/ui/app/components/send_/send-content/send-content.component.js
index e69de29bb..e213cfcf3 100644
--- a/ui/app/components/send_/send-content/send-content.component.js
+++ b/ui/app/components/send_/send-content/send-content.component.js
@@ -0,0 +1,23 @@
+import React, { Component } from 'react'
+import PageContainerContent from '../../page-container/page-container-content.component'
+import SendAmountRow from './send-amount-row/send-amount-row.container'
+import SendFromRow from './send-from-row/send-from-row.container'
+import SendGasRow from './send-gas-row/send-gas-row.container'
+import SendToRow from './send-to-row/send-to-row.container'
+
+export default class SendContent extends Component {
+
+ render () {
+ return (
+ <PageContainerContent>
+ <div className="send-v2__form">
+ <SendFromRow />
+ <SendToRow />
+ <SendAmountRow />
+ <SendGasRow />
+ </div>
+ </PageContainerContent>
+ )
+ }
+
+}
diff --git a/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js
index e69de29bb..337228122 100644
--- a/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js
+++ b/ui/app/components/send_/send-content/send-from-row/from-dropdown/from-dropdown.component.js
@@ -0,0 +1,75 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import AccountListItem from '../../../account-list-item/account-list-item.container'
+
+export default class FromDropdown extends Component {
+
+ static propTypes = {
+ accounts: PropTypes.array,
+ closeDropdown: PropTypes.func,
+ dropdownOpen: PropTypes.bool,
+ onSelect: PropTypes.func,
+ openDropdown: PropTypes.func,
+ selectedAccount: PropTypes.object,
+ };
+
+ renderListItemIcon (icon, color) {
+ return <i className={`fa ${icon} fa-lg`} style={ { color } }/>
+ }
+
+ getListItemIcon (currentAccount, selectedAccount) {
+ return currentAccount.address === selectedAccount.address
+ ? this.renderListItemIcon('fa-check', '#02c9b1')
+ : null
+ }
+
+ renderDropdown () {
+ const {
+ accounts,
+ closeDropdown,
+ onSelect,
+ selectedAccount,
+ } = this.props
+
+ return (<div>
+ <div
+ className="send-v2__from-dropdown__close-area"
+ onClick={() => closeDropdown}
+ />
+ <div className="send-v2__from-dropdown__list">
+ {accounts.map((account, index) => <AccountListItem
+ account={account}
+ className="account-list-item__dropdown"
+ handleClick={() => {
+ onSelect(account)
+ closeDropdown()
+ }}
+ icon={this.getListItemIcon(account, selectedAccount.address)}
+ key={`from-dropdown-account-#${index}`}
+ />)}
+ </div>
+ </div>)
+ }
+
+ render () {
+ const {
+ dropdownOpen,
+ openDropdown,
+ selectedAccount,
+ } = this.props
+
+ return <div className="send-v2__from-dropdown">
+ <AccountListItem
+ account={selectedAccount}
+ handleClick={openDropdown}
+ icon={this.renderListItemIcon('fa-caret-down', '#dedede')}
+ />
+ {dropdownOpen && this.renderDropdown()},
+ </div>
+ }
+
+}
+
+FromDropdown.contextTypes = {
+ t: PropTypes.func,
+}
diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row.component.js b/ui/app/components/send_/send-content/send-from-row/send-from-row.component.js
index 7582cb2e6..17e7f8e46 100644
--- a/ui/app/components/send_/send-content/send-from-row/send-from-row.component.js
+++ b/ui/app/components/send_/send-content/send-from-row/send-from-row.component.js
@@ -1,60 +1,59 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
-import SendRowWrapper from '../../../send/from-dropdown'
-import FromDropdown from ''
+import SendRowWrapper from '../send-row-wrapper/send-row-wrapper.component'
+import FromDropdown from './from-dropdown/from-dropdown.component'
export default class SendFromRow extends Component {
static propTypes = {
closeFromDropdown: PropTypes.func,
- conversionRate: PropTypes.string,
- from: PropTypes.string,
+ conversionRate: PropTypes.number,
+ from: PropTypes.object,
fromAccounts: PropTypes.array,
fromDropdownOpen: PropTypes.bool,
openFromDropdown: PropTypes.func,
tokenContract: PropTypes.object,
updateSendFrom: PropTypes.func,
- updateSendTokenBalance: PropTypes.func,
+ setSendTokenBalance: PropTypes.func,
};
async handleFromChange (newFrom) {
const {
updateSendFrom,
tokenContract,
- updateSendTokenBalance,
+ setSendTokenBalance,
} = this.props
if (tokenContract) {
const usersToken = await tokenContract.balanceOf(newFrom.address)
- updateSendTokenBalance(usersToken)
+ setSendTokenBalance(usersToken)
}
updateSendFrom(newFrom)
}
render () {
const {
+ closeFromDropdown,
+ conversionRate,
from,
fromAccounts,
- conversionRate,
fromDropdownOpen,
- tokenContract,
openFromDropdown,
- closeFromDropdown,
} = this.props
return (
<SendRowWrapper label={`${this.context.t('from')}:`}>
<FromDropdown
- dropdownOpen={fromDropdownOpen}
accounts={fromAccounts}
- selectedAccount={from}
- onSelect={newFrom => this.handleFromChange(newFrom)}
- openDropdown={() => openFromDropdown()}
closeDropdown={() => closeFromDropdown()}
conversionRate={conversionRate}
+ dropdownOpen={fromDropdownOpen}
+ onSelect={newFrom => this.handleFromChange(newFrom)}
+ openDropdown={() => openFromDropdown()}
+ selectedAccount={from}
/>
</SendRowWrapper>
- );
+ )
}
}
diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row.container.js b/ui/app/components/send_/send-content/send-from-row/send-from-row.container.js
index 2ff3f0ccd..9e366445d 100644
--- a/ui/app/components/send_/send-content/send-from-row/send-from-row.container.js
+++ b/ui/app/components/send_/send-content/send-from-row/send-from-row.container.js
@@ -1,29 +1,31 @@
+import { connect } from 'react-redux'
import {
- getSendFrom,
- conversionRateSelector,
- getSelectedTokenContract,
- getCurrentAccountWithSendEtherInfo,
accountsWithSendEtherInfoSelector,
+ getConversionRate,
+ getSelectedTokenContract,
+ getSendFromObject,
} from '../../send.selectors.js'
-import { getFromDropdownOpen } from './send-from-row.selectors.js'
+import {
+ getFromDropdownOpen,
+} from './send-from-row.selectors.js'
import { calcTokenUpdateAmount } from './send-from-row.utils.js'
import {
- updateSendTokenBalance,
updateSendFrom,
-} from '../../../actions'
+ setSendTokenBalance,
+} from '../../../../actions'
import {
- openFromDropdown,
closeFromDropdown,
-} from '../../../ducks/send'
+ openFromDropdown,
+} from '../../../../ducks/send'
import SendFromRow from './send-from-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendFromRow)
function mapStateToProps (state) {
return {
- from: getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state),
+ conversionRate: getConversionRate(state),
+ from: getSendFromObject(state),
fromAccounts: accountsWithSendEtherInfoSelector(state),
- conversionRate: conversionRateSelector(state),
fromDropdownOpen: getFromDropdownOpen(state),
tokenContract: getSelectedTokenContract(state),
}
@@ -31,14 +33,14 @@ function mapStateToProps (state) {
function mapDispatchToProps (dispatch) {
return {
- updateSendTokenBalance: (usersToken, selectedToken) => {
+ closeFromDropdown: () => dispatch(closeFromDropdown()),
+ openFromDropdown: () => dispatch(openFromDropdown()),
+ updateSendFrom: newFrom => dispatch(updateSendFrom(newFrom)),
+ setSendTokenBalance: (usersToken, selectedToken) => {
if (!usersToken) return
const tokenBalance = calcTokenUpdateAmount(selectedToken, selectedToken)
- dispatch(updateSendTokenBalance(tokenBalance))
+ dispatch(setSendTokenBalance(tokenBalance))
},
- updateSendFrom: newFrom => dispatch(updateSendFrom(newFrom)),
- openFromDropdown: () => dispatch(()),
- closeFromDropdown: () => dispatch(()),
}
}
diff --git a/ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js b/ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js
index 2be25816f..0aaaef793 100644
--- a/ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js
+++ b/ui/app/components/send_/send-content/send-from-row/send-from-row.utils.js
@@ -1,6 +1,6 @@
const {
calcTokenAmount,
-} = require('../../token-util')
+} = require('../../../../token-util')
function calcTokenUpdateAmount (usersToken, selectedToken) {
const { decimals } = selectedToken || {}
@@ -8,5 +8,5 @@ function calcTokenUpdateAmount (usersToken, selectedToken) {
}
module.exports = {
- calcTokenUpdateAmount
+ calcTokenUpdateAmount,
}
diff --git a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js
index e69de29bb..c62c110e0 100644
--- a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js
+++ b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.component.js
@@ -0,0 +1,49 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import SendRowWrapper from '../send-row-wrapper/send-row-wrapper.component'
+import GasFeeDisplay from '../../../send/gas-fee-display-v2'
+
+export default class SendGasRow extends Component {
+
+ static propTypes = {
+ closeFromDropdown: PropTypes.func,
+ conversionRate: PropTypes.number,
+ convertedCurrency: PropTypes.string,
+ from: PropTypes.string,
+ fromAccounts: PropTypes.array,
+ fromDropdownOpen: PropTypes.bool,
+ gasLoadingError: PropTypes.bool,
+ gasTotal: PropTypes.string,
+ openFromDropdown: PropTypes.func,
+ showCustomizeGasModal: PropTypes.func,
+ tokenContract: PropTypes.object,
+ updateSendFrom: PropTypes.func,
+ };
+
+ render () {
+ const {
+ conversionRate,
+ convertedCurrency,
+ gasLoadingError,
+ gasTotal,
+ showCustomizeGasModal,
+ } = this.props
+
+ return (
+ <SendRowWrapper label={`${this.context.t('gasFee')}:`}>
+ <GasFeeDisplay
+ conversionRate={conversionRate}
+ convertedCurrency={convertedCurrency}
+ gasLoadingError={gasLoadingError}
+ gasTotal={gasTotal}
+ onClick={() => showCustomizeGasModal()}
+ />
+ </SendRowWrapper>
+ )
+ }
+
+}
+
+SendGasRow.contextTypes = {
+ t: PropTypes.func,
+}
diff --git a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js
index e69de29bb..20d3daa59 100644
--- a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js
+++ b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.container.js
@@ -0,0 +1,26 @@
+import { connect } from 'react-redux'
+import {
+ getConversionRate,
+ getConvertedCurrency,
+ getGasTotal,
+} from '../../send.selectors.js'
+import { sendGasIsInError } from './send-gas-row.selectors.js'
+import { showModal } from '../../../../actions'
+import SendGasRow from './send-gas-row.component'
+
+export default connect(mapStateToProps, mapDispatchToProps)(SendGasRow)
+
+function mapStateToProps (state) {
+ return {
+ conversionRate: getConversionRate(state),
+ convertedCurrency: getConvertedCurrency(state),
+ gasTotal: getGasTotal(state),
+ gasLoadingError: sendGasIsInError(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS' })),
+ }
+}
diff --git a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js
index e69de29bb..ad4ef4877 100644
--- a/ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js
+++ b/ui/app/components/send_/send-content/send-gas-row/send-gas-row.selectors.js
@@ -0,0 +1,9 @@
+const selectors = {
+ sendGasIsInError,
+}
+
+module.exports = selectors
+
+function sendGasIsInError (state) {
+ return state.metamask.send.errors.gasLoading
+}
diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js
index 08f830cc5..0d314208b 100644
--- a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js
+++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.component.js
@@ -1,3 +1,6 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+
export default class SendRowErrorMessage extends Component {
static propTypes = {
@@ -7,17 +10,18 @@ export default class SendRowErrorMessage extends Component {
render () {
const { errors, errorType } = this.props
+
const errorMessage = errors[errorType]
return (
errorMessage
- ? <div className='send-v2__error'>{errorMessage}</div>
+ ? <div className="send-v2__error">{this.context.t(errorMessage)}</div>
: null
- );
+ )
}
}
SendRowErrorMessage.contextTypes = {
t: PropTypes.func,
-} \ No newline at end of file
+}
diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js
index 2278dbe63..59622047f 100644
--- a/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js
+++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-error-message/send-row-error-message.container.js
@@ -1,3 +1,4 @@
+import { connect } from 'react-redux'
import { getSendErrors } from '../../../send.selectors'
import SendRowErrorMessage from './send-row-error-message.component'
@@ -8,4 +9,4 @@ function mapStateToProps (state, ownProps) {
errors: getSendErrors(state),
errorType: ownProps.errorType,
}
-} \ No newline at end of file
+}
diff --git a/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js
index a1ac591b9..707b3ae80 100644
--- a/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js
+++ b/ui/app/components/send_/send-content/send-row-wrapper/send-row-wrapper.component.js
@@ -5,31 +5,35 @@ import SendRowErrorMessage from './send-row-error-message/send-row-error-message
export default class SendRowWrapper extends Component {
static propTypes = {
- label: PropTypes.string,
- showError: PropTypes.bool,
children: PropTypes.node,
errorType: PropTypes.string,
+ label: PropTypes.string,
+ showError: PropTypes.bool,
};
render () {
const {
- label,
- errorType = '',
- showError = false,
- children,
+ children,
+ errorType = '',
+ label,
+ showError = false,
} = this.props
+ const formField = Array.isArray(children) ? children[1] || children[0] : children
+ const customLabelContent = children.length > 1 ? children[0] : null
+
return (
<div className="send-v2__form-row">
<div className="send-v2__form-label">
{label}
- (showError && <SendRowErrorMessage errorType={errorType}/>)
+ {showError && <SendRowErrorMessage errorType={errorType}/>}
+ {customLabelContent}
</div>
<div className="send-v2__form-field">
- {children}
+ {formField}
</div>
</div>
- );
+ )
}
}
diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.component.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.component.js
index abcb54efc..a6e4c1624 100644
--- a/ui/app/components/send_/send-content/send-to-row/send-to-row.component.js
+++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.component.js
@@ -1,57 +1,59 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
-import SendRowWrapper from '../../../send/from-dropdown'
-import ToDropdown from '../../../ens-input'
+import SendRowWrapper from '../send-row-wrapper/send-row-wrapper.component'
+import EnsInput from '../../../ens-input'
export default class SendToRow extends Component {
static propTypes = {
+ closeToDropdown: PropTypes.func,
+ inError: PropTypes.bool,
+ network: PropTypes.string,
+ openToDropdown: PropTypes.func,
to: PropTypes.string,
toAccounts: PropTypes.array,
toDropdownOpen: PropTypes.bool,
- inError: PropTypes.bool,
updateSendTo: PropTypes.func,
updateSendToError: PropTypes.func,
- openToDropdown: PropTypes.func,
- closeToDropdown: PropTypes.func,
- network: PropTypes.number,
};
handleToChange (to, nickname = '') {
const { updateSendTo, updateSendToError } = this.props
updateSendTo(to, nickname)
- updateSendErrors(to)
+ updateSendToError(to)
}
render () {
const {
- from,
- fromAccounts,
- conversionRate,
- fromDropdownOpen,
- tokenContract,
- openToDropdown,
closeToDropdown,
- network,
inError,
+ network,
+ openToDropdown,
+ to,
+ toAccounts,
+ toDropdownOpen,
} = this.props
return (
- <SendRowWrapper label={`${this.context.t('to')}:`}>
+ <SendRowWrapper
+ errorType={'to'}
+ label={`${this.context.t('to')}:`}
+ showError={inError}
+ >
<EnsInput
- name={'address'}
- placeholder={this.context.t('recipient Address')}
- network={network},
- to={to},
accounts={toAccounts}
- dropdownOpen={toDropdownOpen}
- openDropdown={() => openToDropdown()}
closeDropdown={() => closeToDropdown()}
- onChange={this.handleToChange}
+ dropdownOpen={toDropdownOpen}
inError={inError}
+ name={'address'}
+ network={network}
+ onChange={(newTo, newNickname) => this.handleToChange(newTo, newNickname)}
+ openDropdown={() => openToDropdown()}
+ placeholder={this.context.t('recipientAddress')}
+ to={to}
/>
</SendRowWrapper>
- );
+ )
}
}
diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.container.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.container.js
index 1c446c168..bffdda49c 100644
--- a/ui/app/components/send_/send-content/send-to-row/send-to-row.container.js
+++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.container.js
@@ -1,7 +1,8 @@
+import { connect } from 'react-redux'
import {
- getSendTo,
- getToAccounts,
getCurrentNetwork,
+ getSendTo,
+ getSendToAccounts,
} from '../../send.selectors.js'
import {
getToDropdownOpen,
@@ -9,35 +10,34 @@ import {
} from './send-to-row.selectors.js'
import { getToErrorObject } from './send-to-row.utils.js'
import {
- updateSendErrors,
updateSendTo,
-} from '../../../actions'
+} from '../../../../actions'
import {
- openToDropdown,
- closeToDropdown,
-} from '../../../ducks/send'
+ updateSendErrors,
+ openToDropdown,
+ closeToDropdown,
+} from '../../../../ducks/send'
import SendToRow from './send-to-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendToRow)
function mapStateToProps (state) {
- updateSendTo
return {
+ inError: sendToIsInError(state),
+ network: getCurrentNetwork(state),
to: getSendTo(state),
toAccounts: getSendToAccounts(state),
toDropdownOpen: getToDropdownOpen(state),
- inError: sendToIsInError(state),
- network: getCurrentNetwork(state),
}
}
function mapDispatchToProps (dispatch) {
return {
+ closeToDropdown: () => dispatch(closeToDropdown()),
+ openToDropdown: () => dispatch(openToDropdown()),
+ updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
updateSendToError: (to) => {
dispatch(updateSendErrors(getToErrorObject(to)))
},
- updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
- openToDropdown: () => dispatch(()),
- closeToDropdown: () => dispatch(()),
}
-} \ No newline at end of file
+}
diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js
index 05bb65fa3..8919014be 100644
--- a/ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js
+++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.selectors.js
@@ -10,5 +10,5 @@ function getToDropdownOpen (state) {
}
function sendToIsInError (state) {
- return Boolean(state.metamask.send.to)
+ return Boolean(state.send.errors.to)
}
diff --git a/ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js b/ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js
index 52bfde009..22e2e1f34 100644
--- a/ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js
+++ b/ui/app/components/send_/send-content/send-to-row/send-to-row.utils.js
@@ -1,17 +1,21 @@
+const {
+ REQUIRED_ERROR,
+ INVALID_RECIPIENT_ADDRESS_ERROR,
+} = require('../../send.constants')
const { isValidAddress } = require('../../../../util')
function getToErrorObject (to) {
let toError = null
if (!to) {
- toError = 'required'
+ toError = REQUIRED_ERROR
} else if (!isValidAddress(to)) {
- toError = 'invalidAddressRecipient'
+ toError = INVALID_RECIPIENT_ADDRESS_ERROR
}
-
+
return { to: toError }
}
module.exports = {
- getToErrorObject
+ getToErrorObject,
}