aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorDan <danjm.com@gmail.com>2017-10-23 04:14:03 +0800
committerChi Kei Chan <chikeichan@gmail.com>2017-10-24 13:41:30 +0800
commite737a9565a6b78639b74511d026339c1b54bca1a (patch)
tree62ed4e91a0ea5835d90e4015f1c094f4ea27e7ca /ui
parenta7069acf2e93e9eae543bb84dfdda1f5e10b3e19 (diff)
downloadtangerine-wallet-browser-e737a9565a6b78639b74511d026339c1b54bca1a.tar
tangerine-wallet-browser-e737a9565a6b78639b74511d026339c1b54bca1a.tar.gz
tangerine-wallet-browser-e737a9565a6b78639b74511d026339c1b54bca1a.tar.bz2
tangerine-wallet-browser-e737a9565a6b78639b74511d026339c1b54bca1a.tar.lz
tangerine-wallet-browser-e737a9565a6b78639b74511d026339c1b54bca1a.tar.xz
tangerine-wallet-browser-e737a9565a6b78639b74511d026339c1b54bca1a.tar.zst
tangerine-wallet-browser-e737a9565a6b78639b74511d026339c1b54bca1a.zip
Improve customize gas modal error handling
Diffstat (limited to 'ui')
-rw-r--r--ui/app/components/customize-gas-modal/index.js144
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js2
-rw-r--r--ui/app/components/send/send-constants.js20
-rw-r--r--ui/app/components/send/send-utils.js39
-rw-r--r--ui/app/components/send/send-v2-container.js8
-rw-r--r--ui/app/css/itcss/components/send.scss20
-rw-r--r--ui/app/selectors.js23
-rw-r--r--ui/app/send-v2.js33
8 files changed, 230 insertions, 59 deletions
diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js
index 744891c47..710ee24c0 100644
--- a/ui/app/components/customize-gas-modal/index.js
+++ b/ui/app/components/customize-gas-modal/index.js
@@ -6,23 +6,46 @@ const actions = require('../../actions')
const GasModalCard = require('./gas-modal-card')
const {
- MIN_GAS_PRICE,
- MIN_GAS_LIMIT,
+ MIN_GAS_PRICE_DEC,
+ MIN_GAS_LIMIT_DEC,
+ MIN_GAS_PRICE_GWEI,
} = require('../send/send-constants')
-const { conversionUtil, multiplyCurrencies } = require('../../conversion-util')
+const {
+ isBalanceSufficient,
+} = require('../send/send-utils')
+
+const {
+ conversionUtil,
+ multiplyCurrencies,
+ conversionGreaterThan,
+} = require('../../conversion-util')
const {
getGasPrice,
getGasLimit,
conversionRateSelector,
+ getSendAmount,
+ getSelectedToken,
+ getSendFrom,
+ getCurrentAccountWithSendEtherInfo,
+ getSelectedTokenToFiatRate,
} = require('../../selectors')
function mapStateToProps (state) {
+ const selectedToken = getSelectedToken(state)
+ const currentAccount = getSendFrom(state) || getCurrentAccountWithSendEtherInfo(state)
+ const conversionRate = conversionRateSelector(state)
+
return {
gasPrice: getGasPrice(state),
gasLimit: getGasLimit(state),
- conversionRate: conversionRateSelector(state),
+ conversionRate,
+ amount: getSendAmount(state),
+ balance: currentAccount.balance,
+ primaryCurrency: selectedToken && selectedToken.symbol,
+ selectedToken,
+ amountConversionRate: selectedToken ? getSelectedTokenToFiatRate(state) : conversionRate,
}
}
@@ -39,15 +62,26 @@ inherits(CustomizeGasModal, Component)
function CustomizeGasModal (props) {
Component.call(this)
+ const gasPrice = props.gasPrice || MIN_GAS_PRICE_DEC
+ const gasLimit = props.gasLimit || MIN_GAS_LIMIT_DEC
+
+ const gasTotal = multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+
this.state = {
- gasPrice: props.gasPrice || MIN_GAS_PRICE,
- gasLimit: props.gasLimit || MIN_GAS_LIMIT,
+ gasPrice,
+ gasLimit,
+ gasTotal,
+ error: null,
}
}
module.exports = connect(mapStateToProps, mapDispatchToProps)(CustomizeGasModal)
-CustomizeGasModal.prototype.save = function (gasPrice, gasLimit) {
+CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) {
const {
updateGasPrice,
updateGasLimit,
@@ -55,41 +89,101 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit) {
updateGasTotal
} = this.props
- const newGasTotal = multiplyCurrencies(gasLimit, gasPrice, {
- toNumericBase: 'hex',
- multiplicandBase: 16,
- multiplierBase: 16,
- })
-
updateGasPrice(gasPrice)
updateGasLimit(gasLimit)
- updateGasTotal(newGasTotal)
+ updateGasTotal(gasTotal)
hideModal()
}
+CustomizeGasModal.prototype.validate = function ({ gasTotal, gasLimit }) {
+ const {
+ amount,
+ balance,
+ primaryCurrency,
+ selectedToken,
+ amountConversionRate,
+ conversionRate,
+ } = this.props
+
+ let error = null
+
+ const balanceIsSufficient = isBalanceSufficient({
+ amount,
+ gasTotal,
+ balance,
+ primaryCurrency,
+ selectedToken,
+ amountConversionRate,
+ conversionRate,
+ })
+
+ if (!balanceIsSufficient) {
+ error = 'Insufficient balance for current gas total'
+ }
+
+ const gasLimitTooLow = gasLimit && conversionGreaterThan(
+ {
+ value: MIN_GAS_LIMIT_DEC,
+ fromNumericBase: 'dec',
+ conversionRate,
+ },
+ {
+ value: gasLimit,
+ fromNumericBase: 'hex',
+ },
+ )
+
+ if (gasLimitTooLow) {
+ error = 'Gas limit must be at least 21000'
+ }
+
+ this.setState({ error })
+ return error
+}
+
CustomizeGasModal.prototype.convertAndSetGasLimit = function (newGasLimit) {
- const convertedGasLimit = conversionUtil(newGasLimit, {
+ const { gasPrice } = this.state
+
+ const gasLimit = conversionUtil(newGasLimit, {
fromNumericBase: 'dec',
toNumericBase: 'hex',
})
- this.setState({ gasLimit: convertedGasLimit })
+ const gasTotal = multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+
+ this.validate({ gasTotal, gasLimit })
+
+ this.setState({ gasTotal, gasLimit })
}
CustomizeGasModal.prototype.convertAndSetGasPrice = function (newGasPrice) {
- const convertedGasPrice = conversionUtil(newGasPrice, {
+ const { gasLimit } = this.state
+
+ const gasPrice = conversionUtil(newGasPrice, {
fromNumericBase: 'dec',
toNumericBase: 'hex',
fromDenomination: 'GWEI',
toDenomination: 'WEI',
})
- this.setState({ gasPrice: convertedGasPrice })
+ const gasTotal = multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+
+ this.validate({ gasTotal })
+
+ this.setState({ gasTotal, gasPrice })
}
CustomizeGasModal.prototype.render = function () {
const { hideModal, conversionRate } = this.props
- const { gasPrice, gasLimit } = this.state
+ const { gasPrice, gasLimit, gasTotal, error } = this.state
const convertedGasPrice = conversionUtil(gasPrice, {
fromNumericBase: 'hex',
@@ -120,7 +214,7 @@ CustomizeGasModal.prototype.render = function () {
h(GasModalCard, {
value: convertedGasPrice,
- min: MIN_GAS_PRICE,
+ min: MIN_GAS_PRICE_GWEI,
// max: 1000,
step: 1,
onChange: value => this.convertAndSetGasPrice(value),
@@ -130,7 +224,7 @@ CustomizeGasModal.prototype.render = function () {
h(GasModalCard, {
value: convertedGasLimit,
- min: MIN_GAS_LIMIT,
+ min: 1,
// max: 100000,
step: 1,
onChange: value => this.convertAndSetGasLimit(value),
@@ -141,6 +235,10 @@ CustomizeGasModal.prototype.render = function () {
]),
h('div.send-v2__customize-gas__footer', {}, [
+
+ error && h('div.send-v2__customize-gas__error-message', [
+ error,
+ ]),
h('div.send-v2__customize-gas__revert', {
onClick: () => console.log('Revert'),
@@ -151,8 +249,8 @@ CustomizeGasModal.prototype.render = function () {
onClick: this.props.hideModal,
}, ['CANCEL']),
- h('div.send-v2__customize-gas__save', {
- onClick: () => this.save(gasPrice, gasLimit),
+ h(`div.send-v2__customize-gas__save${error ? '__error' : ''}`, {
+ onClick: () => !error && this.save(gasPrice, gasLimit, gasTotal),
}, ['SAVE']),
])
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index 7162c7122..64da630f6 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -50,7 +50,7 @@ ConfirmSendEther.prototype.getAmount = function () {
const { conversionRate, currentCurrency } = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
- console.log(`conversionRate, currentCurrency`, conversionRate, currentCurrency);
+
const FIAT = conversionUtil(txParams.value, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
diff --git a/ui/app/components/send/send-constants.js b/ui/app/components/send/send-constants.js
index a819a8c28..8b56607cc 100644
--- a/ui/app/components/send/send-constants.js
+++ b/ui/app/components/send/send-constants.js
@@ -3,12 +3,19 @@ const { multiplyCurrencies } = require('../../conversion-util')
const MIN_GAS_PRICE_GWEI = '1'
const GWEI_FACTOR = '1e9'
-const MIN_GAS_PRICE = multiplyCurrencies(GWEI_FACTOR, MIN_GAS_PRICE_GWEI, {
+const MIN_GAS_PRICE_HEX = multiplyCurrencies(GWEI_FACTOR, MIN_GAS_PRICE_GWEI, {
multiplicandBase: 16,
multiplierBase: 16,
+ toNumericBase: 'hex',
+})
+const MIN_GAS_PRICE_DEC = multiplyCurrencies(GWEI_FACTOR, MIN_GAS_PRICE_GWEI, {
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ toNumericBase: 'dec',
})
-const MIN_GAS_LIMIT = (21000).toString(16)
-const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT, MIN_GAS_PRICE, {
+const MIN_GAS_LIMIT_HEX = (21000).toString(16)
+const MIN_GAS_LIMIT_DEC = 21000
+const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT_HEX, MIN_GAS_PRICE_HEX, {
toNumericBase: 'hex',
multiplicandBase: 16,
multiplierBase: 16,
@@ -16,8 +23,9 @@ const MIN_GAS_TOTAL = multiplyCurrencies(MIN_GAS_LIMIT, MIN_GAS_PRICE, {
module.exports = {
MIN_GAS_PRICE_GWEI,
- GWEI_FACTOR,
- MIN_GAS_PRICE,
- MIN_GAS_LIMIT,
+ MIN_GAS_PRICE_HEX,
+ MIN_GAS_PRICE_DEC,
+ MIN_GAS_LIMIT_HEX,
+ MIN_GAS_LIMIT_DEC,
MIN_GAS_TOTAL,
}
diff --git a/ui/app/components/send/send-utils.js b/ui/app/components/send/send-utils.js
new file mode 100644
index 000000000..bf096d610
--- /dev/null
+++ b/ui/app/components/send/send-utils.js
@@ -0,0 +1,39 @@
+const { addCurrencies, conversionGreaterThan } = require('../../conversion-util')
+
+function isBalanceSufficient({
+ amount,
+ gasTotal,
+ balance,
+ primaryCurrency,
+ selectedToken,
+ amountConversionRate,
+ conversionRate,
+}) {
+ const totalAmount = addCurrencies(amount, gasTotal, {
+ aBase: 16,
+ bBase: 16,
+ toNumericBase: 'hex',
+ })
+
+ const balanceIsSufficient = conversionGreaterThan(
+ {
+ value: balance,
+ fromNumericBase: 'hex',
+ fromCurrency: primaryCurrency,
+ conversionRate,
+ },
+ {
+ value: totalAmount,
+ fromNumericBase: 'hex',
+ conversionRate: amountConversionRate,
+ fromCurrency: selectedToken || primaryCurrency,
+ conversionRate: amountConversionRate,
+ },
+ )
+
+ return balanceIsSufficient
+}
+
+module.exports = {
+ isBalanceSufficient,
+} \ No newline at end of file
diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js
index 80b52a3ab..fb2634de2 100644
--- a/ui/app/components/send/send-v2-container.js
+++ b/ui/app/components/send/send-v2-container.js
@@ -17,6 +17,7 @@ const {
getAddressBook,
getSendFrom,
getCurrentCurrency,
+ getSelectedTokenToFiatRate,
} = require('../../selectors')
module.exports = connect(mapStateToProps, mapDispatchToProps)(SendEther)
@@ -26,7 +27,6 @@ function mapStateToProps (state) {
const selectedAddress = getSelectedAddress(state)
const selectedToken = getSelectedToken(state)
const tokenExchangeRates = state.metamask.tokenExchangeRates
- const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
const conversionRate = conversionRateSelector(state)
let data;
@@ -40,11 +40,7 @@ function mapStateToProps (state) {
primaryCurrency = selectedToken.symbol
- tokenToFiatRate = multiplyCurrencies(
- conversionRate,
- selectedTokenExchangeRate,
- { toNumericBase: 'dec' }
- )
+ tokenToFiatRate = getSelectedTokenToFiatRate(state)
}
return {
diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss
index c4efeccf0..d2415f26c 100644
--- a/ui/app/css/itcss/components/send.scss
+++ b/ui/app/css/itcss/components/send.scss
@@ -738,6 +738,7 @@
align-items: center;
justify-content: space-between;
font-size: 22px;
+ position: relative;
}
&__buttons {
@@ -747,7 +748,7 @@
margin-right: 21.25px;
}
- &__revert, &__cancel, &__save {
+ &__revert, &__cancel, &__save, &__save__error {
display: flex;
justify-content: center;
align-items: center;
@@ -760,7 +761,7 @@
margin-left: 21.25px;
}
- &__cancel, &__save {
+ &__cancel, &__save, &__save__error {
height: 34.64px;
width: 85.74px;
border: 1px solid $dusty-gray;
@@ -769,6 +770,21 @@
font-size: 12px;
color: $dusty-gray;
}
+
+ &__save__error {
+ opacity: 0.5;
+ cursor: auto;
+ }
+
+ &__error-message {
+ display: block;
+ position: absolute;
+ top: 4px;
+ right: 4px;
+ font-size: 12px;
+ line-height: 12px;
+ color: $red;
+ }
}
&__gas-modal-card {
diff --git a/ui/app/selectors.js b/ui/app/selectors.js
index 4c3d21d33..3a15cef4c 100644
--- a/ui/app/selectors.js
+++ b/ui/app/selectors.js
@@ -1,5 +1,9 @@
const valuesFor = require('./util').valuesFor
+const {
+ multiplyCurrencies,
+} = require('./conversion-util')
+
const selectors = {
getSelectedAddress,
getSelectedIdentity,
@@ -16,6 +20,8 @@ const selectors = {
getAddressBook,
getSendFrom,
getCurrentCurrency,
+ getSendAmount,
+ getSelectedTokenToFiatRate,
}
module.exports = selectors
@@ -123,6 +129,23 @@ function getSendFrom (state) {
return state.metamask.send.from
}
+function getSendAmount (state) {
+ return state.metamask.send.amount
+}
+
function getCurrentCurrency (state) {
return state.metamask.currentCurrency
}
+
+function getSelectedTokenToFiatRate (state) {
+ const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
+ const conversionRate = conversionRateSelector(state)
+
+ const tokenToFiatRate = multiplyCurrencies(
+ conversionRate,
+ selectedTokenExchangeRate,
+ { toNumericBase: 'dec' }
+ )
+
+ return tokenToFiatRate
+}
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index 4986edf5f..16e4d7801 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -19,6 +19,9 @@ const {
conversionGreaterThan,
addCurrencies,
} = require('./conversion-util')
+const {
+ isBalanceSufficient,
+} = require('./components/send/send-utils.js')
const { isValidAddress } = require('./util')
module.exports = SendTransactionScreen
@@ -237,28 +240,16 @@ SendTransactionScreen.prototype.validateAmount = function (value) {
let amountError = null
- const totalAmount = addCurrencies(amount, gasTotal, {
- aBase: 16,
- bBase: 16,
- toNumericBase: 'hex',
+ const sufficientBalance = isBalanceSufficient({
+ amount,
+ gasTotal,
+ balance,
+ primaryCurrency,
+ selectedToken,
+ amountConversionRate,
+ conversionRate,
})
- const sufficientBalance = conversionGreaterThan(
- {
- value: balance,
- fromNumericBase: 'hex',
- fromCurrency: primaryCurrency,
- conversionRate,
- },
- {
- value: totalAmount,
- fromNumericBase: 'hex',
- conversionRate: amountConversionRate,
- fromCurrency: selectedToken || primaryCurrency,
- conversionRate: amountConversionRate,
- },
- )
-
const amountLessThanZero = conversionGreaterThan(
{ value: 0, fromNumericBase: 'dec' },
{ value: amount, fromNumericBase: 'hex' },
@@ -387,7 +378,7 @@ SendTransactionScreen.prototype.renderFooter = function () {
clearSend,
errors: { amount: amountError, to: toError }
} = this.props
-
+
const noErrors = amountError === null && toError === null
const errorClass = noErrors ? '' : '__disabled'