Commit 300dd708 authored by Moody Salem's avatar Moody Salem

show currency values and price impact in the confirmation modal (fixes...

show currency values and price impact in the confirmation modal (fixes https://github.com/Uniswap/v3-interface/issues/92)
parent f4e99486
import { CurrencyAmount, Percent } from '@uniswap/sdk-core'
import React, { useMemo } from 'react'
import useTheme from '../../hooks/useTheme'
import { TYPE } from '../../theme'
import { warningSeverity } from '../../utils/prices'
export function FiatValue({
fiatValue,
priceImpact,
}: {
fiatValue: CurrencyAmount | null | undefined
priceImpact?: Percent
}) {
const theme = useTheme()
const priceImpactColor = useMemo(() => {
if (!priceImpact) return undefined
if (priceImpact.lessThan('0')) return theme.green1
const severity = warningSeverity(priceImpact)
if (severity < 1) return theme.text4
if (severity < 3) return theme.yellow1
return theme.red1
}, [priceImpact, theme.green1, theme.red1, theme.text4, theme.yellow1])
return (
<TYPE.body fontSize={14} color={fiatValue ? theme.text2 : theme.text4}>
{fiatValue ? '~' : ''}${fiatValue ? Number(fiatValue?.toSignificant(6)).toLocaleString('en') : '-'}
{priceImpact ? (
<span style={{ color: priceImpactColor }}> ({priceImpact.multiply(-100).toSignificant(3)}%)</span>
) : null}
</TYPE.body>
)
}
import { Pair } from '@uniswap/v2-sdk' import { Pair } from '@uniswap/v2-sdk'
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import React, { useState, useCallback, useMemo } from 'react' import React, { useState, useCallback } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { darken } from 'polished' import { darken } from 'polished'
import { useCurrencyBalance } from '../../state/wallet/hooks' import { useCurrencyBalance } from '../../state/wallet/hooks'
import { warningSeverity } from '../../utils/prices'
import CurrencySearchModal from '../SearchModal/CurrencySearchModal' import CurrencySearchModal from '../SearchModal/CurrencySearchModal'
import CurrencyLogo from '../CurrencyLogo' import CurrencyLogo from '../CurrencyLogo'
import DoubleCurrencyLogo from '../DoubleLogo' import DoubleCurrencyLogo from '../DoubleLogo'
...@@ -18,6 +17,7 @@ import { useTranslation } from 'react-i18next' ...@@ -18,6 +17,7 @@ import { useTranslation } from 'react-i18next'
import useTheme from '../../hooks/useTheme' import useTheme from '../../hooks/useTheme'
import { Lock } from 'react-feather' import { Lock } from 'react-feather'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import { FiatValue } from './FiatValue'
const InputPanel = styled.div<{ hideInput?: boolean }>` const InputPanel = styled.div<{ hideInput?: boolean }>`
${({ theme }) => theme.flexColumnNoWrap} ${({ theme }) => theme.flexColumnNoWrap}
...@@ -196,15 +196,6 @@ export default function CurrencyInputPanel({ ...@@ -196,15 +196,6 @@ export default function CurrencyInputPanel({
setModalOpen(false) setModalOpen(false)
}, [setModalOpen]) }, [setModalOpen])
const priceImpactColor = useMemo(() => {
if (!priceImpact) return undefined
if (priceImpact.lessThan('0')) return theme.green1
const severity = warningSeverity(priceImpact)
if (severity < 1) return theme.text4
if (severity < 3) return theme.yellow1
return theme.red1
}, [priceImpact, theme.green1, theme.red1, theme.text4, theme.yellow1])
return ( return (
<InputPanel id={id} hideInput={hideInput} {...rest}> <InputPanel id={id} hideInput={hideInput} {...rest}>
{locked && ( {locked && (
...@@ -291,12 +282,7 @@ export default function CurrencyInputPanel({ ...@@ -291,12 +282,7 @@ export default function CurrencyInputPanel({
</RowFixed> </RowFixed>
)} )}
<TYPE.body fontSize={14} color={fiatValue ? theme.text2 : theme.text4}> <FiatValue fiatValue={fiatValue} priceImpact={priceImpact} />
{fiatValue ? '~' : ''}${fiatValue ? Number(fiatValue?.toSignificant(6)).toLocaleString('en') : '-'}
{priceImpact ? (
<span style={{ color: priceImpactColor }}> ({priceImpact.multiply(-100).toSignificant(3)}%)</span>
) : null}
</TYPE.body>
</RowBetween> </RowBetween>
</FiatRow> </FiatRow>
)} )}
......
...@@ -5,10 +5,12 @@ import React, { useContext, useState } from 'react' ...@@ -5,10 +5,12 @@ import React, { useContext, useState } from 'react'
import { ArrowDown, AlertTriangle } from 'react-feather' import { ArrowDown, AlertTriangle } from 'react-feather'
import { Text } from 'rebass' import { Text } from 'rebass'
import styled, { ThemeContext } from 'styled-components' import styled, { ThemeContext } from 'styled-components'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { ButtonPrimary } from '../Button' import { ButtonPrimary } from '../Button'
import { isAddress, shortenAddress } from '../../utils' import { computeFiatValuePriceImpact, isAddress, shortenAddress } from '../../utils'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
import { FiatValue } from '../CurrencyInputPanel/FiatValue'
import CurrencyLogo from '../CurrencyLogo' import CurrencyLogo from '../CurrencyLogo'
import { RowBetween, RowFixed } from '../Row' import { RowBetween, RowFixed } from '../Row'
import { TruncatedText, SwapShowAcceptChanges } from './styleds' import { TruncatedText, SwapShowAcceptChanges } from './styleds'
...@@ -57,17 +59,18 @@ export default function SwapModalHeader({ ...@@ -57,17 +59,18 @@ export default function SwapModalHeader({
const [showInverted, setShowInverted] = useState<boolean>(false) const [showInverted, setShowInverted] = useState<boolean>(false)
const fiatValueInput = useUSDCValue(maximumAmountIn)
const fiatValueOutput = useUSDCValue(minimumAmountOut)
return ( return (
<AutoColumn gap={'4px'} style={{ marginTop: '1rem' }}> <AutoColumn gap={'4px'} style={{ marginTop: '1rem' }}>
<DarkGreyCard padding="0.75rem 1rem"> <DarkGreyCard padding="0.75rem 1rem">
<AutoColumn gap={'8px'}> <AutoColumn gap={'8px'}>
<RowBetween> <RowBetween>
<TYPE.body color={theme.text3} fontWeight={500} fontSize={14}> <TYPE.body color={theme.text3} fontWeight={500} fontSize={14}>
{'From'} From
</TYPE.body>
<TYPE.body fontSize={14} color={theme.text3}>
{'$-'}
</TYPE.body> </TYPE.body>
<FiatValue fiatValue={fiatValueInput} />
</RowBetween> </RowBetween>
<RowBetween align="center"> <RowBetween align="center">
<RowFixed gap={'0px'}> <RowFixed gap={'0px'}>
...@@ -95,10 +98,13 @@ export default function SwapModalHeader({ ...@@ -95,10 +98,13 @@ export default function SwapModalHeader({
<AutoColumn gap={'8px'}> <AutoColumn gap={'8px'}>
<RowBetween> <RowBetween>
<TYPE.body color={theme.text3} fontWeight={500} fontSize={14}> <TYPE.body color={theme.text3} fontWeight={500} fontSize={14}>
{'To'} To
</TYPE.body> </TYPE.body>
<TYPE.body fontSize={14} color={theme.text3}> <TYPE.body fontSize={14} color={theme.text3}>
{'$-'} <FiatValue
fiatValue={fiatValueOutput}
priceImpact={computeFiatValuePriceImpact(fiatValueInput, fiatValueOutput)}
/>
</TYPE.body> </TYPE.body>
</RowBetween> </RowBetween>
<RowBetween align="flex-end"> <RowBetween align="flex-end">
......
import { CurrencyAmount, currencyEquals, Percent, Token } from '@uniswap/sdk-core' import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk' import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk' import { Trade as V3Trade } from '@uniswap/v3-sdk'
import { AdvancedSwapDetails } from 'components/swap/AdvancedSwapDetails' import { AdvancedSwapDetails } from 'components/swap/AdvancedSwapDetails'
...@@ -6,26 +6,27 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter ...@@ -6,26 +6,27 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter
import { MouseoverTooltip, MouseoverTooltipContent } from 'components/Tooltip' import { MouseoverTooltip, MouseoverTooltipContent } from 'components/Tooltip'
import JSBI from 'jsbi' import JSBI from 'jsbi'
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react' import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { ArrowDown, HelpCircle, CheckCircle, Info, X } from 'react-feather' import { ArrowDown, CheckCircle, HelpCircle, Info, X } from 'react-feather'
import ReactGA from 'react-ga' import ReactGA from 'react-ga'
import { RouteComponentProps } from 'react-router-dom' import { Link, RouteComponentProps } from 'react-router-dom'
import { Text } from 'rebass' import { Text } from 'rebass'
import { ThemeContext } from 'styled-components' import { ThemeContext } from 'styled-components'
import AddressInputPanel from '../../components/AddressInputPanel' import AddressInputPanel from '../../components/AddressInputPanel'
import { ButtonConfirmed, ButtonError, ButtonLight, ButtonPrimary, ButtonGray } from '../../components/Button' import { ButtonConfirmed, ButtonError, ButtonGray, ButtonLight, ButtonPrimary } from '../../components/Button'
import { GreyCard } from '../../components/Card' import { GreyCard } from '../../components/Card'
import { AutoColumn } from '../../components/Column' import { AutoColumn } from '../../components/Column'
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import CurrencyLogo from '../../components/CurrencyLogo' import CurrencyLogo from '../../components/CurrencyLogo'
import Loader from '../../components/Loader' import Loader from '../../components/Loader'
import { AutoRow, RowBetween, RowFixed } from '../../components/Row' import { AutoRow, RowBetween, RowFixed } from '../../components/Row'
import BetterTradeLink from '../../components/swap/BetterTradeLink'
import confirmPriceImpactWithoutFee from '../../components/swap/confirmPriceImpactWithoutFee' import confirmPriceImpactWithoutFee from '../../components/swap/confirmPriceImpactWithoutFee'
import ConfirmSwapModal from '../../components/swap/ConfirmSwapModal' import ConfirmSwapModal from '../../components/swap/ConfirmSwapModal'
import { ArrowWrapper, BottomGrouping, Dots, SwapCallbackError, Wrapper } from '../../components/swap/styleds' import { ArrowWrapper, BottomGrouping, Dots, SwapCallbackError, Wrapper } from '../../components/swap/styleds'
import SwapHeader from '../../components/swap/SwapHeader'
import TradePrice from '../../components/swap/TradePrice' import TradePrice from '../../components/swap/TradePrice'
import TokenWarningModal from '../../components/TokenWarningModal' import TokenWarningModal from '../../components/TokenWarningModal'
import { ONE_HUNDRED_PERCENT } from '../../constants'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import { useAllTokens, useCurrency } from '../../hooks/Tokens' import { useAllTokens, useCurrency } from '../../hooks/Tokens'
import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useApproveCallback' import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useApproveCallback'
...@@ -47,27 +48,13 @@ import { ...@@ -47,27 +48,13 @@ import {
} from '../../state/swap/hooks' } from '../../state/swap/hooks'
import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance } from '../../state/user/hooks' import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance } from '../../state/user/hooks'
import { LinkStyledButton, TYPE } from '../../theme' import { LinkStyledButton, TYPE } from '../../theme'
import { computeFiatValuePriceImpact } from '../../utils'
import { getTradeVersion } from '../../utils/getTradeVersion' import { getTradeVersion } from '../../utils/getTradeVersion'
import { isTradeBetter } from '../../utils/isTradeBetter'
import { maxAmountSpend } from '../../utils/maxAmountSpend' import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { warningSeverity } from '../../utils/prices' import { warningSeverity } from '../../utils/prices'
import AppBody from '../AppBody' import AppBody from '../AppBody'
import { Link } from 'react-router-dom'
import { isTradeBetter } from '../../utils/isTradeBetter'
import BetterTradeLink from '../../components/swap/BetterTradeLink'
import SwapHeader from '../../components/swap/SwapHeader'
function computeFiatValuePriceImpact(
fiatValueInput: CurrencyAmount | undefined | null,
fiatValueOutput: CurrencyAmount | undefined | null
): Percent | undefined {
if (!fiatValueOutput || !fiatValueInput) return undefined
if (!currencyEquals(fiatValueInput.currency, fiatValueOutput.currency)) return undefined
if (JSBI.equal(fiatValueInput.raw, JSBI.BigInt(0))) return undefined
const pct = ONE_HUNDRED_PERCENT.subtract(fiatValueOutput.divide(fiatValueInput))
return new Percent(pct.numerator, pct.denominator)
}
export default function Swap({ history }: RouteComponentProps) { export default function Swap({ history }: RouteComponentProps) {
const loadedUrlParams = useDefaultsFromURLSearch() const loadedUrlParams = useDefaultsFromURLSearch()
......
import { CurrencyAmount, currencyEquals, Percent } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
import { ONE_HUNDRED_PERCENT } from '../constants'
export function computeFiatValuePriceImpact(
fiatValueInput: CurrencyAmount | undefined | null,
fiatValueOutput: CurrencyAmount | undefined | null
): Percent | undefined {
if (!fiatValueOutput || !fiatValueInput) return undefined
if (!currencyEquals(fiatValueInput.currency, fiatValueOutput.currency)) return undefined
if (JSBI.equal(fiatValueInput.raw, JSBI.BigInt(0))) return undefined
const pct = ONE_HUNDRED_PERCENT.subtract(fiatValueOutput.divide(fiatValueInput))
return new Percent(pct.numerator, pct.denominator)
}
...@@ -119,3 +119,4 @@ export function supportedChainId(chainId: number): ChainId | undefined { ...@@ -119,3 +119,4 @@ export function supportedChainId(chainId: number): ChainId | undefined {
export function formattedFeeAmount(feeAmount: FeeAmount): number { export function formattedFeeAmount(feeAmount: FeeAmount): number {
return feeAmount / 10000 return feeAmount / 10000
} }
export { computeFiatValuePriceImpact } from './computeFiatValuePriceImpact'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment