From 66758b784a5ca4b6829a6d4c895739fcc0a5ad61 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Mon, 23 Oct 2017 15:57:14 -0700 Subject: [PATCH 01/17] Update token menu css --- ui/app/css/itcss/components/newui-sections.scss | 1 + ui/app/css/itcss/components/token-list.scss | 6 ++++-- yarn.lock | 14 ++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index 1ee8283ef..5e0acb1ec 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -45,6 +45,7 @@ $wallet-view-bg: $wild-sand; flex-direction: column; flex: 33.5 0 33.5%; background: $wallet-view-bg; + z-index: 200; @media screen and (min-width: 576px) { overflow-y: scroll; diff --git a/ui/app/css/itcss/components/token-list.scss b/ui/app/css/itcss/components/token-list.scss index bbc64c324..d4add71b1 100644 --- a/ui/app/css/itcss/components/token-list.scss +++ b/ui/app/css/itcss/components/token-list.scss @@ -67,19 +67,21 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( position: fixed; margin-top: 20px; margin-left: 105px; + z-index: 2000; &__close-area { position: fixed; top: 0; left: 0; - z-index: 1000; + z-index: 2100; width: 100%; height: 100%; + cursor: default; } &__container { padding: 16px 34px 32px; - z-index: 1050; + z-index: 2200; position: relative; } diff --git a/yarn.lock b/yarn.lock index ef81fe3ce..7b04eb638 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3450,9 +3450,9 @@ eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7: promise-to-callback "^1.0.0" tape "^4.6.3" -eth-keyring-controller@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-2.1.1.tgz#08129c8300f0ac6de9110e0b8d51292b5c6327e3" +eth-keyring-controller@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-2.1.2.tgz#1af179d8fd7ff470eb91e113a0fd3a440bd66bcc" dependencies: bip39 "^2.4.0" bluebird "^3.5.0" @@ -8540,14 +8540,12 @@ samsam@1.x, samsam@^1.1.3: version "1.2.1" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67" -sandwich-expando@^1.0.5: - version "1.1.1" - resolved "https://registry.yarnpkg.com/sandwich-expando/-/sandwich-expando-1.1.1.tgz#83806fcca2375af8b6c30e6f52ed4f989debb165" +sandwich-expando@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sandwich-expando/-/sandwich-expando-1.1.3.tgz#6ba78d034c32f8bf5ab5934c214f8384614a88a5" dependencies: babel-preset-es2015 "^6.6.0" babelify "^7.3.0" - brfs "^1.4.3" - raphael "^2.2.0" react "^15.0.2" react-dom "^15.0.2" react-hyperscript "^2.4.0" From 754d117d189d81839bad3b5715b2d049779b4882 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 23 Oct 2017 22:04:44 -0700 Subject: [PATCH 02/17] Fix settings styling on mobile view --- ui/app/css/itcss/components/settings.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ui/app/css/itcss/components/settings.scss b/ui/app/css/itcss/components/settings.scss index d4bcdcc4b..d37a9d10d 100644 --- a/ui/app/css/itcss/components/settings.scss +++ b/ui/app/css/itcss/components/settings.scss @@ -38,6 +38,7 @@ @media screen and (max-width: 575px) { flex-direction: column; + padding: 10px 0; } } @@ -48,6 +49,11 @@ flex-direction: column; padding: 0 5px; height: 71px; + + @media screen and (max-width: 575px) { + height: initial; + padding: 5px 0; + } } .settings__content-item-col { @@ -71,6 +77,7 @@ padding-left: 10px; font-size: 14px; height: 40px; + border: 1px solid $alto; } .settings__input::-webkit-input-placeholder { From 09d659614ed8a3d7627002eb77f0953b7f495f7e Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 23 Oct 2017 09:35:53 -0230 Subject: [PATCH 03/17] Cleaner implementation of currency-display input. --- ui/app/components/send/currency-display.js | 36 ++++++++----------- .../itcss/components/currency-display.scss | 10 ++++++ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/ui/app/components/send/currency-display.js b/ui/app/components/send/currency-display.js index 799e9b56d..5dba6a8dd 100644 --- a/ui/app/components/send/currency-display.js +++ b/ui/app/components/send/currency-display.js @@ -20,14 +20,6 @@ function isValidInput (text) { return re.test(text) } -function resetCaretIfPastEnd (value, event) { - const caretPosition = event.target.selectionStart - - if (caretPosition > value.length) { - event.target.setSelectionRange(value.length, value.length) - } -} - function toHexWei (value) { return conversionUtil(value, { fromNumericBase: 'dec', @@ -82,6 +74,8 @@ CurrencyDisplay.prototype.render = function () { conversionRate, }) + const inputSizeMultiplier = readOnly ? 1 : 1.2; + return h('div', { className, style: { @@ -95,35 +89,33 @@ CurrencyDisplay.prototype.render = function () { h('input', { className: primaryBalanceClassName, - value: `${value || initValueToRender} ${primaryCurrency}`, - placeholder: `${0} ${primaryCurrency}`, + value: `${value || initValueToRender}`, + placeholder: '0', + size: (value || initValueToRender).length * inputSizeMultiplier, readOnly, onChange: (event) => { - let newValue = event.target.value.split(' ')[0] + let newValue = event.target.value if (newValue === '') { - this.setState({ value: '0' }) + newValue = '0' } else if (newValue.match(/^0[1-9]$/)) { - this.setState({ value: newValue.match(/[1-9]/)[0] }) + newValue = newValue.match(/[1-9]/)[0] } - else if (newValue && !isValidInput(newValue)) { + + if (newValue && !isValidInput(newValue)) { event.preventDefault() } else { + validate(this.getAmount(newValue)) this.setState({ value: newValue }) } }, - onBlur: event => !readOnly && handleChange(this.getAmount(event.target.value.split(' ')[0])), - onKeyUp: event => { - if (!readOnly) { - validate(toHexWei(value || initValueToRender)) - resetCaretIfPastEnd(value || initValueToRender, event) - } - }, - onClick: event => !readOnly && resetCaretIfPastEnd(value || initValueToRender, event), + onBlur: event => !readOnly && handleChange(this.getAmount(event.target.value)), }), + h('span.currency-display__currency-symbol', primaryCurrency), + ]), ]), diff --git a/ui/app/css/itcss/components/currency-display.scss b/ui/app/css/itcss/components/currency-display.scss index eb1776c58..9459629b6 100644 --- a/ui/app/css/itcss/components/currency-display.scss +++ b/ui/app/css/itcss/components/currency-display.scss @@ -22,6 +22,7 @@ line-height: 22px; border: none; outline: 0 !important; + max-width: 100%; } &__primary-currency { @@ -43,4 +44,13 @@ font-size: 12px; line-height: 12px; } + + &__input-wrapper { + position: relative; + display: flex; + } + + &__currency-symbol { + margin-top: 1px; + } } \ No newline at end of file From a7069acf2e93e9eae543bb84dfdda1f5e10b3e19 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 21 Oct 2017 00:06:42 -0230 Subject: [PATCH 04/17] Disable send-v2 next button if in error --- ui/app/css/itcss/components/send.scss | 14 ++++++++------ ui/app/send-v2.js | 13 ++++++++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index 9a076551e..c4efeccf0 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -652,7 +652,8 @@ } &__next-btn, - &__cancel-btn { + &__cancel-btn, + &__next-btn__disabled { width: 163px; text-align: center; height: 55px; @@ -667,16 +668,17 @@ border: 1px solid; } + &__next-btn, &__next-btn__disabled { - opacity: .5; - cursor: auto; - } - - &__next-btn { color: $curious-blue; border-color: $curious-blue; } + &__next-btn__disabled { + opacity: .5; + cursor: auto; + } + &__cancel-btn { color: $dusty-gray; border-color: $dusty-gray; diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index a9473541c..4986edf5f 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -382,7 +382,14 @@ SendTransactionScreen.prototype.renderForm = function () { } SendTransactionScreen.prototype.renderFooter = function () { - const { goHome, clearSend } = this.props + const { + goHome, + clearSend, + errors: { amount: amountError, to: toError } + } = this.props + + const noErrors = amountError === null && toError === null + const errorClass = noErrors ? '' : '__disabled' return h('div.send-v2__footer', [ h('button.send-v2__cancel-btn', { @@ -391,8 +398,8 @@ SendTransactionScreen.prototype.renderFooter = function () { goHome() }, }, 'Cancel'), - h('button.send-v2__next-btn', { - onClick: event => this.onSubmit(event), + h(`button.send-v2__next-btn${errorClass}`, { + onClick: event => noErrors && this.onSubmit(event), }, 'Next'), ]) } From e737a9565a6b78639b74511d026339c1b54bca1a Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 22 Oct 2017 17:44:03 -0230 Subject: [PATCH 05/17] Improve customize gas modal error handling --- .../components/customize-gas-modal/index.js | 144 +++++++++++++++--- .../pending-tx/confirm-send-ether.js | 2 +- ui/app/components/send/send-constants.js | 20 ++- ui/app/components/send/send-utils.js | 39 +++++ ui/app/components/send/send-v2-container.js | 8 +- ui/app/css/itcss/components/send.scss | 20 ++- ui/app/selectors.js | 23 +++ ui/app/send-v2.js | 33 ++-- 8 files changed, 230 insertions(+), 59 deletions(-) create mode 100644 ui/app/components/send/send-utils.js 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' From e058efd6a890598164baa9b337f710fc66ca22c5 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 23 Oct 2017 22:02:30 -0230 Subject: [PATCH 06/17] Use classnames library and disabled attribute on 'Next' button in send-v2 --- ui/app/send-v2.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index 16e4d7801..0086faa1f 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -2,6 +2,7 @@ const { inherits } = require('util') const PersistentForm = require('../lib/persistent-form') const h = require('react-hyperscript') const connect = require('react-redux').connect +const classnames = require('classnames') const Identicon = require('./components/identicon') const FromDropdown = require('./components/send/from-dropdown') @@ -380,7 +381,6 @@ SendTransactionScreen.prototype.renderFooter = function () { } = this.props const noErrors = amountError === null && toError === null - const errorClass = noErrors ? '' : '__disabled' return h('div.send-v2__footer', [ h('button.send-v2__cancel-btn', { @@ -389,8 +389,13 @@ SendTransactionScreen.prototype.renderFooter = function () { goHome() }, }, 'Cancel'), - h(`button.send-v2__next-btn${errorClass}`, { - onClick: event => noErrors && this.onSubmit(event), + h(`button`, { + className: classnames({ + 'send-v2__next-btn': noErrors, + 'send-v2__next-btn__disabled': !noErrors, + }), + disabled: !noErrors, + onClick: event => this.onSubmit(event), }, 'Next'), ]) } From 8895a225dc3e69a5baab66ad93bd54b7d5e6c82c Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 23 Oct 2017 22:59:45 -0700 Subject: [PATCH 07/17] Remove Current Provider info from Settings --- ui/app/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/settings.js b/ui/app/settings.js index 2ac70d82d..b6fae7707 100644 --- a/ui/app/settings.js +++ b/ui/app/settings.js @@ -208,7 +208,7 @@ class Settings extends Component { h('div.settings__content', [ warning && h('div.settings__error', warning), this.renderCurrentConversion(), - this.renderCurrentProvider(), + // this.renderCurrentProvider(), this.renderNewRpcUrl(), this.renderStateLogs(), this.renderSeedWords(), From 6d3f261b2f923782279be5e2ce05e8d6cc558a9e Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Mon, 23 Oct 2017 23:11:47 -0700 Subject: [PATCH 08/17] Change LOOSE label to IMPORTED --- ui/app/components/account-menu/index.js | 2 +- ui/app/css/itcss/components/account-menu.scss | 2 ++ ui/app/css/itcss/tools/utilities.scss | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index 85bd21076..32e7bc466 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -148,6 +148,6 @@ AccountMenu.prototype.indicateIfLoose = function (keyring) { try { // Sometimes keyrings aren't loaded yet: const type = keyring.type const isLoose = type !== 'HD Key Tree' - return isLoose ? h('.keyring-label', 'LOOSE') : null + return isLoose ? h('.keyring-label', 'IMPORTED') : null } catch (e) { return } } diff --git a/ui/app/css/itcss/components/account-menu.scss b/ui/app/css/itcss/components/account-menu.scss index 090710f7b..72cb29ce8 100644 --- a/ui/app/css/itcss/components/account-menu.scss +++ b/ui/app/css/itcss/components/account-menu.scss @@ -65,6 +65,8 @@ .keyring-label { margin-top: 5px; + background-color: $black; + color: $dusty-gray; } } diff --git a/ui/app/css/itcss/tools/utilities.scss b/ui/app/css/itcss/tools/utilities.scss index ca9fd0d9c..ee867640d 100644 --- a/ui/app/css/itcss/tools/utilities.scss +++ b/ui/app/css/itcss/tools/utilities.scss @@ -237,7 +237,6 @@ hr.horizontal-line { color: #fff; border-radius: 10px; padding: 4px; - width: 41px; text-align: center; height: 15px; } From a63373401b9983b991d4b2a0e28eec8d66c18e78 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Mon, 23 Oct 2017 23:59:21 -0700 Subject: [PATCH 09/17] New Sidebar uplift --- ui/app/components/account-menu/index.js | 1 - ui/app/components/wallet-view.js | 92 ++++++++----------- .../css/itcss/components/newui-sections.scss | 66 +++++++++++-- 3 files changed, 93 insertions(+), 66 deletions(-) diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index 32e7bc466..45e39e8ba 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -103,7 +103,6 @@ AccountMenu.prototype.renderAccounts = function () { showAccountDetail, } = this.props - console.log({ accounts }) return Object.keys(identities).map((key, index) => { const identity = identities[key] const isSelected = identity.address === selected diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js index a870a24e3..06123fd0e 100644 --- a/ui/app/components/wallet-view.js +++ b/ui/app/components/wallet-view.js @@ -3,7 +3,8 @@ const connect = require('react-redux').connect const h = require('react-hyperscript') const inherits = require('util').inherits const Identicon = require('./identicon') -const AccountDropdowns = require('./dropdowns/index.js').AccountDropdowns +// const AccountDropdowns = require('./dropdowns/index.js').AccountDropdowns +const copyToClipboard = require('copy-to-clipboard') const actions = require('../actions') const BalanceComponent = require('./balance-component') const TokenList = require('./token-list') @@ -19,6 +20,7 @@ function mapStateToProps (state) { identities: state.metamask.identities, accounts: state.metamask.accounts, tokens: state.metamask.tokens, + keyrings: state.metamask.keyrings, selectedAddress: selectors.getSelectedAddress(state), selectedIdentity: selectors.getSelectedIdentity(state), selectedAccount: selectors.getSelectedAccount(state), @@ -28,9 +30,12 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - showSendPage: () => { dispatch(actions.showSendPage()) }, - hideSidebar: () => { dispatch(actions.hideSidebar()) }, + showSendPage: () => dispatch(actions.showSendPage()), + hideSidebar: () => dispatch(actions.hideSidebar()), unsetSelectedToken: () => dispatch(actions.setSelectedToken()), + showAccountDetailModal: () => { + dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' })) + }, } } @@ -47,7 +52,7 @@ WalletView.prototype.renderWalletBalance = function () { hideSidebar, sidebarOpen, } = this.props - console.log({ selectedAccount }) + const selectedClass = selectedTokenAddress ? '' : 'wallet-balance-wrapper--active' @@ -73,13 +78,24 @@ WalletView.prototype.renderWalletBalance = function () { WalletView.prototype.render = function () { const { - network, responsiveDisplayClassname, identities, - selectedAddress, accounts, + responsiveDisplayClassname, + selectedAddress, selectedIdentity, + keyrings, + showAccountDetailModal, + hideSidebar, } = this.props // temporary logs + fake extra wallets // console.log('walletview, selectedAccount:', selectedAccount) + const keyring = keyrings.find((kr) => { + return kr.accounts.includes(selectedAddress) || + kr.accounts.includes(selectedIdentity.address) + }) + + const type = keyring.type + const isLoose = type !== 'HD Key Tree' + return h('div.wallet-view.flex-column' + (responsiveDisplayClassname || ''), { style: {}, }, [ @@ -88,57 +104,15 @@ WalletView.prototype.render = function () { h('div.flex-column.wallet-view-account-details', { style: {}, }, [ + h('div.wallet-view__sidebar-close', { + onClick: hideSidebar, + }), - h('div.flex-row.account-options-menu', { - style: { - position: 'relative', - }, - }, [ - - h(AccountDropdowns, { - selected: selectedAddress, - network, - identities, - useCssTransition: true, - enableAccountOptions: true, - dropdownWrapperStyle: { - padding: '1px 15px', - marginLeft: '-25px', - position: 'absolute', - width: '122%', // TODO, refactor all of this component out into media queries - }, - menuItemStyles: { - padding: '0px 0px', - margin: '22px 0px', - }, - }, []), - - ]), + h('div.wallet-view__keyring-label', isLoose ? 'IMPORTED' : ''), h('div.flex-column.flex-center', { + style: { margin: '0 auto' }, }, [ - h('div', { - style: { - position: 'relative', - }, - }, [ - h(AccountDropdowns, { - accounts, - style: { - position: 'absolute', - left: 'calc(50% + 28px + 5.5px)', - top: '14px', - }, - innerStyle: { - padding: '10px 16px', - }, - useCssTransition: true, - selected: selectedAddress, - network, - identities, - }, []), - ]), - h(Identicon, { diameter: 54, address: selectedAddress, @@ -149,14 +123,20 @@ WalletView.prototype.render = function () { }, [ selectedIdentity.name, ]), - ]), ]), + h('button.wallet-view__details-button', { onClick: showAccountDetailModal }, 'DETAILS'), + + h('div.wallet-view__address', { onClick: () => copyToClipboard(selectedAddress) }, [ + `${selectedAddress.slice(0, 4)}...${selectedAddress.slice(-4)}`, + h('i.fa.fa-clipboard', { style: { marginLeft: '8px' } }), + ]), + // 'Wallet' - Title // Not visible on mobile - h('div.flex-column.wallet-view-title-wrapper', {}, [ - h('span.wallet-view-title', {}, [ + h('div.flex-column.wallet-view-title-wrapper', [ + h('span.wallet-view-title', [ 'Wallet', ]), ]), diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index 5e0acb1ec..396dacae6 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -46,6 +46,7 @@ $wallet-view-bg: $wild-sand; flex: 33.5 0 33.5%; background: $wallet-view-bg; z-index: 200; + position: relative; @media screen and (min-width: 576px) { overflow-y: scroll; @@ -55,6 +56,57 @@ $wallet-view-bg: $wild-sand; .wallet-view-account-details { flex: 0 0 150px; } + + &__keyring-label { + height: 40px; + color: $dusty-gray; + font-family: Roboto; + font-size: 10px; + line-height: 40px; + text-align: right; + padding: 0 20px; + } + + &__details-button { + color: $curious-blue; + font-size: 10px; + line-height: 13px; + text-align: center; + border: 1px solid $curious-blue; + border-radius: 10.5px; + background-color: transparent; + margin: 0 auto; + padding: 4px 12px; + flex: 0 0 auto; + } + + &__address { + border-radius: 3px; + background-color: $alto; + color: $scorpion; + font-size: 14px; + line-height: 12px; + padding: 4px 12px; + margin: 24px auto; + font-weight: 300; + cursor: pointer; + flex: 0 0 auto; + } + + &__sidebar-close { + + @media screen and (max-width: 575px) { + &::after { + content: '\00D7'; + font-size: 40px; + color: $tundora; + position: absolute; + top: 15px; + left: 15px; + cursor: pointer; + } + } + } } @media screen and (min-width: 576px) { @@ -174,15 +226,11 @@ $wallet-view-bg: $wild-sand; // wallet view .account-name { - - @media screen and (max-width: 575px) { - font-size: 102%; - margin-left: 3%; - } - - @media screen and (max-width: 575px) { - text-align: center; - } + font-size: 24px; + font-weight: 200; + line-height: 20px; + color: $scorpion; + margin-top: 8px; } // account options dropdown From 4401800a42eccbd77f11b332e1052431328401bb Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 00:13:49 -0700 Subject: [PATCH 10/17] Account menu white check mark --- app/images/check-white.svg | 14 ++++++++++++++ ui/app/components/account-menu/index.js | 6 +++--- ui/app/components/tx-view.js | 7 ++++--- ui/app/css/itcss/components/account-menu.scss | 11 +++++++++++ ui/app/css/itcss/components/newui-sections.scss | 4 ++-- 5 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 app/images/check-white.svg diff --git a/app/images/check-white.svg b/app/images/check-white.svg new file mode 100644 index 000000000..0f15667da --- /dev/null +++ b/app/images/check-white.svg @@ -0,0 +1,14 @@ + + + + check-white + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index 45e39e8ba..da2c86233 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -98,14 +98,14 @@ AccountMenu.prototype.renderAccounts = function () { const { identities, accounts, - selected, + selectedAddress, keyrings, showAccountDetail, } = this.props return Object.keys(identities).map((key, index) => { const identity = identities[key] - const isSelected = identity.address === selected + const isSelected = identity.address === selectedAddress const balanceValue = accounts[key] ? accounts[key].balance : '' const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...' @@ -121,7 +121,7 @@ AccountMenu.prototype.renderAccounts = function () { { onClick: () => showAccountDetail(identity.address) }, [ h('div.account-menu__check-mark', [ - isSelected ? h('i.fa.fa-check') : null, + isSelected ? h('div.account-menu__check-mark-icon') : null, ]), h( diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js index d903998c0..ebef22680 100644 --- a/ui/app/components/tx-view.js +++ b/ui/app/components/tx-view.js @@ -109,14 +109,15 @@ TxView.prototype.render = function () { margin: '1em 0.9em', alignItems: 'center', }, - onClick: () => { - this.props.sidebarOpen ? this.props.hideSidebar() : this.props.showSidebar() - }, }, [ h('div.fa.fa-bars', { style: { fontSize: '1.3em', + cursor: 'pointer', + }, + onClick: () => { + this.props.sidebarOpen ? this.props.hideSidebar() : this.props.showSidebar() }, }, []), diff --git a/ui/app/css/itcss/components/account-menu.scss b/ui/app/css/itcss/components/account-menu.scss index 72cb29ce8..91884e658 100644 --- a/ui/app/css/itcss/components/account-menu.scss +++ b/ui/app/css/itcss/components/account-menu.scss @@ -90,9 +90,20 @@ &__check-mark { width: 14px; + margin-right: 12px; flex: 0 0 auto; } + &__check-mark-icon { + background-image: url("images/check-white.svg"); + height: 18px; + width: 18px; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + margin: 3px 0; + } + .identicon { margin: 0 12px 0 0; flex: 0 0 auto; diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index 396dacae6..f86decab3 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -101,8 +101,8 @@ $wallet-view-bg: $wild-sand; font-size: 40px; color: $tundora; position: absolute; - top: 15px; - left: 15px; + top: 12px; + left: 12px; cursor: pointer; } } From 3891cf1af6130126781b12aaee410c0831fa43e9 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 00:16:19 -0700 Subject: [PATCH 11/17] Fix clickable area on logout --- ui/app/components/account-menu/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/app/components/account-menu/index.js b/ui/app/components/account-menu/index.js index da2c86233..e0f38ae78 100644 --- a/ui/app/components/account-menu/index.js +++ b/ui/app/components/account-menu/index.js @@ -63,10 +63,11 @@ AccountMenu.prototype.render = function () { h(CloseArea, { onClick: toggleAccountMenu }), h(Item, { className: 'account-menu__header', - onClick: lockMetamask, }, [ 'My Accounts', - h('button.account-menu__logout-button', 'Log out'), + h('button.account-menu__logout-button', { + onClick: lockMetamask, + }, 'Log out'), ]), h(Divider), h('div.account-menu__accounts', this.renderAccounts()), From 2871beebe61418ce148069c932301d89e85923fa Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 00:29:20 -0700 Subject: [PATCH 12/17] Add "Add Token" button to side bar --- ui/app/components/wallet-view.js | 5 +++++ ui/app/css/itcss/components/newui-sections.scss | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js index 06123fd0e..580ac54aa 100644 --- a/ui/app/components/wallet-view.js +++ b/ui/app/components/wallet-view.js @@ -36,6 +36,7 @@ function mapDispatchToProps (dispatch) { showAccountDetailModal: () => { dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' })) }, + showAddTokenPage: () => dispatch(actions.showAddTokenPage()), } } @@ -84,6 +85,7 @@ WalletView.prototype.render = function () { keyrings, showAccountDetailModal, hideSidebar, + showAddTokenPage, } = this.props // temporary logs + fake extra wallets // console.log('walletview, selectedAccount:', selectedAccount) @@ -145,6 +147,9 @@ WalletView.prototype.render = function () { h(TokenList), + h('button.wallet-view__add-token-button', { + onClick: showAddTokenPage, + }, 'Add Token'), ]) } diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index f86decab3..a78279084 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -107,6 +107,19 @@ $wallet-view-bg: $wild-sand; } } } + + &__add-token-button { + color: $dusty-gray; + font-size: 14px; + line-height: 19px; + text-align: center; + margin: 36px auto 0; + border: 1px solid $dusty-gray; + border-radius: 2px; + font-weight: 300; + background: none; + padding: 9px 30px; + } } @media screen and (min-width: 576px) { From ba9cefb24e61e570407154c37b6cc30b22829667 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 00:38:39 -0700 Subject: [PATCH 13/17] Add caret to Add Token toggle --- ui/app/add-token.js | 5 ++++- ui/app/css/itcss/components/add-token.scss | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ui/app/add-token.js b/ui/app/add-token.js index e313babf3..148a8c622 100644 --- a/ui/app/add-token.js +++ b/ui/app/add-token.js @@ -350,7 +350,10 @@ AddTokenScreen.prototype.render = function () { h('div.add-token__footers', [ h('div.add-token__add-custom', { onClick: () => this.setState({ isCollapsed: !isCollapsed }), - }, 'Add custom token'), + }, [ + 'Add custom token', + h(`i.fa.fa-angle-${isCollapsed ? 'down' : 'up'}`), + ]), this.renderCustomForm(), ]), ]), diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss index aa8221c9a..9bdda6a9b 100644 --- a/ui/app/css/itcss/components/add-token.scss +++ b/ui/app/css/itcss/components/add-token.scss @@ -109,7 +109,18 @@ cursor: pointer; &:hover { - background-color: $gallery; + background-color: rgba(0, 0, 0, .05); + } + + &:active { + background-color: rgba(0, 0, 0, .1); + } + + .fa { + position: absolute; + right: 24px; + font-size: 24px; + line-height: 24px; } } From 4336794355e819f798343e0de3cea6933c8121ee Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 00:43:12 -0700 Subject: [PATCH 14/17] Fix styling in private key modal --- ui/app/components/modals/export-private-key-modal.js | 1 - ui/app/css/itcss/components/modal.scss | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/components/modals/export-private-key-modal.js b/ui/app/components/modals/export-private-key-modal.js index 302596eda..80d7779ef 100644 --- a/ui/app/components/modals/export-private-key-modal.js +++ b/ui/app/components/modals/export-private-key-modal.js @@ -66,7 +66,6 @@ ExportPrivateKeyModal.prototype.renderPasswordInput = function (privateKey) { }) : h('input.private-key-password-input', { type: 'password', - placeholder: 'Type password', onChange: event => this.setState({ password: event.target.value }), }) } diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss index 1ffea58a9..139e5a8f2 100644 --- a/ui/app/css/itcss/components/modal.scss +++ b/ui/app/css/itcss/components/modal.scss @@ -372,6 +372,7 @@ resize: none; padding: 9px 13px 8px; text-transform: uppercase; + font-weight: 300; } From 966e4cfd1189f7c115cfc552796c1353060d2125 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 00:54:49 -0700 Subject: [PATCH 15/17] Change clickable area for account detail; change network dot size --- ui/app/components/wallet-view.js | 6 ++++-- ui/app/css/itcss/components/network.scss | 6 +++--- ui/app/css/itcss/components/newui-sections.scss | 8 +++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js index 580ac54aa..215103396 100644 --- a/ui/app/components/wallet-view.js +++ b/ui/app/components/wallet-view.js @@ -112,8 +112,9 @@ WalletView.prototype.render = function () { h('div.wallet-view__keyring-label', isLoose ? 'IMPORTED' : ''), - h('div.flex-column.flex-center', { + h('div.flex-column.flex-center.wallet-view__name-container', { style: { margin: '0 auto' }, + onClick: showAccountDetailModal, }, [ h(Identicon, { diameter: 54, @@ -125,10 +126,11 @@ WalletView.prototype.render = function () { }, [ selectedIdentity.name, ]), + + h('button.wallet-view__details-button', 'DETAILS'), ]), ]), - h('button.wallet-view__details-button', { onClick: showAccountDetailModal }, 'DETAILS'), h('div.wallet-view__address', { onClick: () => copyToClipboard(selectedAddress) }, [ `${selectedAddress.slice(0, 4)}...${selectedAddress.slice(-4)}`, diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss index bb8c4eea8..77a6a393d 100644 --- a/ui/app/css/itcss/components/network.scss +++ b/ui/app/css/itcss/components/network.scss @@ -40,7 +40,7 @@ .dropdown-menu-item { .menu-icon-circle, .menu-icon-circle--active { - margin: 0 16px; + margin: 0 14px; } } @@ -116,8 +116,8 @@ .menu-icon-circle div, .menu-icon-circle--active div { - height: 17px; - width: 17px; + height: 12px; + width: 12px; border-radius: 17px; } diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index a78279084..c65ceb2db 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -54,7 +54,12 @@ $wallet-view-bg: $wild-sand; } .wallet-view-account-details { - flex: 0 0 150px; + flex: 0 0 auto; + } + + &__name-container { + flex: 0 0 auto; + cursor: pointer; } &__keyring-label { @@ -244,6 +249,7 @@ $wallet-view-bg: $wild-sand; line-height: 20px; color: $scorpion; margin-top: 8px; + margin-bottom: 24px; } // account options dropdown From 6daa8343234cf2a0bc32ed434ee3acae6100fd38 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 01:07:51 -0700 Subject: [PATCH 16/17] Disable network dropdown on conf tx screen --- ui/app/app.js | 25 ++++++++++++++++-------- ui/app/components/network.js | 7 ++++++- ui/app/css/itcss/components/network.scss | 9 +++++++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ui/app/app.js b/ui/app/app.js index 35ff8603a..0cfbb5af5 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -203,6 +203,16 @@ App.prototype.renderSidebar = function () { } App.prototype.renderAppBar = function () { + const { + isUnlocked, + network, + provider, + networkDropdownOpen, + showNetworkDropdown, + hideNetworkDropdown, + currentView, + } = this.props + if (window.METAMASK_UI_TYPE === 'notification') { return null } @@ -243,22 +253,21 @@ App.prototype.renderAppBar = function () { }, [ // Network Indicator h(NetworkIndicator, { - network: this.props.network, - provider: this.props.provider, + network, + provider, + disabled: currentView.name === 'confTx', onClick: (event) => { event.preventDefault() event.stopPropagation() - if (this.props.networkDropdownOpen === false) { - this.props.showNetworkDropdown() - } else { - this.props.hideNetworkDropdown() - } + return networkDropdownOpen === false + ? showNetworkDropdown() + : hideNetworkDropdown() }, }), ]), - h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [ + isUnlocked && h('div.account-menu__icon', { onClick: this.props.toggleAccountMenu }, [ h(Identicon, { address: this.props.selectedAddress, diameter: 32, diff --git a/ui/app/components/network.js b/ui/app/components/network.js index b24505750..229d02e36 100644 --- a/ui/app/components/network.js +++ b/ui/app/components/network.js @@ -64,13 +64,18 @@ Network.prototype.render = function () { return ( h('div.network-component.pointer', { className: classnames('network-component pointer', { + 'network-component--disabled': this.props.disabled, 'ethereum-network': providerName === 'mainnet', 'ropsten-test-network': providerName === 'ropsten' || parseInt(networkNumber) === 3, 'kovan-test-network': providerName === 'kovan', 'rinkeby-test-network': providerName === 'rinkeby', }), title: hoverText, - onClick: (event) => this.props.onClick(event), + onClick: (event) => { + if (!this.props.disabled) { + this.props.onClick(event) + } + }, }, [ (function () { switch (iconName) { diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss index 77a6a393d..0bc66ea1a 100644 --- a/ui/app/css/itcss/components/network.scss +++ b/ui/app/css/itcss/components/network.scss @@ -1,3 +1,12 @@ +.network-component--disabled { + border-color: transparent !important; + cursor: default; + + .fa-caret-down { + opacity: 0; + } +} + .network-component.pointer { border: 1px solid $shark; border-radius: 82px; From de3a48ec66f044d4116f8dbd25c358ab30d073a9 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Tue, 24 Oct 2017 01:19:00 -0700 Subject: [PATCH 17/17] Fix mobile add token button --- ui/app/css/itcss/components/confirm.scss | 6 ++++-- ui/app/css/itcss/components/newui-sections.scss | 3 ++- ui/app/css/itcss/components/send.scss | 3 +-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss index d4f0fe5ac..c498afba2 100644 --- a/ui/app/css/itcss/components/confirm.scss +++ b/ui/app/css/itcss/components/confirm.scss @@ -37,7 +37,7 @@ overflow-y: auto; top: 0; box-shadow: none; - height: calc(100vh - 58px - 100px); + height: calc(100vh - 58px - 85px); border-top-left-radius: 0; border-top-right-radius: 0; } @@ -271,6 +271,7 @@ section .confirm-screen-account-number, box-shadow: none; flex: 1 0 auto; font-weight: 300; + margin: 0 8px; } .btn-light.confirm-screen-cancel-button { @@ -288,6 +289,7 @@ section .confirm-screen-account-number, cursor: pointer; flex: 1 0 auto; font-weight: 300; + margin: 0 8px; } #pending-tx-form { @@ -296,7 +298,7 @@ section .confirm-screen-account-number, display: flex; flex-flow: row nowrap; background-color: $white; - padding: 19px 18px; + padding: 12px 18px; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; width: 100%; diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index c65ceb2db..d975c56b7 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -114,11 +114,12 @@ $wallet-view-bg: $wild-sand; } &__add-token-button { + flex: 0 0 auto; color: $dusty-gray; font-size: 14px; line-height: 19px; text-align: center; - margin: 36px auto 0; + margin: 36px auto; border: 1px solid $dusty-gray; border-radius: 2px; font-weight: 300; diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index d2415f26c..bac5f4d05 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -657,15 +657,14 @@ width: 163px; text-align: center; height: 55px; - width: 163px; border-radius: 2px; background-color: $white; font-family: Roboto; font-size: 16px; font-weight: 300; line-height: 21px; - text-align: center; border: 1px solid; + margin: 0 4px; } &__next-btn,