Handling to and amount errors.

feature/default_network_editable
Dan 7 years ago committed by Chi Kei Chan
parent f81226fbe9
commit 60eda592b5
  1. 10
      ui/app/actions.js
  2. 23
      ui/app/components/send/currency-display.js
  3. 1
      ui/app/components/send/send-v2-container.js
  4. 10
      ui/app/components/send/to-autocomplete.js
  5. 11
      ui/app/conversion-util.js
  6. 11
      ui/app/css/itcss/components/send.scss
  7. 16
      ui/app/reducers/metamask.js
  8. 95
      ui/app/send-v2.js

@ -140,6 +140,7 @@ var actions = {
UPDATE_SEND_TO: 'UPDATE_SEND_TO',
UPDATE_SEND_AMOUNT: 'UPDATE_SEND_AMOUNT',
UPDATE_SEND_MEMO: 'UPDATE_SEND_MEMO',
UPDATE_SEND_ERRORS: 'UPDATE_SEND_ERRORS',
updateGasLimit,
updateGasPrice,
updateGasTotal,
@ -147,6 +148,7 @@ var actions = {
updateSendTo,
updateSendAmount,
updateSendMemo,
updateSendErrors,
setSelectedAddress,
// app messages
confirmSeedWords: confirmSeedWords,
@ -553,6 +555,14 @@ function updateSendMemo (memo) {
}
}
function updateSendErrors (error) {
console.log(`updateSendErrors error`, error);
return {
type: actions.UPDATE_SEND_ERRORS,
value: error,
}
}
function sendTx (txData) {
log.info(`actions - sendTx: ${JSON.stringify(txData.txParams)}`)

@ -28,16 +28,12 @@ function resetCaretIfPastEnd (value, event) {
}
}
CurrencyDisplay.prototype.handleChangeInHexWei = function (value) {
const { handleChange } = this.props
const valueInHexWei = conversionUtil(value, {
function toHexWei (value) {
return conversionUtil(value, {
fromNumericBase: 'dec',
toNumericBase: 'hex',
toDenomination: 'WEI',
})
handleChange(valueInHexWei)
}
CurrencyDisplay.prototype.render = function () {
@ -51,7 +47,10 @@ CurrencyDisplay.prototype.render = function () {
convertedPrefix = '',
placeholder = '0',
readOnly = false,
inError = false,
value: initValue,
handleChange,
validate,
} = this.props
const { value } = this.state
@ -73,6 +72,9 @@ CurrencyDisplay.prototype.render = function () {
return h('div', {
className,
style: {
borderColor: inError ? 'red' : null,
},
}, [
h('div.currency-display__primary-row', [
@ -100,8 +102,13 @@ CurrencyDisplay.prototype.render = function () {
this.setState({ value: newValue })
}
},
onBlur: event => !readOnly && this.handleChangeInHexWei(event.target.value.split(' ')[0]),
onKeyUp: event => !readOnly && resetCaretIfPastEnd(value || initValueToRender, event),
onBlur: event => !readOnly && handleChange(toHexWei(event.target.value.split(' ')[0])),
onKeyUp: event => {
if (!readOnly) {
validate(toHexWei(value || initValueToRender))
resetCaretIfPastEnd(value || initValueToRender, event)
}
},
onClick: event => !readOnly && resetCaretIfPastEnd(value || initValueToRender, event),
}),

@ -76,5 +76,6 @@ function mapDispatchToProps (dispatch) {
updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)),
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),
}
}

@ -11,7 +11,7 @@ function ToAutoComplete () {
}
ToAutoComplete.prototype.render = function () {
const { to, accounts, onChange } = this.props
const { to, accounts, onChange, inError } = this.props
return h('div.send-v2__to-autocomplete', [
@ -19,15 +19,15 @@ ToAutoComplete.prototype.render = function () {
name: 'address',
list: 'addresses',
placeholder: 'Recipient Address',
className: inError ? `send-v2__error-border` : '',
value: to,
onChange,
// onBlur: () => {
// this.setErrorsFor('to')
// },
onFocus: event => {
// this.clearErrorsFor('to')
to && event.target.select()
},
style: {
borderColor: inError ? 'red' : null,
}
}),
h('datalist#addresses', [

@ -157,14 +157,11 @@ const multiplyCurrencies = (a, b, options = {}) => {
}
const conversionGreaterThan = (
{ value, fromNumericBase },
{ value: compareToValue, fromNumericBase: compareToBase },
{ ...firstProps },
{ ...secondProps },
) => {
const firstValue = converter({ value, fromNumericBase })
const secondValue = converter({
value: compareToValue,
fromNumericBase: compareToBase,
})
const firstValue = converter({ ...firstProps })
const secondValue = converter({ ...secondProps })
return firstValue.gt(secondValue)
}

@ -497,6 +497,17 @@
width: 287px;
}
&__error {
font-size: 12px;
line-height: 12px;
left: 8px;
color: $red;
}
&__error-border {
color: $red;
}
&__form {
display: flex;
flex-direction: column;

@ -29,6 +29,7 @@ function reduceMetamask (state, action) {
to: '',
amount: '0x0',
memo: '',
errors: {},
},
}, state.metamask)
@ -224,6 +225,21 @@ function reduceMetamask (state, action) {
},
})
case actions.UPDATE_SEND_ERRORS:
console.log(123, {
...metamaskState.send.errors,
...action.value,
})
return extend(metamaskState, {
send: {
...metamaskState.send,
errors: {
...metamaskState.send.errors,
...action.value,
}
},
})
default:
return metamaskState

@ -12,7 +12,8 @@ const GasFeeDisplay = require('./components/send/gas-fee-display-v2')
const { showModal } = require('./actions')
const { multiplyCurrencies } = require('./conversion-util')
const { multiplyCurrencies, conversionGreaterThan } = require('./conversion-util')
const { isValidAddress } = require('./util')
module.exports = SendTransactionScreen
@ -22,10 +23,15 @@ function SendTransactionScreen () {
this.state = {
dropdownOpen: false,
errors: {
to: null,
amount: null,
},
}
this.handleToChange = this.handleToChange.bind(this)
this.handleAmountChange = this.handleAmountChange.bind(this)
this.validateAmount = this.validateAmount.bind(this)
}
SendTransactionScreen.prototype.componentWillMount = function () {
@ -126,6 +132,16 @@ SendTransactionScreen.prototype.renderHeader = function () {
])
}
SendTransactionScreen.prototype.renderErrorMessage = function(errorType) {
const { errors } = this.props
console.log(`! errors`, errors);
const errorMessage = errors[errorType];
console.log(`errorMessage`, errorMessage);
return errorMessage
? h('div.send-v2__error', [ errorMessage ] )
: null
}
SendTransactionScreen.prototype.renderFromRow = function () {
const {
from,
@ -155,56 +171,121 @@ SendTransactionScreen.prototype.renderFromRow = function () {
}
SendTransactionScreen.prototype.handleToChange = function (event) {
const { updateSendTo } = this.props
const { updateSendTo, updateSendErrors } = this.props
const to = event.target.value
let toError = null
if (!to) {
toError = 'Required'
} else if (!isValidAddress(to)) {
toError = 'Recipient address is invalid.'
}
updateSendTo(to)
updateSendErrors({ to: toError })
}
SendTransactionScreen.prototype.renderToRow = function () {
const { toAccounts } = this.props
const { toAccounts, errors } = this.props
const { to } = this.state
return h('div.send-v2__form-row', [
h('div.send-v2__form-label', 'To:'),
h('div.send-v2__form-label', [
'To:',
this.renderErrorMessage('to'),
]),
h(ToAutoComplete, {
to,
accounts: toAccounts,
onChange: this.handleToChange,
inError: Boolean(errors.to),
}),
])
}
SendTransactionScreen.prototype.handleAmountChange = function (value) {
const { updateSendAmount } = this.props
const amount = value
const { updateSendAmount } = this.props
updateSendAmount(amount)
}
SendTransactionScreen.prototype.validateAmount = function (value) {
const {
from: { balance },
updateSendErrors,
amountConversionRate,
conversionRate,
primaryCurrency,
toCurrency,
selectedToken
} = this.props
const amount = value
let amountError = null
const sufficientBalance = conversionGreaterThan(
{
value: balance,
fromNumericBase: 'hex',
fromCurrency: primaryCurrency,
conversionRate,
},
{
value: amount,
fromNumericBase: 'hex',
conversionRate: amountConversionRate,
fromCurrency: selectedToken || primaryCurrency,
conversionRate: amountConversionRate,
},
)
console.log(`sufficientBalance`, sufficientBalance);
const amountLessThanZero = conversionGreaterThan(
{ value: 0, fromNumericBase: 'dec' },
{ value: amount, fromNumericBase: 'hex' },
)
if (!sufficientBalance) {
amountError = 'Insufficient funds.'
} else if (amountLessThanZero) {
amountError = 'Can not send negative amounts of ETH.'
}
updateSendErrors({ amount: amountError })
}
SendTransactionScreen.prototype.renderAmountRow = function () {
const {
selectedToken,
primaryCurrency = 'ETH',
amountConversionRate,
errors,
} = this.props
const { amount } = this.state
return h('div.send-v2__form-row', [
h('div.send-v2__form-label', 'Amount:'),
h('div.send-v2__form-label', [
'Amount:',
this.renderErrorMessage('amount'),
]),
h(CurrencyDisplay, {
inError: Boolean(errors.amount),
primaryCurrency,
convertedCurrency: 'USD',
value: amount,
conversionRate: amountConversionRate,
convertedPrefix: '$',
handleChange: this.handleAmountChange
handleChange: this.handleAmountChange,
validate: this.validateAmount,
}),
])

Loading…
Cancel
Save