mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Handling to and amount errors.
This commit is contained in:
parent
f81226fbe9
commit
60eda592b5
@ -140,6 +140,7 @@ var actions = {
|
|||||||
UPDATE_SEND_TO: 'UPDATE_SEND_TO',
|
UPDATE_SEND_TO: 'UPDATE_SEND_TO',
|
||||||
UPDATE_SEND_AMOUNT: 'UPDATE_SEND_AMOUNT',
|
UPDATE_SEND_AMOUNT: 'UPDATE_SEND_AMOUNT',
|
||||||
UPDATE_SEND_MEMO: 'UPDATE_SEND_MEMO',
|
UPDATE_SEND_MEMO: 'UPDATE_SEND_MEMO',
|
||||||
|
UPDATE_SEND_ERRORS: 'UPDATE_SEND_ERRORS',
|
||||||
updateGasLimit,
|
updateGasLimit,
|
||||||
updateGasPrice,
|
updateGasPrice,
|
||||||
updateGasTotal,
|
updateGasTotal,
|
||||||
@ -147,6 +148,7 @@ var actions = {
|
|||||||
updateSendTo,
|
updateSendTo,
|
||||||
updateSendAmount,
|
updateSendAmount,
|
||||||
updateSendMemo,
|
updateSendMemo,
|
||||||
|
updateSendErrors,
|
||||||
setSelectedAddress,
|
setSelectedAddress,
|
||||||
// app messages
|
// app messages
|
||||||
confirmSeedWords: confirmSeedWords,
|
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) {
|
function sendTx (txData) {
|
||||||
log.info(`actions - sendTx: ${JSON.stringify(txData.txParams)}`)
|
log.info(`actions - sendTx: ${JSON.stringify(txData.txParams)}`)
|
||||||
|
@ -28,16 +28,12 @@ function resetCaretIfPastEnd (value, event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrencyDisplay.prototype.handleChangeInHexWei = function (value) {
|
function toHexWei (value) {
|
||||||
const { handleChange } = this.props
|
return conversionUtil(value, {
|
||||||
|
|
||||||
const valueInHexWei = conversionUtil(value, {
|
|
||||||
fromNumericBase: 'dec',
|
fromNumericBase: 'dec',
|
||||||
toNumericBase: 'hex',
|
toNumericBase: 'hex',
|
||||||
toDenomination: 'WEI',
|
toDenomination: 'WEI',
|
||||||
})
|
})
|
||||||
|
|
||||||
handleChange(valueInHexWei)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrencyDisplay.prototype.render = function () {
|
CurrencyDisplay.prototype.render = function () {
|
||||||
@ -51,7 +47,10 @@ CurrencyDisplay.prototype.render = function () {
|
|||||||
convertedPrefix = '',
|
convertedPrefix = '',
|
||||||
placeholder = '0',
|
placeholder = '0',
|
||||||
readOnly = false,
|
readOnly = false,
|
||||||
|
inError = false,
|
||||||
value: initValue,
|
value: initValue,
|
||||||
|
handleChange,
|
||||||
|
validate,
|
||||||
} = this.props
|
} = this.props
|
||||||
const { value } = this.state
|
const { value } = this.state
|
||||||
|
|
||||||
@ -73,6 +72,9 @@ CurrencyDisplay.prototype.render = function () {
|
|||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
className,
|
className,
|
||||||
|
style: {
|
||||||
|
borderColor: inError ? 'red' : null,
|
||||||
|
},
|
||||||
}, [
|
}, [
|
||||||
|
|
||||||
h('div.currency-display__primary-row', [
|
h('div.currency-display__primary-row', [
|
||||||
@ -100,8 +102,13 @@ CurrencyDisplay.prototype.render = function () {
|
|||||||
this.setState({ value: newValue })
|
this.setState({ value: newValue })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onBlur: event => !readOnly && this.handleChangeInHexWei(event.target.value.split(' ')[0]),
|
onBlur: event => !readOnly && handleChange(toHexWei(event.target.value.split(' ')[0])),
|
||||||
onKeyUp: event => !readOnly && resetCaretIfPastEnd(value || initValueToRender, event),
|
onKeyUp: event => {
|
||||||
|
if (!readOnly) {
|
||||||
|
validate(toHexWei(value || initValueToRender))
|
||||||
|
resetCaretIfPastEnd(value || initValueToRender, event)
|
||||||
|
}
|
||||||
|
},
|
||||||
onClick: event => !readOnly && resetCaretIfPastEnd(value || initValueToRender, event),
|
onClick: event => !readOnly && resetCaretIfPastEnd(value || initValueToRender, event),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -76,5 +76,6 @@ function mapDispatchToProps (dispatch) {
|
|||||||
updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)),
|
updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)),
|
||||||
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
|
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
|
||||||
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
|
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
|
||||||
|
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ function ToAutoComplete () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ToAutoComplete.prototype.render = function () {
|
ToAutoComplete.prototype.render = function () {
|
||||||
const { to, accounts, onChange } = this.props
|
const { to, accounts, onChange, inError } = this.props
|
||||||
|
|
||||||
return h('div.send-v2__to-autocomplete', [
|
return h('div.send-v2__to-autocomplete', [
|
||||||
|
|
||||||
@ -19,15 +19,15 @@ ToAutoComplete.prototype.render = function () {
|
|||||||
name: 'address',
|
name: 'address',
|
||||||
list: 'addresses',
|
list: 'addresses',
|
||||||
placeholder: 'Recipient Address',
|
placeholder: 'Recipient Address',
|
||||||
|
className: inError ? `send-v2__error-border` : '',
|
||||||
value: to,
|
value: to,
|
||||||
onChange,
|
onChange,
|
||||||
// onBlur: () => {
|
|
||||||
// this.setErrorsFor('to')
|
|
||||||
// },
|
|
||||||
onFocus: event => {
|
onFocus: event => {
|
||||||
// this.clearErrorsFor('to')
|
|
||||||
to && event.target.select()
|
to && event.target.select()
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
borderColor: inError ? 'red' : null,
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
h('datalist#addresses', [
|
h('datalist#addresses', [
|
||||||
|
@ -157,14 +157,11 @@ const multiplyCurrencies = (a, b, options = {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const conversionGreaterThan = (
|
const conversionGreaterThan = (
|
||||||
{ value, fromNumericBase },
|
{ ...firstProps },
|
||||||
{ value: compareToValue, fromNumericBase: compareToBase },
|
{ ...secondProps },
|
||||||
) => {
|
) => {
|
||||||
const firstValue = converter({ value, fromNumericBase })
|
const firstValue = converter({ ...firstProps })
|
||||||
const secondValue = converter({
|
const secondValue = converter({ ...secondProps })
|
||||||
value: compareToValue,
|
|
||||||
fromNumericBase: compareToBase,
|
|
||||||
})
|
|
||||||
return firstValue.gt(secondValue)
|
return firstValue.gt(secondValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,6 +497,17 @@
|
|||||||
width: 287px;
|
width: 287px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__error {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 12px;
|
||||||
|
left: 8px;
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__error-border {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
|
||||||
&__form {
|
&__form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -29,6 +29,7 @@ function reduceMetamask (state, action) {
|
|||||||
to: '',
|
to: '',
|
||||||
amount: '0x0',
|
amount: '0x0',
|
||||||
memo: '',
|
memo: '',
|
||||||
|
errors: {},
|
||||||
},
|
},
|
||||||
}, state.metamask)
|
}, 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:
|
default:
|
||||||
return metamaskState
|
return metamaskState
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ const GasFeeDisplay = require('./components/send/gas-fee-display-v2')
|
|||||||
|
|
||||||
const { showModal } = require('./actions')
|
const { showModal } = require('./actions')
|
||||||
|
|
||||||
const { multiplyCurrencies } = require('./conversion-util')
|
const { multiplyCurrencies, conversionGreaterThan } = require('./conversion-util')
|
||||||
|
const { isValidAddress } = require('./util')
|
||||||
|
|
||||||
module.exports = SendTransactionScreen
|
module.exports = SendTransactionScreen
|
||||||
|
|
||||||
@ -22,10 +23,15 @@ function SendTransactionScreen () {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
dropdownOpen: false,
|
dropdownOpen: false,
|
||||||
|
errors: {
|
||||||
|
to: null,
|
||||||
|
amount: null,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleToChange = this.handleToChange.bind(this)
|
this.handleToChange = this.handleToChange.bind(this)
|
||||||
this.handleAmountChange = this.handleAmountChange.bind(this)
|
this.handleAmountChange = this.handleAmountChange.bind(this)
|
||||||
|
this.validateAmount = this.validateAmount.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
SendTransactionScreen.prototype.componentWillMount = function () {
|
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 () {
|
SendTransactionScreen.prototype.renderFromRow = function () {
|
||||||
const {
|
const {
|
||||||
from,
|
from,
|
||||||
@ -155,57 +171,122 @@ SendTransactionScreen.prototype.renderFromRow = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SendTransactionScreen.prototype.handleToChange = function (event) {
|
SendTransactionScreen.prototype.handleToChange = function (event) {
|
||||||
const { updateSendTo } = this.props
|
const { updateSendTo, updateSendErrors } = this.props
|
||||||
const to = event.target.value
|
const to = event.target.value
|
||||||
|
let toError = null
|
||||||
|
|
||||||
|
if (!to) {
|
||||||
|
toError = 'Required'
|
||||||
|
} else if (!isValidAddress(to)) {
|
||||||
|
toError = 'Recipient address is invalid.'
|
||||||
|
}
|
||||||
|
|
||||||
updateSendTo(to)
|
updateSendTo(to)
|
||||||
|
updateSendErrors({ to: toError })
|
||||||
}
|
}
|
||||||
|
|
||||||
SendTransactionScreen.prototype.renderToRow = function () {
|
SendTransactionScreen.prototype.renderToRow = function () {
|
||||||
const { toAccounts } = this.props
|
const { toAccounts, errors } = this.props
|
||||||
const { to } = this.state
|
const { to } = this.state
|
||||||
|
|
||||||
return h('div.send-v2__form-row', [
|
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, {
|
h(ToAutoComplete, {
|
||||||
to,
|
to,
|
||||||
accounts: toAccounts,
|
accounts: toAccounts,
|
||||||
onChange: this.handleToChange,
|
onChange: this.handleToChange,
|
||||||
|
inError: Boolean(errors.to),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
SendTransactionScreen.prototype.handleAmountChange = function (value) {
|
SendTransactionScreen.prototype.handleAmountChange = function (value) {
|
||||||
const { updateSendAmount } = this.props
|
|
||||||
const amount = value
|
const amount = value
|
||||||
|
const { updateSendAmount } = this.props
|
||||||
|
|
||||||
updateSendAmount(amount)
|
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 () {
|
SendTransactionScreen.prototype.renderAmountRow = function () {
|
||||||
const {
|
const {
|
||||||
selectedToken,
|
selectedToken,
|
||||||
primaryCurrency = 'ETH',
|
primaryCurrency = 'ETH',
|
||||||
amountConversionRate,
|
amountConversionRate,
|
||||||
|
errors,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
const { amount } = this.state
|
const { amount } = this.state
|
||||||
|
|
||||||
return h('div.send-v2__form-row', [
|
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, {
|
h(CurrencyDisplay, {
|
||||||
|
inError: Boolean(errors.amount),
|
||||||
primaryCurrency,
|
primaryCurrency,
|
||||||
convertedCurrency: 'USD',
|
convertedCurrency: 'USD',
|
||||||
value: amount,
|
value: amount,
|
||||||
conversionRate: amountConversionRate,
|
conversionRate: amountConversionRate,
|
||||||
convertedPrefix: '$',
|
convertedPrefix: '$',
|
||||||
handleChange: this.handleAmountChange
|
handleChange: this.handleAmountChange,
|
||||||
}),
|
validate: this.validateAmount,
|
||||||
|
}),
|
||||||
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user