aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/components/send_/send-content/send-amount-row
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/components/send_/send-content/send-amount-row')
-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.js36
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js0
-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.js91
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/send-amount-row.container.js45
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/send-amount-row.selectors.js14
-rw-r--r--ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js55
8 files changed, 295 insertions, 22 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..59a1fd6db 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 = {
+ tokenBalance: PropTypes.string,
+ gasTotal: PropTypes.string,
+ balance: PropTypes.string,
+ selectedToken: PropTypes.object,
+ setAmountToMax: PropTypes.func,
+ setMaxModeTo: PropTypes.func,
+ maxModeOn: PropTypes.bool,
+ };
+
+ setAmountToMax = function () {
+ const {
+ balance,
+ tokenBalance,
+ selectedToken,
+ gasTotal,
+ setAmountToMax,
+ } = this.props
+
+ setAmountToMax({
+ tokenBalance,
+ selectedToken,
+ gasTotal,
+ setAmountToMax,
+ })
+ }
+
+ render () {
+ const { setMaxModeTo } = this.props
+
+ return (
+ <div
+ className='send-v2__amount-max'
+ onClick={(event) => {
+ event.preventDefault()
+ setMaxModeTo(true)
+ this.setAmountToMax()
+ }}
+ >
+ {!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..572e1fc46 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,36 @@
+import {
+ getSelectedToken,
+ getGasTotal,
+ getTokenBalance,
+ getSendFromBalance,
+} from '../../../send.selectors.js'
+import { getMaxModeOn } from '../send-amount-row.selectors.js'
+import { calcMaxAmount } from './amount-max-button.utils.js'
+import {
+ updateSendAmount,
+ setMaxModeTo,
+} from '../../../actions'
+import AmountMaxButton from './amount-max-button.component'
+
+export default connect(mapStateToProps, mapDispatchToProps)(SendToRow)
+
+function mapStateToProps (state) {
+
+ return {
+ selectedToken: getSelectedToken(state),
+ maxModeOn: getMaxModeOn(state),
+ gasTotal: getGasTotal(state),
+ tokenBalance: getTokenBalance(state),
+ balance: getSendFromBalance(state),
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ setAmountToMax: maxAmountDataObject => {
+ updateSendErrors({ amount: null })
+ updateSendAmount(calcMaxAmount(maxAmountDataObject))
+ }
+ setMaxModeTo: bool => dispatch(setMaxModeTo(bool)),
+ }
+} \ No newline at end of file
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
deleted file mode 100644
index e69de29bb..000000000
--- a/ui/app/components/send_/send-content/send-amount-row/amount-max-button/amount-max-button.selectors.js
+++ /dev/null
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..54aacc8d7 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..78038f714 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,91 @@
+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.component'
+import CurrencyDisplay from '../../../send/currency-display'
+
+export default class SendAmountRow extends Component {
+
+ static propTypes = {
+ amountConversionRate: PropTypes.string,
+ conversionRate: PropTypes.string,
+ from: PropTypes.object,
+ gasTotal: PropTypes.string,
+ primaryCurrency: PropTypes.string,
+ selectedToken: PropTypes.object,
+ tokenBalance: PropTypes.string,
+ updateSendAmountError: PropTypes.func,
+ updateSendAmount: PropTypes.func,
+ setMaxModeTo: PropTypes.func
+ }
+
+ validateAmount (amount) {
+ const {
+ amountConversionRate,
+ conversionRate,
+ from: { balance },
+ 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,
+ inError,
+ gasTotal,
+ maxModeOn,
+ primaryCurrency = 'ETH',
+ selectedToken,
+ } = this.props
+
+ return (
+ <SendRowWrapper
+ label={`${this.context.t('amount')}:`}
+ showError={inError}
+ errorType={'amount'}
+ >
+ !inError && gasTotal && <AmountMaxButton />
+ <CurrencyDisplay
+ inError={inError},
+ primaryCurrency={primaryCurrency},
+ convertedCurrency={convertedCurrency},
+ selectedToken={selectedToken},
+ value={amount || '0x0'},
+ conversionRate={amountConversionRate},
+ handleChange={this.handleAmountChange},
+ >
+ </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..098855a02 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
@@ -7,42 +7,43 @@ import {
getGasTotal,
getSelectedBalance,
getTokenBalance,
+ getSendFromBalance,
} from '../../send.selectors.js'
import {
getMaxModeOn,
- getSendAmountError,
+ sendAmountIsInError,
} from './send-amount-row.selectors.js'
-import { getAmountErrorObject } from './send-to-row.utils.js'
+import { getAmountErrorObject } from './send-amount-row.utils.js'
import {
- updateSendErrors,
- updateSendTo,
+ updateSendAmount,
+ setMaxModeTo,
} from '../../../actions'
-import {
- openToDropdown,
- closeToDropdown,
-} from '../../../ducks/send'
-import SendToRow from './send-to-row.component'
+import SendAmountRow from './send-amount-row.component'
export default connect(mapStateToProps, mapDispatchToProps)(SendToRow)
function mapStateToProps (state) {
updateSendTo
return {
- to: getSendTo(state),
- toAccounts: getSendToAccounts(state),
- toDropdownOpen: getToDropdownOpen(state),
- inError: sendToIsInError(state),
- network: getCurrentNetwork(state),
+ selectedToken: getSelectedToken(state),
+ primaryCurrency: getPrimaryCurrency(state),
+ convertedCurrency: getConvertedCurrency(state),
+ amountConversionRate: getAmountConversionRate(state),
+ inError: sendAmountIsInError(state),
+ amount: getSendAmount(state),
+ maxModeOn: getMaxModeOn(state),
+ gasTotal: getGasTotal(state),
+ tokenBalance: getTokenBalance(state),
+ balance: getSendFromBalance(state),
}
}
function mapDispatchToProps (dispatch) {
-return {
- updateSendToError: (to) => {
- dispatch(updateSendErrors(getToErrorObject(to)))
- },
- updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
- openToDropdown: () => dispatch(()),
- closeToDropdown: () => dispatch(()),
-}
+ return {
+ updateSendAmountError: (amountDataObject) => {
+ dispatch(updateSendErrors(getAmountErrorObject(amountDataObject)))
+ },
+ updateSendAmount: newAmount => dispatch(updateSendAmount(newAmount)),
+ setMaxModeTo: bool => dispatch(setMaxModeTo(bool)),
+ }
} \ 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..724f345af 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,14 @@
+const selectors = {
+ getMaxModeOn,
+ sendAmountIsInError,
+}
+
+module.exports = selectors
+
+function getMaxModeOn (state) {
+ return state.metamask.send.maxModeOn
+}
+
+function sendAmountIsInError (state) {
+ return Boolean(state.metamask.send.errors.amount)
+}
diff --git a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js
index e69de29bb..5b01b4594 100644
--- a/ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js
+++ b/ui/app/components/send_/send-content/send-amount-row/send-amount-row.utils.js
@@ -0,0 +1,55 @@
+const { isValidAddress } = require('../../../../util')
+
+function getAmountErrorObject ({
+ amount,
+ balance,
+ amountConversionRate,
+ conversionRate,
+ primaryCurrency,
+ selectedToken,
+ gasTotal,
+ tokenBalance,
+}) {
+ let insufficientFunds = false
+ if (gasTotal && conversionRate) {
+ insufficientFunds = !isBalanceSufficient({
+ amount: selectedToken ? '0x0' : amount,
+ gasTotal,
+ balance,
+ primaryCurrency,
+ amountConversionRate,
+ conversionRate,
+ })
+ }
+
+ let inSufficientTokens = false
+ if (selectedToken && tokenBalance !== null) {
+ const { decimals } = selectedToken
+ inSufficientTokens = !isTokenBalanceSufficient({
+ tokenBalance,
+ amount,
+ decimals,
+ })
+ }
+
+ const amountLessThanZero = conversionGreaterThan(
+ { value: 0, fromNumericBase: 'dec' },
+ { value: amount, fromNumericBase: 'hex' },
+ )
+
+ let amountError = null
+
+ if (insufficientFunds) {
+ amountError = this.context.t('insufficientFunds')
+ } else if (insufficientTokens) {
+ amountError = this.context.t('insufficientTokens')
+ } else if (amountLessThanZero) {
+ amountError = this.context.t('negativeETH')
+ }
+
+ return { amount: amountError }
+}
+
+module.exports = {
+ getAmountErrorObject
+}