diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 6870be1cc..8a00369f4 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1620,9 +1620,6 @@ "message": "You need $1 more $2 to complete this swap", "description": "Tells the user how many more of a given token they need for a specific swap. $1 is an amount of tokens and $2 is the token symbol." }, - "swapBetterQuoteAvailable": { - "message": "A better quote is available" - }, "swapBuildQuotePlaceHolderText": { "message": "No tokens available matching $1", "description": "Tells the user that a given search string does not match any tokens in our token lists. $1 can be any string of text" @@ -1729,8 +1726,8 @@ "message": "We find the best price from the top liquidity sources, every time. A fee of $1% is automatically factored into each quote, which supports ongoing development to make MetaMask even better.", "description": "Provides information about the fee that metamask takes for swaps. $1 is a decimal number." }, - "swapNQuotes": { - "message": "$1 quotes", + "swapNQuotesAvailable": { + "message": "$1 quotes available", "description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen" }, "swapNetworkFeeSummary": { @@ -1791,10 +1788,6 @@ "swapRequestForQuotation": { "message": "Request for quotation" }, - "swapSaving": { - "message": "Saving $1 $2", - "description": "Tells the user their average savings for the selected best quote. $1 is replaced by a tilde sign, to shown approximation. $2 is replaced by the approximate amount of money the user will save, in fiat" - }, "swapSearchForAToken": { "message": "Search for a token" }, @@ -1848,9 +1841,6 @@ "swapUnknown": { "message": "Unknown" }, - "swapUsingBestQuote": { - "message": "Using the best quote" - }, "swapVerifyTokenExplanation": { "message": "Multiple tokens can use the same name and symbol. Check Etherscan to verify this is the token you're looking for." }, @@ -1870,6 +1860,13 @@ "swapsAlmostDone": { "message": "Almost done..." }, + "swapsBestQuote": { + "message": "Best quote" + }, + "swapsConvertToAbout": { + "message": "Convert $1 to about", + "description": "This message is part of a quote for a swap. The $1 is the amount being converted, and the amount it is being swapped for is below this message" + }, "swapsMaxSlippage": { "message": "Max slippage" }, diff --git a/app/images/down-arrow-grey.svg b/app/images/down-arrow-grey.svg deleted file mode 100644 index fcdb33eec..000000000 --- a/app/images/down-arrow-grey.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/ui/app/components/ui/url-icon/index.scss b/ui/app/components/ui/url-icon/index.scss index 14d5524cb..482f327d3 100644 --- a/ui/app/components/ui/url-icon/index.scss +++ b/ui/app/components/ui/url-icon/index.scss @@ -20,9 +20,9 @@ border-radius: 50%; background: #bbc0c5; flex: 0 1 auto; - display: flex; justify-content: center; align-items: center; + text-align: center; padding-top: 2px; } } diff --git a/ui/app/components/ui/url-icon/url-icon.js b/ui/app/components/ui/url-icon/url-icon.js index 115eb5fe1..6dcfcc06f 100644 --- a/ui/app/components/ui/url-icon/url-icon.js +++ b/ui/app/components/ui/url-icon/url-icon.js @@ -3,13 +3,13 @@ import PropTypes from 'prop-types' import classnames from 'classnames' import IconWithFallback from '../icon-with-fallback' -export default function UrlIcon({ url, className, name, fallbackClassName }) { +export default function UrlIcon({ url, className, name }) { return ( ) } @@ -18,5 +18,4 @@ UrlIcon.propTypes = { url: PropTypes.string, className: PropTypes.string, name: PropTypes.string, - fallbackClassName: PropTypes.string, } diff --git a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js index e70ffd8e7..fbb268d65 100644 --- a/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js +++ b/ui/app/pages/swaps/exchange-rate-display/exchange-rate-display.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types' import BigNumber from 'bignumber.js' import classnames from 'classnames' import { calcTokenAmount } from '../../../helpers/utils/token-util' -import { formatSwapsValueForDisplay } from '../swaps.util' +import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util' export default function ExchangeRateDisplay({ primaryTokenValue, @@ -13,7 +13,6 @@ export default function ExchangeRateDisplay({ secondaryTokenDecimals = 18, secondaryTokenSymbol, arrowColor = 'black', - boldSymbols = true, className, }) { const [showPrimaryToSecondary, setShowPrimaryToSecondary] = useState(true) @@ -58,24 +57,16 @@ export default function ExchangeRateDisplay({ } else if (new BigNumber(rate, 10).lt('0.000001', 10)) { rateToDisplay = rate } else { - rateToDisplay = formatSwapsValueForDisplay(rate) + rateToDisplay = toPrecisionWithoutTrailingZeros(rate, 9) } return (
1 - - {baseSymbol} - + {baseSymbol} {comparisonSymbol} {rateToDisplay} - - {ratiodSymbol} - + {ratiodSymbol}
- ~ - , - savingAmount, - ]) - } else if (inDevelopment && isBestQuote && tokenConversionRate) { - savingsText = t('swapUsingBestQuote') - } else if (inDevelopment && savingsIsPositive && tokenConversionRate) { - savingsText = t('swapBetterQuoteAvailable') - } - return (
-
-
-
-
- {shouldDisplaySavings && ( -
- -
- )} -
- {savingsText && ( -

{savingsText}

- )} -
-

- {t('swapNQuotes', [numberOfQuotes])} -

-
- -
-
-
-
@@ -165,39 +83,26 @@ export default function FeeCard({
{!hideTokenApprovalRow && ( -
+
{t('swapThisWillAllowApprove', [tokenApprovalTextComponent])}
+
onTokenApprovalClick()} + > + {t('swapEditLimit')} +
-
onTokenApprovalClick()} - > - {t('swapEditLimit')} -
)} -
-
-
- {t('swapQuoteIncludesRate', [metaMaskFee])} -
- -
-
) @@ -217,12 +122,4 @@ FeeCard.propTypes = { tokenApprovalTextComponent: PropTypes.node, tokenApprovalSourceTokenSymbol: PropTypes.string, onTokenApprovalClick: PropTypes.func, - metaMaskFee: PropTypes.string.isRequired, - savings: PropTypes.object, - isBestQuote: PropTypes.bool, - onQuotesClick: PropTypes.func.isRequired, - numberOfQuotes: PropTypes.number.isRequired, - conversionRate: PropTypes.number, - currentCurrency: PropTypes.string, - tokenConversionRate: PropTypes.number, } diff --git a/ui/app/pages/swaps/fee-card/fee-card.stories.js b/ui/app/pages/swaps/fee-card/fee-card.stories.js index 43adbc48f..6b316caab 100644 --- a/ui/app/pages/swaps/fee-card/fee-card.stories.js +++ b/ui/app/pages/swaps/fee-card/fee-card.stories.js @@ -1,6 +1,6 @@ import React from 'react' import { action } from '@storybook/addon-actions' -import { text, boolean, number, object } from '@storybook/addon-knobs/react' +import { text } from '@storybook/addon-knobs/react' import FeeCard from './fee-card' const tokenApprovalTextComponent = ( @@ -35,13 +35,6 @@ export const WithAllProps = () => { tokenApprovalSourceTokenSymbol="ABC" onTokenApprovalClick={action('Clicked third row link')} hideTokenApprovalRow={false} - metaMaskFee="0.875" - savings={object('savings 1', { total: '8.55' })} - onQuotesClick={action('Clicked quotes link')} - numberOfQuotes={number('numberOfQuotes', 6)} - isBestQuote={boolean('isBestQuote', true)} - conversionRate={300} - currentCurrency="usd" />
) @@ -62,11 +55,6 @@ export const WithoutThirdRow = () => { }} onFeeCardMaxRowClick={action('Clicked max fee row link')} hideTokenApprovalRow - onQuotesClick={action('Clicked quotes link')} - numberOfQuotes={number('numberOfQuotes', 1)} - isBestQuote={boolean('isBestQuote', true)} - savings={object('savings 1', { total: '8.55' })} - metaMaskFee="0.875" />
) @@ -82,9 +70,6 @@ export const WithOnlyRequiredProps = () => { }} onFeeCardMaxRowClick={action('Clicked max fee row link')} hideTokenApprovalRow - metaMaskFee="0.875" - onQuotesClick={action('Clicked quotes link')} - numberOfQuotes={2} />
) diff --git a/ui/app/pages/swaps/fee-card/index.scss b/ui/app/pages/swaps/fee-card/index.scss index ce42ca676..0a86f6ab7 100644 --- a/ui/app/pages/swaps/fee-card/index.scss +++ b/ui/app/pages/swaps/fee-card/index.scss @@ -1,103 +1,11 @@ .fee-card { + border-radius: 8px; + border: 1px solid $Grey-100; + width: 100%; + @include H7; - &__savings-and-quotes-header { - display: flex; - position: relative; - align-items: center; - } - - &__savings-and-quotes-header-first-part, - &__savings-and-quotes-header-second-part, - &__savings-and-quotes-header-third-part { - height: 39px; - background: $Blue-000; - border: 1px solid $Blue-500; - } - - &__savings-and-quotes-header-first-part { - width: 22px; - border-top-left-radius: 8px; - border-bottom: none; - border-right: none; - } - - &__savings-and-quotes-header-second-part { - width: 18px; - border: none; - - &--top-border { - border-top: 1px solid $Blue-500; - } - } - - &__savings-and-quotes-header-third-part { - width: 271px; - border-top-right-radius: 8px; - border-bottom: none; - border-left: none; - } - - &__pig-icon-container { - position: absolute; - left: 14.5px; - bottom: 4px; - } - - &__savings-and-quotes-row { - display: flex; - justify-content: space-between; - align-items: center; - max-width: 234px; - width: 100%; - position: absolute; - left: 58px; - - &--align-left { - left: 16px; - max-width: 272px; - } - } - - &__savings-text { - @include H6; - - font-weight: bold; - color: $Blue-500; - } - - &__quote-link-container { - display: flex; - align-items: center; - cursor: pointer; - } - - &__quote-link-text { - @include H7; - - color: $Blue-500; - } - - &__caret-right { - color: $Blue-500; - width: 6px; - height: 6px; - display: flex; - justify-content: center; - align-items: center; - margin-left: 6px; - - i { - transform: rotate(90deg); - } - } - &__main { - border: 1px solid $Blue-500; - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; - width: 100%; - max-width: 311px; padding: 16px 16px 12px 16px; } @@ -123,10 +31,6 @@ cursor: pointer; } - &__row-header-text--bold { - color: $Black-100; - } - &__row, &__top-bordered-row { display: flex; @@ -147,6 +51,7 @@ img { height: 10px; width: 10px; + margin-left: 4px; cursor: pointer; } } @@ -155,12 +60,7 @@ height: 10px; width: 10px; justify-content: center; - - div { - // Needed to override the style property added by the react-tippy library - display: flex !important; - height: 10px; - } + margin-top: 2px; } &__info-tooltip-paragraph { @@ -211,12 +111,9 @@ margin-right: 12px; } - &__row-header-primary { - color: $Grey-500; - } - + &__row-header-primary, &__row-header-primary--bold { - color: $Black-100; + color: $Grey-500; } &__row-header-text--bold, @@ -228,11 +125,6 @@ &__bold { font-weight: bold; } - - &__tilde { - font-family: Roboto, Helvetica, Arial, sans-serif; - margin-right: -3.5px; - } } .info-tooltip { diff --git a/ui/app/pages/swaps/fee-card/pig-icon.js b/ui/app/pages/swaps/fee-card/pig-icon.js deleted file mode 100644 index ef7677ae4..000000000 --- a/ui/app/pages/swaps/fee-card/pig-icon.js +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react' - -export default function PigIcon() { - return ( - - - - - - - - - - ) -} diff --git a/ui/app/pages/swaps/main-quote-summary/index.scss b/ui/app/pages/swaps/main-quote-summary/index.scss index dfdc882f1..7993ea724 100644 --- a/ui/app/pages/swaps/main-quote-summary/index.scss +++ b/ui/app/pages/swaps/main-quote-summary/index.scss @@ -1,75 +1,28 @@ .main-quote-summary { display: flex; flex-flow: column; - justify-content: center; align-items: center; position: relative; - max-height: 196px; - min-height: 196px; + height: 196px; width: 100%; - color: $Black-100; + color: $white; - &__source-row, - &__destination-row { - width: 100%; - display: flex; - align-items: flex-start; - justify-content: center; - - @include H6; - - color: $Grey-500; + &__quote-backdrop-with-top-tab, + &__quote-backdrop { + position: absolute; + box-shadow: 0 10px 39px rgba(3, 125, 214, 0.15); + border-radius: 8px; + background: #fafcff; } - &__source-row { - align-items: center; + &__quote-backdrop-with-top-tab { + width: 348px; + height: 215px; } - &__source-row-value, - &__source-row-symbol { - // Each of these spans can be half their container width minus the space - // needed for the token icon and the span margins - max-width: calc(50% - 13px); - } - - - &__source-row-value { - margin-right: 5px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - &__source-row-symbol { - margin-left: 5px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - &__destination-row { - margin-top: 6px; - } - - &__destination-row-symbol { - margin-left: 5px; - color: $Black-100; - } - - &__icon, - &__icon-fallback { - height: 16px; - width: 16px; - } - - &__icon-fallback { - padding-top: 0; - font-size: 12px; - line-height: 16px; - } - - &__down-arrow { - margin-top: 5px; + &__quote-backdrop { + width: 310px; + height: 164px; } &__details { @@ -80,24 +33,62 @@ position: relative; } + &__best-quote { + @include H7; + + font-weight: bold; + position: relative; + display: flex; + padding-top: 6px; + letter-spacing: 0.12px; + min-height: 16px; + + > span { + margin-left: 4px; + } + } + &__quote-details-top { + height: 94px; display: flex; flex-flow: column; justify-content: center; align-items: center; width: 100%; + padding: 12px; + padding-top: 2px; + margin-top: 4px; + } + + &__bold { + font-weight: 900; + } + + &__quote-small-white { + white-space: nowrap; + width: 100%; + text-align: center; + font-size: 14px; + margin-bottom: 8px; + margin-top: 6px; } &__quote-large { display: flex; - align-items: flex-start; - margin-top: 8px; - height: 50px; + align-items: flex-end; } &__quote-large-number { - font-size: 60px; - line-height: 48px; + font-size: 40px; + line-height: 32px; + margin-right: 6px; + } + + &__quote-large-symbol { + display: flex; + align-items: flex-end; + font-size: 32px; + line-height: 32px; } &__quote-large-white { @@ -113,10 +104,7 @@ justify-content: center; align-items: center; width: 287px; - margin-top: 14px; - } - - &__exchange-rate-display { - color: $Grey-500; + border-top: 1px solid rgba(255, 255, 255, 0.2); + height: 42px; } } diff --git a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js index b335cc656..1ae2e7d51 100644 --- a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js +++ b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.js @@ -1,33 +1,62 @@ -import React from 'react' +import React, { useContext } from 'react' import PropTypes from 'prop-types' import BigNumber from 'bignumber.js' +import classnames from 'classnames' +import { I18nContext } from '../../../contexts/i18n' import { calcTokenAmount } from '../../../helpers/utils/token-util' import { toPrecisionWithoutTrailingZeros } from '../../../helpers/utils/util' import Tooltip from '../../../components/ui/tooltip' -import UrlIcon from '../../../components/ui/url-icon' +import SunCheckIcon from '../../../components/ui/icon/sun-check-icon.component' import ExchangeRateDisplay from '../exchange-rate-display' import { formatSwapsValueForDisplay } from '../swaps.util' +import QuoteBackdrop from './quote-backdrop' -function getFontSizesAndLineHeights(fontSizeScore) { - if (fontSizeScore <= 9) { - return [60, 48] - } - if (fontSizeScore <= 13) { +function getFontSizes(fontSizeScore) { + if (fontSizeScore <= 11) { return [40, 32] } - return [26, 15] + if (fontSizeScore <= 16) { + return [30, 24] + } + return [24, 14] +} + +function getLineHeight(fontSizeScore) { + if (fontSizeScore <= 11) { + return 32 + } + if (fontSizeScore <= 16) { + return 26 + } + return 18 +} + +// Returns a numerical value based on the length of the two passed strings: amount and symbol. +// The returned value equals the number of digits in the amount string plus a value calculated +// from the length of the symbol string. The returned number will be passed to the getFontSizes function +// to determine the font size to apply to the amount and symbol strings when rendered. The +// desired maximum digits and letters to show in the ultimately rendered string is 20, and in +// such cases there can also be ellipsis shown and a decimal, combinding for a rendered "string" +// length of ~22. As the symbol will always have a smaller font size than the amount, the +// additive value of the symbol length to the font size score is corrected based on the total +// number of alphanumeric characters in both strings and the desired rendered length of 22. +function getFontSizeScore(amount, symbol) { + const amountLength = amount.match(/\d+/gu).join('').length + const symbolModifier = Math.min((amountLength + symbol.length) / 22, 1) + return amountLength + symbol.length * symbolModifier } export default function MainQuoteSummary({ + isBestQuote, sourceValue, sourceSymbol, sourceDecimals, - sourceIconUrl, destinationValue, destinationSymbol, destinationDecimals, - destinationIconUrl, }) { + const t = useContext(I18nContext) + const sourceAmount = toPrecisionWithoutTrailingZeros( calcTokenAmount(sourceValue, sourceDecimals).toString(10), 12, @@ -38,55 +67,43 @@ export default function MainQuoteSummary({ ) const amountToDisplay = formatSwapsValueForDisplay(destinationAmount) - const amountDigitLength = amountToDisplay.match(/\d+/gu).join('').length - const [numberFontSize, lineHeight] = getFontSizesAndLineHeights( - amountDigitLength, - ) + const fontSizeScore = getFontSizeScore(amountToDisplay, destinationSymbol) + const [numberFontSize, symbolFontSize] = getFontSizes(fontSizeScore) + const lineHeight = getLineHeight(fontSizeScore) + let ellipsedAmountToDisplay = amountToDisplay - if (amountDigitLength > 20) { - ellipsedAmountToDisplay = `${amountToDisplay.slice(0, 20)}...` + if (fontSizeScore > 20) { + ellipsedAmountToDisplay = `${amountToDisplay.slice( + 0, + amountToDisplay.length - (fontSizeScore - 20), + )}...` } return (
+
+ +
+
+ {isBestQuote && } + {isBestQuote && t('swapsBestQuote')} +
-
- - {formatSwapsValueForDisplay(sourceAmount)} - - - - {sourceSymbol} - -
- -
- - - {destinationSymbol} - -
+ + {t('swapsConvertToAbout', [ + + {`${sourceAmount} ${sourceSymbol}`} + , + ])} +
+ + {`${destinationSymbol}`} +
@@ -115,9 +141,8 @@ export default function MainQuoteSummary({ secondaryTokenValue={destinationValue} secondaryTokenDecimals={destinationDecimals} secondaryTokenSymbol={destinationSymbol} - arrowColor="#037DD6" - boldSymbols={false} - className="main-quote-summary__exchange-rate-display" + className="exchange-rate-display--white" + arrowColor="white" />
@@ -126,6 +151,7 @@ export default function MainQuoteSummary({ } MainQuoteSummary.propTypes = { + isBestQuote: PropTypes.bool, sourceValue: PropTypes.oneOfType([ PropTypes.string, PropTypes.instanceOf(BigNumber), @@ -141,6 +167,4 @@ MainQuoteSummary.propTypes = { PropTypes.number, ]), destinationSymbol: PropTypes.string.isRequired, - sourceIconUrl: PropTypes.string, - destinationIconUrl: PropTypes.string, } diff --git a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js index 709549d7b..f6c1ffeb2 100644 --- a/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js +++ b/ui/app/pages/swaps/main-quote-summary/main-quote-summary.stories.js @@ -1,5 +1,5 @@ import React from 'react' -import { text, number } from '@storybook/addon-knobs/react' +import { text, number, boolean } from '@storybook/addon-knobs/react' import MainQuoteSummary from './main-quote-summary' export default { @@ -8,24 +8,28 @@ export default { export const BestQuote = () => { return ( -
- -
+ + ) +} + +export const NotBestQuote = () => { + return ( + ) } diff --git a/ui/app/pages/swaps/swaps-footer/swaps-footer.js b/ui/app/pages/swaps/swaps-footer/swaps-footer.js index c5a90ba34..c158c21fb 100644 --- a/ui/app/pages/swaps/swaps-footer/swaps-footer.js +++ b/ui/app/pages/swaps/swaps-footer/swaps-footer.js @@ -13,7 +13,6 @@ export default function SwapsFooter({ disabled, showTermsOfService, showTopBorder, - className, }) { const t = useContext(I18nContext) @@ -31,10 +30,7 @@ export default function SwapsFooter({ onSubmit={onSubmit} submitText={submitText} submitButtonType="confirm" - footerClassName={classnames( - 'swaps-footer__custom-page-container-footer-class', - className, - )} + footerClassName="swaps-footer__custom-page-container-footer-class" footerButtonClassName={classnames( 'swaps-footer__custom-page-container-footer-button-class', { @@ -66,5 +62,4 @@ SwapsFooter.propTypes = { disabled: PropTypes.bool, showTermsOfService: PropTypes.bool, showTopBorder: PropTypes.bool, - className: PropTypes.string, } diff --git a/ui/app/pages/swaps/swaps.util.js b/ui/app/pages/swaps/swaps.util.js index 189ff877b..d3189e5b7 100644 --- a/ui/app/pages/swaps/swaps.util.js +++ b/ui/app/pages/swaps/swaps.util.js @@ -507,7 +507,6 @@ export function quotesToRenderableData( destinationTokenDecimals: destinationTokenInfo.decimals, destinationTokenSymbol: destinationTokenInfo.symbol, destinationTokenValue: formatSwapsValueForDisplay(destinationValue), - destinationIconUrl: destinationTokenInfo.iconUrl, isBestQuote: quote.isBestQuote, liquiditySourceKey, feeInEth, @@ -519,7 +518,6 @@ export function quotesToRenderableData( sourceTokenDecimals: sourceTokenInfo.decimals, sourceTokenSymbol: sourceTokenInfo.symbol, sourceTokenValue: sourceValue, - sourceTokenIconUrl: sourceTokenInfo.iconUrl, ethValueOfTrade, minimumAmountReceived, metaMaskFee: fee, diff --git a/ui/app/pages/swaps/view-quote/index.scss b/ui/app/pages/swaps/view-quote/index.scss index 013f57557..1b76853fb 100644 --- a/ui/app/pages/swaps/view-quote/index.scss +++ b/ui/app/pages/swaps/view-quote/index.scss @@ -44,13 +44,13 @@ display: flex; align-items: center; justify-content: center; - min-height: 46px; } &__view-other-button, &__view-other-button-fade { display: flex; align-items: center; + margin-bottom: 16px; position: absolute; @include H7; @@ -87,12 +87,10 @@ } &__insufficient-eth-warning-wrapper { + margin-top: 8px; width: 100%; align-items: center; justify-content: center; - width: intrinsic; /* Safari/WebKit uses a non-standard name */ - width: max-content; - max-width: 340px; @media screen and (min-width: 576px) { min-height: 36px; @@ -105,30 +103,57 @@ } &__countdown-timer-container { - width: 152px; - min-height: 32px; - display: flex; - justify-content: center; - border-radius: 42px; - background: #f2f3f4; - margin-top: 16px; + @media screen and (max-width: 576px) { + margin-top: 12px; + margin-bottom: 16px; + + &--thin { + margin-top: 8px; + margin-bottom: 8px; + + > div { + margin-top: 0; + margin-bottom: 0; + } + } + } + + @media screen and (min-width: 576px) { + &--thin { + margin-top: 6px; + } + } } &__fee-card-container { - display: flex; - align-items: center; - min-height: 172px; width: 100%; - max-width: 311px; + margin-top: 8px; margin-bottom: 8px; @media screen and (min-width: 576px) { margin-bottom: 0; + + &--three-rows { + margin-bottom: -16px; + } + } + } + + &__main-quote-summary-container { + margin-top: 24px; + + @media screen and (max-width: 576px) { + margin-top: 0; + } + + &--thin { + margin-top: 8px; } } &__metamask-rate { display: flex; + margin-top: 8%; } &__metamask-rate-text { @@ -140,10 +165,4 @@ &__metamask-rate-info-icon { margin-left: 4px; } - - &__thin-swaps-footer { - @media screen and (min-width: 576px) { - height: 72px; - } - } } diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index c4375219b..8528a38b3 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -73,6 +73,7 @@ import { useTokenTracker } from '../../../hooks/useTokenTracker' import { QUOTES_EXPIRED_ERROR } from '../../../helpers/constants/swaps' import CountdownTimer from '../countdown-timer' import SwapsFooter from '../swaps-footer' +import InfoTooltip from '../../../components/ui/info-tooltip' export default function ViewQuote() { const history = useHistory() @@ -115,7 +116,6 @@ export default function ViewQuote() { const tradeValue = usedQuote?.trade?.value ?? '0x0' const { isBestQuote } = usedQuote - const fetchParamsSourceToken = fetchParams?.sourceToken const usedGasLimit = @@ -190,11 +190,9 @@ export default function ViewQuote() { destinationTokenDecimals, destinationTokenSymbol, destinationTokenValue, - destinationIconUrl, sourceTokenDecimals, sourceTokenSymbol, sourceTokenValue, - sourceTokenIconUrl, } = renderableDataForUsedQuote const { feeInFiat, feeInEth } = getRenderableNetworkFeesForQuote( @@ -484,7 +482,11 @@ export default function ViewQuote() { /> )}
-
+
- +
+ +
+
+
+ {t('swapNQuotesAvailable', [Object.values(quotes).length])} + +
+
{ + allAvailableQuotesOpened() + setSelectQuotePopoverShown(true) + }} + > + {t('swapNQuotesAvailable', [Object.values(quotes).length])} + +
+
+
+

+ {t('swapQuoteIncludesRate', [metaMaskFee])} +

+ +
{ - allAvailableQuotesOpened() - setSelectQuotePopoverShown(true) - }} - savings={usedQuote?.savings} - conversionRate={conversionRate} - currentCurrency={currentCurrency} - tokenConversionRate={ - destinationTokenSymbol === 'ETH' - ? 1 - : memoizedTokenConversionRates[destinationToken.address] - } />
@@ -559,7 +577,6 @@ export default function ViewQuote() { submitText={t('swap')} onCancel={async () => await dispatch(navigateBackToBuildQuote(history))} disabled={balanceError || gasPrice === null || gasPrice === undefined} - className={showWarning && 'view-quote__thin-swaps-footer'} showTermsOfService showTopBorder />