Update send token to handle errors onBlur events and prevent clicking send until all errors handled

feature/default_network_editable
Dan 7 years ago
parent 171d38c8db
commit a1d87b821b
  1. 71
      ui/app/components/send-token/index.js

@ -5,7 +5,7 @@ const classnames = require('classnames')
const inherits = require('util').inherits const inherits = require('util').inherits
const actions = require('../../actions') const actions = require('../../actions')
const selectors = require('../../selectors') const selectors = require('../../selectors')
const { isValidAddress } = require('../../util') const { isValidAddress, allNull } = require('../../util')
// const BalanceComponent = require('./balance-component') // const BalanceComponent = require('./balance-component')
const Identicon = require('../identicon') const Identicon = require('../identicon')
@ -65,7 +65,8 @@ function SendTokenScreen () {
Component.call(this) Component.call(this)
this.state = { this.state = {
to: '', to: '',
amount: '', amount: '0x0',
amountToSend: '0x0',
selectedCurrency: 'USD', selectedCurrency: 'USD',
isGasTooltipOpen: false, isGasTooltipOpen: false,
gasPrice: '0x5d21dba00', gasPrice: '0x5d21dba00',
@ -113,6 +114,46 @@ SendTokenScreen.prototype.validate = function () {
} }
} }
SendTokenScreen.prototype.setErrorsFor = function (field) {
const { balance, selectedToken } = this.props
const { errors: previousErrors } = this.state
const {
isValid,
errors: newErrors
} = this.validate()
const nextErrors = Object.assign({}, previousErrors, {
[field]: newErrors[field] || null
})
if (!isValid) {
this.setState({
errors: nextErrors,
isValid,
})
}
}
SendTokenScreen.prototype.clearErrorsFor = function (field) {
const { errors: previousErrors } = this.state
const nextErrors = Object.assign({}, previousErrors, {
[field]: null
})
this.setState({
errors: nextErrors,
isValid: allNull(nextErrors),
})
}
SendTokenScreen.prototype.getAmountToSend = function (amount, selectedToken) {
const { decimals } = selectedToken || {}
const multiplier = Math.pow(10, Number(decimals || 0))
const sendAmount = Number(amount * multiplier).toString(16)
return sendAmount
}
SendTokenScreen.prototype.submit = function () { SendTokenScreen.prototype.submit = function () {
const { const {
to, to,
@ -132,11 +173,6 @@ SendTokenScreen.prototype.submit = function () {
} = this.props } = this.props
const { nickname = ' ' } = identities[to] || {} const { nickname = ' ' } = identities[to] || {}
const { isValid, errors } = this.validate()
if (!isValid) {
return this.setState({ errors })
}
hideWarning() hideWarning()
addToAddressBook(to, nickname) addToAddressBook(to, nickname)
@ -148,9 +184,7 @@ SendTokenScreen.prototype.submit = function () {
gasPrice: gasPrice, gasPrice: gasPrice,
} }
const { decimals } = selectedToken || {} const sendAmount = this.getAmountToSend(amount, selectedToken)
const multiplier = Math.pow(10, Number(decimals || 0))
const sendAmount = Number(amount * multiplier).toString(16)
signTokenTx(selectedTokenAddress, to, sendAmount, txParams) signTokenTx(selectedTokenAddress, to, sendAmount, txParams)
} }
@ -181,6 +215,8 @@ SendTokenScreen.prototype.renderToAddressInput = function () {
to: e.target.value, to: e.target.value,
errors: {}, errors: {},
}), }),
onBlur: () => this.setErrorsFor('to'),
onFocus: () => this.clearErrorsFor('to'),
}), }),
h('datalist#addresses', [ h('datalist#addresses', [
// Corresponds to the addresses owned. // Corresponds to the addresses owned.
@ -234,8 +270,9 @@ SendTokenScreen.prototype.renderAmountInput = function () {
value: amount, value: amount,
onChange: e => this.setState({ onChange: e => this.setState({
amount: e.target.value, amount: e.target.value,
errors: {},
}), }),
onBlur: () => this.setErrorsFor('amount'),
onFocus: () => this.clearErrorsFor('amount'),
}), }),
h('div.send-screen-input-wrapper__error-message', [ errorMessage ]), h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
]) ])
@ -272,6 +309,14 @@ SendTokenScreen.prototype.renderGasInput = function () {
onFeeChange: ({ gasLimit, gasPrice }) => { onFeeChange: ({ gasLimit, gasPrice }) => {
this.setState({ gasLimit, gasPrice, errors: {} }) this.setState({ gasLimit, gasPrice, errors: {} })
}, },
onBlur: () => {
this.setErrorsFor('gasLimit')
this.setErrorsFor('gasPrice')
},
onFocus: () => {
this.clearErrorsFor('gasLimit')
this.clearErrorsFor('gasPrice')
},
}), }),
h('div.send-screen-gas-labels', {}, [ h('div.send-screen-gas-labels', {}, [
@ -311,10 +356,12 @@ SendTokenScreen.prototype.renderMemoInput = function () {
SendTokenScreen.prototype.renderButtons = function () { SendTokenScreen.prototype.renderButtons = function () {
const { selectedAddress, backToAccountDetail } = this.props const { selectedAddress, backToAccountDetail } = this.props
const { isValid } = this.validate()
return h('div.send-token__button-group', [ return h('div.send-token__button-group', [
h('button.send-token__button-next.btn-secondary', { h('button.send-token__button-next.btn-secondary', {
onClick: () => this.submit(), className: !isValid && 'send-screen__send-button__disabled',
onClick: () => isValid && this.submit(),
}, ['Next']), }, ['Next']),
h('button.send-token__button-cancel.btn-tertiary', { h('button.send-token__button-cancel.btn-tertiary', {
onClick: () => backToAccountDetail(selectedAddress), onClick: () => backToAccountDetail(selectedAddress),

Loading…
Cancel
Save