From 0ca5d1dc8a940b5fc7b91fcb84b4d5f40af682cc Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 13 May 2020 17:41:15 -0300 Subject: [PATCH] Refactor asset list items (#8586) All asset list items now use the same component (`AssetListItem`). Previously the tokens and the Ethereum balance were totally separate components, despite being styled similarly. Various unnecessary DOM elements and style rules were removed, but the overall list looks identical to how it looked before. --- test/e2e/address-book.spec.js | 2 +- test/e2e/metamask-ui.spec.js | 4 +- test/e2e/threebox.spec.js | 4 +- .../app/asset-list-item/asset-list-item.js | 67 ++++++++++++ .../app/asset-list-item/asset-list-item.scss | 20 ++++ .../components/app/asset-list-item/index.js | 1 + .../app/asset-list/asset-list.component.js | 43 +++++--- .../app/asset-list/asset-list.container.js | 3 + .../components/app/asset-list/asset-list.scss | 68 ++---------- ui/app/components/app/index.scss | 2 + .../app/token-cell/token-cell.component.js | 102 +++++++++--------- .../components/app/token-cell/token-cell.scss | 39 +------ .../ui/balance/balance.component.js | 48 --------- .../ui/balance/balance.container.js | 22 ---- ui/app/components/ui/balance/index.js | 1 - 15 files changed, 186 insertions(+), 240 deletions(-) create mode 100644 ui/app/components/app/asset-list-item/asset-list-item.js create mode 100644 ui/app/components/app/asset-list-item/asset-list-item.scss create mode 100644 ui/app/components/app/asset-list-item/index.js delete mode 100644 ui/app/components/ui/balance/balance.component.js delete mode 100644 ui/app/components/ui/balance/balance.container.js delete mode 100644 ui/app/components/ui/balance/index.js diff --git a/test/e2e/address-book.spec.js b/test/e2e/address-book.spec.js index e283fb61d..5ccd563d9 100644 --- a/test/e2e/address-book.spec.js +++ b/test/e2e/address-book.spec.js @@ -151,7 +151,7 @@ describe('MetaMask', function () { }) it('balance renders', async function () { - const balance = await driver.findElement(By.css('.balance-display .token-amount')) + const balance = await driver.findElement(By.css('[data-testid="wallet-balance"] .asset-list__primary-amount')) await driver.wait(until.elementTextMatches(balance, /25\s*ETH/)) await driver.delay(regularDelayMs) }) diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index 1fe503d7d..964453818 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -206,7 +206,7 @@ describe('MetaMask', function () { }) it('balance renders', async function () { - const balance = await driver.findElement(By.css('.balance-display .token-amount')) + const balance = await driver.findElement(By.css('[data-testid="wallet-balance"] .asset-list__primary-amount')) await driver.wait(until.elementTextMatches(balance, /100\s*ETH/)) await driver.delay(regularDelayMs) }) @@ -991,7 +991,7 @@ describe('MetaMask', function () { const txStatuses = await driver.findElements(By.css('.transaction-list-item__action')) await driver.wait(until.elementTextMatches(txStatuses[0], /Sent\sToken/), 10000) - await driver.clickElement(By.css('.wallet-balance')) + await driver.clickElement(By.css('[data-testid="wallet-balance"]')) await driver.clickElement(By.css('.token-cell')) await driver.delay(1000) diff --git a/test/e2e/threebox.spec.js b/test/e2e/threebox.spec.js index 57624735f..10bb0fcfb 100644 --- a/test/e2e/threebox.spec.js +++ b/test/e2e/threebox.spec.js @@ -96,7 +96,7 @@ describe('MetaMask', function () { }) it('balance renders', async function () { - const balance = await driver.findElement(By.css('.balance-display .token-amount')) + const balance = await driver.findElement(By.css('[data-testid="wallet-balance"] .asset-list__primary-amount')) await driver.wait(until.elementTextMatches(balance, /25\s*ETH/)) await driver.delay(regularDelayMs) }) @@ -202,7 +202,7 @@ describe('MetaMask', function () { }) it('balance renders', async function () { - const balance = await driver2.findElement(By.css('.balance-display .token-amount')) + const balance = await driver2.findElement(By.css('[data-testid="wallet-balance"] .asset-list__primary-amount')) await driver2.wait(until.elementTextMatches(balance, /25\s*ETH/)) await driver2.delay(regularDelayMs) }) diff --git a/ui/app/components/app/asset-list-item/asset-list-item.js b/ui/app/components/app/asset-list-item/asset-list-item.js new file mode 100644 index 000000000..bada9aaa9 --- /dev/null +++ b/ui/app/components/app/asset-list-item/asset-list-item.js @@ -0,0 +1,67 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import Identicon from '../../ui/identicon' + +const AssetListItem = ({ + active, + children, + className, + 'data-testid': dataTestId, + iconClassName, + menu, + onClick, + tokenAddress, + tokenImage, + warning, +}) => { + return ( +
+ +
+ { children } +
+ { warning } + { menu } +
+ ) +} + +AssetListItem.propTypes = { + active: PropTypes.bool, + children: PropTypes.node.isRequired, + className: PropTypes.string, + 'data-testid': PropTypes.string, + iconClassName: PropTypes.string, + menu: PropTypes.node, + onClick: PropTypes.func.isRequired, + tokenAddress: PropTypes.string, + tokenImage: PropTypes.string, + warning: PropTypes.node, +} + +AssetListItem.defaultProps = { + active: undefined, + className: undefined, + 'data-testid': undefined, + menu: undefined, + iconClassName: undefined, + tokenAddress: undefined, + tokenImage: undefined, + warning: undefined, +} + +export default AssetListItem diff --git a/ui/app/components/app/asset-list-item/asset-list-item.scss b/ui/app/components/app/asset-list-item/asset-list-item.scss new file mode 100644 index 000000000..847b0adba --- /dev/null +++ b/ui/app/components/app/asset-list-item/asset-list-item.scss @@ -0,0 +1,20 @@ +.asset-list-item { + &__container { + display: flex; + padding: 20px 25px; + align-items: center; + + &--active { + background: $manatee; + color: $white; + } + } + + &__balance { + display: flex; + flex-direction: column; + margin-left: 15px; + flex: 1; + min-width: 0; + } +} diff --git a/ui/app/components/app/asset-list-item/index.js b/ui/app/components/app/asset-list-item/index.js new file mode 100644 index 000000000..48b7de3d2 --- /dev/null +++ b/ui/app/components/app/asset-list-item/index.js @@ -0,0 +1 @@ +export { default } from './asset-list-item' diff --git a/ui/app/components/app/asset-list/asset-list.component.js b/ui/app/components/app/asset-list/asset-list.component.js index 7cfcb57db..35dc8429d 100644 --- a/ui/app/components/app/asset-list/asset-list.component.js +++ b/ui/app/components/app/asset-list/asset-list.component.js @@ -1,10 +1,11 @@ -import classnames from 'classnames' import PropTypes from 'prop-types' import React, { Component } from 'react' -import BalanceComponent from '../../ui/balance' import AddTokenButton from '../add-token-button' import TokenList from '../token-list' import { ADD_TOKEN_ROUTE } from '../../../helpers/constants/routes' +import AssetListItem from '../asset-list-item' +import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display' +import { PRIMARY, SECONDARY } from '../../../helpers/constants/common' export default class AssetList extends Component { static contextTypes = { @@ -18,32 +19,44 @@ export default class AssetList extends Component { static propTypes = { history: PropTypes.object.isRequired, + selectedAccountBalance: PropTypes.string, selectedTokenAddress: PropTypes.string, setSelectedToken: PropTypes.func.isRequired, + showFiat: PropTypes.bool.isRequired, unsetSelectedToken: PropTypes.func.isRequired, } renderWalletBalance () { const { + selectedAccountBalance, selectedTokenAddress, + showFiat, unsetSelectedToken, } = this.props return ( -
-
{ - unsetSelectedToken() - }} - > - -
-
+ + { + showFiat && ( + + ) + } + ) } diff --git a/ui/app/components/app/asset-list/asset-list.container.js b/ui/app/components/app/asset-list/asset-list.container.js index 493d7b096..65ea1ce73 100644 --- a/ui/app/components/app/asset-list/asset-list.container.js +++ b/ui/app/components/app/asset-list/asset-list.container.js @@ -3,10 +3,13 @@ import { withRouter } from 'react-router-dom' import { compose } from 'redux' import AssetList from './asset-list.component' import { setSelectedToken } from '../../../store/actions' +import { getCurrentAccountWithSendEtherInfo, getShouldShowFiat } from '../../../selectors/selectors' function mapStateToProps (state) { return { + selectedAccountBalance: getCurrentAccountWithSendEtherInfo(state).balance, selectedTokenAddress: state.metamask.selectedTokenAddress, + showFiat: getShouldShowFiat(state), } } diff --git a/ui/app/components/app/asset-list/asset-list.scss b/ui/app/components/app/asset-list/asset-list.scss index 679a76099..82ca6798d 100644 --- a/ui/app/components/app/asset-list/asset-list.scss +++ b/ui/app/components/app/asset-list/asset-list.scss @@ -1,64 +1,10 @@ -$wallet-balance-bg: #e7e7e7; -$wallet-balance-breakpoint: 890px; -$wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (max-width: #{$wallet-balance-breakpoint})"; +.asset-list { + &__primary-amount { + font-size: 1.5rem; + } -.wallet-balance-wrapper { - flex: 0 0 auto; - transition: linear 200ms; - background: rgba($wallet-balance-bg, 0); - - &--active { - background: $manatee; - color: $white; - } -} - -.wallet-balance { - background: inherit; - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - flex: 0 0 auto; - cursor: pointer; - border-top: 1px solid $wallet-balance-bg; - - .balance-container { - display: flex; - justify-content: flex-start; - align-items: center; - margin: 20px 24px; - flex-direction: row; - min-width: 0; - - @media #{$wallet-balance-breakpoint-range} { - margin: 10% 4%; - } - } - - .balance-display { - margin-left: 15px; - min-width: 0; - - .token-amount { - font-size: 1.5rem; - } - - .fiat-amount { - margin-top: .25%; - font-size: 105%; - } - - @media #{$wallet-balance-breakpoint-range} { - margin-left: 4%; - - .token-amount { - font-size: 105%; - } - - .fiat-amount { - font-size: 95%; - } - } + &__secondary-amount { + margin-top: .25%; + font-size: 105%; } } diff --git a/ui/app/components/app/index.scss b/ui/app/components/app/index.scss index 7ba12eb0f..347108b2e 100644 --- a/ui/app/components/app/index.scss +++ b/ui/app/components/app/index.scss @@ -10,6 +10,8 @@ @import 'asset-list/asset-list'; +@import 'asset-list-item/asset-list-item'; + @import '../ui/breadcrumbs/index'; @import '../ui/button-group/index'; diff --git a/ui/app/components/app/token-cell/token-cell.component.js b/ui/app/components/app/token-cell/token-cell.component.js index a64c4952e..380913e3b 100644 --- a/ui/app/components/app/token-cell/token-cell.component.js +++ b/ui/app/components/app/token-cell/token-cell.component.js @@ -1,11 +1,11 @@ import classnames from 'classnames' import PropTypes from 'prop-types' import React, { Component } from 'react' -import Identicon from '../../ui/identicon' import { conversionUtil, multiplyCurrencies } from '../../../helpers/utils/conversion-util' import TokenMenuDropdown from '../dropdowns/token-menu-dropdown.js' import Tooltip from '../../ui/tooltip-v2' import { I18nContext } from '../../../contexts/i18n' +import AssetListItem from '../asset-list-item' export default class TokenCell extends Component { static contextType = I18nContext @@ -71,55 +71,8 @@ export default class TokenCell extends Component { const showFiat = Boolean(currentTokenInFiat) && currentCurrency.toUpperCase() !== symbol - return ( -
- -
-
-
{string || 0}
-
{symbol}
- {showFiat && ( -
- {formattedFiat} -
- )} -
-
- { - outdatedBalance && ( - - { t('troubleTokenBalances') } - - { t('here') } - -
- )} - > - - - ) - } - + const menu = ( + <>
)} -
+ + ) + + const warning = outdatedBalance + ? ( + + { t('troubleTokenBalances') } + + { t('here') } + + + )} + > + + + ) + : null + + return ( + +
+
{string || 0}
+
{symbol}
+ {showFiat && ( +
+ {formattedFiat} +
+ )} +
+
) } } diff --git a/ui/app/components/app/token-cell/token-cell.scss b/ui/app/components/app/token-cell/token-cell.scss index 4b50158fb..6ba02a08a 100644 --- a/ui/app/components/app/token-cell/token-cell.scss +++ b/ui/app/components/app/token-cell/token-cell.scss @@ -2,16 +2,8 @@ $wallet-balance-breakpoint: 890px; $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and (max-width: #{$wallet-balance-breakpoint})"; .token-cell { - display: flex; - flex-flow: row nowrap; - align-items: center; - padding: 20px 24px; cursor: pointer; - transition: linear 200ms; - background-color: rgba($wallet-balance-bg, 0); position: relative; - flex: 1; - min-width: 0; &__token-balance { margin-right: 4px; @@ -42,37 +34,10 @@ $wallet-balance-breakpoint-range: "screen and (min-width: #{$break-large}) and ( } } - @media #{$wallet-balance-breakpoint-range} { - padding: 10% 4%; - } - - &--active { - background-color: $manatee; - color: $white; - } - - &__identicon { - margin-right: 15px; - border: '1px solid #dedede'; - min-width: 50px; - - @media #{$wallet-balance-breakpoint-range} { - margin-right: 4%; - } - } - - &--outdated > &__identicon { + &--outdated &__icon { opacity: 0.5 } - - &__balance-ellipsis { - display: flex; - align-items: center; - min-width: 0; - flex: 1; - } - - &--outdated > &__balance-ellipsis { + &--outdated &__balance-wrapper { opacity: 0.5 } diff --git a/ui/app/components/ui/balance/balance.component.js b/ui/app/components/ui/balance/balance.component.js deleted file mode 100644 index 91e9184d3..000000000 --- a/ui/app/components/ui/balance/balance.component.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, { PureComponent } from 'react' -import PropTypes from 'prop-types' -import Identicon from '../identicon' -import UserPreferencedCurrencyDisplay from '../../app/user-preferenced-currency-display' -import { PRIMARY, SECONDARY } from '../../../helpers/constants/common' - -export default class Balance extends PureComponent { - static propTypes = { - account: PropTypes.object, - showFiat: PropTypes.bool, - } - - renderBalance () { - const { account, showFiat } = this.props - const balanceValue = account && account.balance - - return ( -
- - { - showFiat && ( - - ) - } -
- ) - } - - render () { - return ( -
- - { this.renderBalance() } -
- ) - } -} diff --git a/ui/app/components/ui/balance/balance.container.js b/ui/app/components/ui/balance/balance.container.js deleted file mode 100644 index 888c65721..000000000 --- a/ui/app/components/ui/balance/balance.container.js +++ /dev/null @@ -1,22 +0,0 @@ -import { connect } from 'react-redux' -import Balance from './balance.component' -import { - getMetaMaskAccounts, - getIsMainnet, - preferencesSelector, -} from '../../../selectors' - -const mapStateToProps = (state) => { - const { showFiatInTestnets } = preferencesSelector(state) - const isMainnet = getIsMainnet(state) - const accounts = getMetaMaskAccounts(state) - const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0] - const account = accounts[selectedAddress] - - return { - account, - showFiat: (isMainnet || !!showFiatInTestnets), - } -} - -export default connect(mapStateToProps)(Balance) diff --git a/ui/app/components/ui/balance/index.js b/ui/app/components/ui/balance/index.js deleted file mode 100644 index f8fb9ea19..000000000 --- a/ui/app/components/ui/balance/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './balance.container'