show currency values and price impact in the confirmation modal (fixes https://github.com/Uniswap/v3-interface/issues/92)
This commit is contained in:
parent
f4e994867e
commit
300dd70804
32
src/components/CurrencyInputPanel/FiatValue.tsx
Normal file
32
src/components/CurrencyInputPanel/FiatValue.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
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>
|
||||
)
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
import { Pair } from '@uniswap/v2-sdk'
|
||||
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 { darken } from 'polished'
|
||||
import { useCurrencyBalance } from '../../state/wallet/hooks'
|
||||
import { warningSeverity } from '../../utils/prices'
|
||||
import CurrencySearchModal from '../SearchModal/CurrencySearchModal'
|
||||
import CurrencyLogo from '../CurrencyLogo'
|
||||
import DoubleCurrencyLogo from '../DoubleLogo'
|
||||
@ -18,6 +17,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import useTheme from '../../hooks/useTheme'
|
||||
import { Lock } from 'react-feather'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { FiatValue } from './FiatValue'
|
||||
|
||||
const InputPanel = styled.div<{ hideInput?: boolean }>`
|
||||
${({ theme }) => theme.flexColumnNoWrap}
|
||||
@ -196,15 +196,6 @@ export default function CurrencyInputPanel({
|
||||
setModalOpen(false)
|
||||
}, [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 (
|
||||
<InputPanel id={id} hideInput={hideInput} {...rest}>
|
||||
{locked && (
|
||||
@ -291,12 +282,7 @@ export default function CurrencyInputPanel({
|
||||
</RowFixed>
|
||||
)}
|
||||
|
||||
<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>
|
||||
<FiatValue fiatValue={fiatValue} priceImpact={priceImpact} />
|
||||
</RowBetween>
|
||||
</FiatRow>
|
||||
)}
|
||||
|
@ -5,10 +5,12 @@ import React, { useContext, useState } from 'react'
|
||||
import { ArrowDown, AlertTriangle } from 'react-feather'
|
||||
import { Text } from 'rebass'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import { useUSDCValue } from '../../hooks/useUSDCPrice'
|
||||
import { TYPE } from '../../theme'
|
||||
import { ButtonPrimary } from '../Button'
|
||||
import { isAddress, shortenAddress } from '../../utils'
|
||||
import { computeFiatValuePriceImpact, isAddress, shortenAddress } from '../../utils'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { FiatValue } from '../CurrencyInputPanel/FiatValue'
|
||||
import CurrencyLogo from '../CurrencyLogo'
|
||||
import { RowBetween, RowFixed } from '../Row'
|
||||
import { TruncatedText, SwapShowAcceptChanges } from './styleds'
|
||||
@ -57,17 +59,18 @@ export default function SwapModalHeader({
|
||||
|
||||
const [showInverted, setShowInverted] = useState<boolean>(false)
|
||||
|
||||
const fiatValueInput = useUSDCValue(maximumAmountIn)
|
||||
const fiatValueOutput = useUSDCValue(minimumAmountOut)
|
||||
|
||||
return (
|
||||
<AutoColumn gap={'4px'} style={{ marginTop: '1rem' }}>
|
||||
<DarkGreyCard padding="0.75rem 1rem">
|
||||
<AutoColumn gap={'8px'}>
|
||||
<RowBetween>
|
||||
<TYPE.body color={theme.text3} fontWeight={500} fontSize={14}>
|
||||
{'From'}
|
||||
</TYPE.body>
|
||||
<TYPE.body fontSize={14} color={theme.text3}>
|
||||
{'$-'}
|
||||
From
|
||||
</TYPE.body>
|
||||
<FiatValue fiatValue={fiatValueInput} />
|
||||
</RowBetween>
|
||||
<RowBetween align="center">
|
||||
<RowFixed gap={'0px'}>
|
||||
@ -95,10 +98,13 @@ export default function SwapModalHeader({
|
||||
<AutoColumn gap={'8px'}>
|
||||
<RowBetween>
|
||||
<TYPE.body color={theme.text3} fontWeight={500} fontSize={14}>
|
||||
{'To'}
|
||||
To
|
||||
</TYPE.body>
|
||||
<TYPE.body fontSize={14} color={theme.text3}>
|
||||
{'$-'}
|
||||
<FiatValue
|
||||
fiatValue={fiatValueOutput}
|
||||
priceImpact={computeFiatValuePriceImpact(fiatValueInput, fiatValueOutput)}
|
||||
/>
|
||||
</TYPE.body>
|
||||
</RowBetween>
|
||||
<RowBetween align="flex-end">
|
||||
|
@ -1,4 +1,4 @@
|
||||
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 V3Trade } from '@uniswap/v3-sdk'
|
||||
import { AdvancedSwapDetails } from 'components/swap/AdvancedSwapDetails'
|
||||
@ -6,26 +6,27 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter
|
||||
import { MouseoverTooltip, MouseoverTooltipContent } from 'components/Tooltip'
|
||||
import JSBI from 'jsbi'
|
||||
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 { RouteComponentProps } from 'react-router-dom'
|
||||
import { Link, RouteComponentProps } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import { ThemeContext } from 'styled-components'
|
||||
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 { AutoColumn } from '../../components/Column'
|
||||
import CurrencyInputPanel from '../../components/CurrencyInputPanel'
|
||||
import CurrencyLogo from '../../components/CurrencyLogo'
|
||||
import Loader from '../../components/Loader'
|
||||
import { AutoRow, RowBetween, RowFixed } from '../../components/Row'
|
||||
import BetterTradeLink from '../../components/swap/BetterTradeLink'
|
||||
import confirmPriceImpactWithoutFee from '../../components/swap/confirmPriceImpactWithoutFee'
|
||||
import ConfirmSwapModal from '../../components/swap/ConfirmSwapModal'
|
||||
|
||||
import { ArrowWrapper, BottomGrouping, Dots, SwapCallbackError, Wrapper } from '../../components/swap/styleds'
|
||||
import SwapHeader from '../../components/swap/SwapHeader'
|
||||
import TradePrice from '../../components/swap/TradePrice'
|
||||
import TokenWarningModal from '../../components/TokenWarningModal'
|
||||
import { ONE_HUNDRED_PERCENT } from '../../constants'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useAllTokens, useCurrency } from '../../hooks/Tokens'
|
||||
import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useApproveCallback'
|
||||
@ -47,27 +48,13 @@ import {
|
||||
} from '../../state/swap/hooks'
|
||||
import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance } from '../../state/user/hooks'
|
||||
import { LinkStyledButton, TYPE } from '../../theme'
|
||||
import { computeFiatValuePriceImpact } from '../../utils'
|
||||
import { getTradeVersion } from '../../utils/getTradeVersion'
|
||||
import { isTradeBetter } from '../../utils/isTradeBetter'
|
||||
import { maxAmountSpend } from '../../utils/maxAmountSpend'
|
||||
import { warningSeverity } from '../../utils/prices'
|
||||
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) {
|
||||
const loadedUrlParams = useDefaultsFromURLSearch()
|
||||
|
||||
|
14
src/utils/computeFiatValuePriceImpact.tsx
Normal file
14
src/utils/computeFiatValuePriceImpact.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
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 {
|
||||
export function formattedFeeAmount(feeAmount: FeeAmount): number {
|
||||
return feeAmount / 10000
|
||||
}
|
||||
export { computeFiatValuePriceImpact } from './computeFiatValuePriceImpact'
|
||||
|
Loading…
Reference in New Issue
Block a user