diff options
author | Daniel Tsui <szehungdanieltsui@gmail.com> | 2017-10-24 19:32:19 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-24 19:32:19 +0800 |
commit | 09445ef692f5a63b1a4bd418962dca2892e4cda9 (patch) | |
tree | 155484d2dfade59955f888f729b631581527475e /ui | |
parent | 0a436dcf9a1283a8452966fea2508801de589ab7 (diff) | |
parent | de3a48ec66f044d4116f8dbd25c358ab30d073a9 (diff) | |
download | tangerine-wallet-browser-09445ef692f5a63b1a4bd418962dca2892e4cda9.tar tangerine-wallet-browser-09445ef692f5a63b1a4bd418962dca2892e4cda9.tar.gz tangerine-wallet-browser-09445ef692f5a63b1a4bd418962dca2892e4cda9.tar.bz2 tangerine-wallet-browser-09445ef692f5a63b1a4bd418962dca2892e4cda9.tar.lz tangerine-wallet-browser-09445ef692f5a63b1a4bd418962dca2892e4cda9.tar.xz tangerine-wallet-browser-09445ef692f5a63b1a4bd418962dca2892e4cda9.tar.zst tangerine-wallet-browser-09445ef692f5a63b1a4bd418962dca2892e4cda9.zip |
Merge branch 'NewUI-flat' into NewUI-flat-disable-send-next-in-error
Diffstat (limited to 'ui')
27 files changed, 469 insertions, 180 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/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/account-menu/index.js b/ui/app/components/account-menu/index.js index 85bd21076..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()), @@ -98,15 +99,14 @@ AccountMenu.prototype.renderAccounts = function () { const { identities, accounts, - selected, + selectedAddress, keyrings, showAccountDetail, } = this.props - console.log({ accounts }) 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) : '...' @@ -122,7 +122,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( @@ -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/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/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/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/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/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/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/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/components/wallet-view.js b/ui/app/components/wallet-view.js index a870a24e3..215103396 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,13 @@ 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' })) + }, + showAddTokenPage: () => dispatch(actions.showAddTokenPage()), } } @@ -47,7 +53,7 @@ WalletView.prototype.renderWalletBalance = function () { hideSidebar, sidebarOpen, } = this.props - console.log({ selectedAccount }) + const selectedClass = selectedTokenAddress ? '' : 'wallet-balance-wrapper--active' @@ -73,13 +79,25 @@ WalletView.prototype.renderWalletBalance = function () { WalletView.prototype.render = function () { const { - network, responsiveDisplayClassname, identities, - selectedAddress, accounts, + responsiveDisplayClassname, + selectedAddress, selectedIdentity, + keyrings, + showAccountDetailModal, + hideSidebar, + showAddTokenPage, } = 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 +106,16 @@ 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('div.wallet-view__keyring-label', isLoose ? 'IMPORTED' : ''), - 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.flex-column.flex-center', { + h('div.flex-column.flex-center.wallet-view__name-container', { + style: { margin: '0 auto' }, + onClick: showAccountDetailModal, }, [ - 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, @@ -150,13 +127,20 @@ WalletView.prototype.render = function () { selectedIdentity.name, ]), + h('button.wallet-view__details-button', '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', ]), ]), @@ -165,6 +149,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/account-menu.scss b/ui/app/css/itcss/components/account-menu.scss index 090710f7b..91884e658 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; } } @@ -88,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/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; } } 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/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 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; } diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss index bb8c4eea8..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; @@ -40,7 +49,7 @@ .dropdown-menu-item { .menu-icon-circle, .menu-icon-circle--active { - margin: 0 16px; + margin: 0 14px; } } @@ -116,8 +125,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 1ee8283ef..d975c56b7 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -45,6 +45,8 @@ $wallet-view-bg: $wild-sand; flex-direction: column; flex: 33.5 0 33.5%; background: $wallet-view-bg; + z-index: 200; + position: relative; @media screen and (min-width: 576px) { overflow-y: scroll; @@ -52,7 +54,77 @@ $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 { + 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: 12px; + left: 12px; + cursor: pointer; + } + } + } + + &__add-token-button { + flex: 0 0 auto; + color: $dusty-gray; + font-size: 14px; + line-height: 19px; + text-align: center; + margin: 36px auto; + border: 1px solid $dusty-gray; + border-radius: 2px; + font-weight: 300; + background: none; + padding: 9px 30px; } } @@ -173,15 +245,12 @@ $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; + margin-bottom: 24px; } // account options dropdown diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index c4efeccf0..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, @@ -738,6 +737,7 @@ align-items: center; justify-content: space-between; font-size: 22px; + position: relative; } &__buttons { @@ -747,7 +747,7 @@ margin-right: 21.25px; } - &__revert, &__cancel, &__save { + &__revert, &__cancel, &__save, &__save__error { display: flex; justify-content: center; align-items: center; @@ -760,7 +760,7 @@ margin-left: 21.25px; } - &__cancel, &__save { + &__cancel, &__save, &__save__error { height: 34.64px; width: 85.74px; border: 1px solid $dusty-gray; @@ -769,6 +769,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/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 { 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/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; } 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..7fa8ca18a 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') @@ -19,6 +20,9 @@ const { conversionGreaterThan, addCurrencies, } = require('./conversion-util') +const { + isBalanceSufficient, +} = require('./components/send/send-utils.js') const { isValidAddress } = require('./util') module.exports = SendTransactionScreen @@ -237,28 +241,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' }, @@ -399,7 +391,6 @@ SendTransactionScreen.prototype.renderFooter = function () { }, }, 'Cancel'), h(`button.send-v2__next-btn${errorClass}`, { - onClick: event => noErrors && this.onSubmit(event), }, 'Next'), ]) } 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(), |