9e1a775c13
* client-side smart order router support * support auto router on L2s * add swap router version in approval/swap callback GA events to save $ on approval txs * add persistent UI view of gas estimate on L1s Co-authored-by: Lint Action <lint-action@samuelmeuli.com> Co-authored-by: Ian Lapham <ian@uniswap.org> Co-authored-by: Callil Capuozzo <callil.capuozzo@gmail.com>
176 lines
6.5 KiB
TypeScript
176 lines
6.5 KiB
TypeScript
import { Trans } from '@lingui/macro'
|
|
import { Currency, Percent, TradeType } from '@uniswap/sdk-core'
|
|
import { useContext, useState } from 'react'
|
|
import { AlertTriangle, ArrowDown } from 'react-feather'
|
|
import { Text } from 'rebass'
|
|
import { InterfaceTrade } from 'state/routing/types'
|
|
import styled, { ThemeContext } from 'styled-components/macro'
|
|
|
|
import { useUSDCValue } from '../../hooks/useUSDCPrice'
|
|
import { ThemedText } from '../../theme'
|
|
import { isAddress, shortenAddress } from '../../utils'
|
|
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
|
|
import { ButtonPrimary } from '../Button'
|
|
import { LightCard } from '../Card'
|
|
import { AutoColumn } from '../Column'
|
|
import { FiatValue } from '../CurrencyInputPanel/FiatValue'
|
|
import CurrencyLogo from '../CurrencyLogo'
|
|
import { RowBetween, RowFixed } from '../Row'
|
|
import TradePrice from '../swap/TradePrice'
|
|
import { AdvancedSwapDetails } from './AdvancedSwapDetails'
|
|
import { SwapShowAcceptChanges, TruncatedText } from './styleds'
|
|
|
|
const ArrowWrapper = styled.div`
|
|
padding: 4px;
|
|
border-radius: 12px;
|
|
height: 32px;
|
|
width: 32px;
|
|
position: relative;
|
|
margin-top: -18px;
|
|
margin-bottom: -18px;
|
|
left: calc(50% - 16px);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: ${({ theme }) => theme.bg1};
|
|
border: 4px solid;
|
|
border-color: ${({ theme }) => theme.bg0};
|
|
z-index: 2;
|
|
`
|
|
|
|
export default function SwapModalHeader({
|
|
trade,
|
|
allowedSlippage,
|
|
recipient,
|
|
showAcceptChanges,
|
|
onAcceptChanges,
|
|
}: {
|
|
trade: InterfaceTrade<Currency, Currency, TradeType>
|
|
allowedSlippage: Percent
|
|
recipient: string | null
|
|
showAcceptChanges: boolean
|
|
onAcceptChanges: () => void
|
|
}) {
|
|
const theme = useContext(ThemeContext)
|
|
|
|
const [showInverted, setShowInverted] = useState<boolean>(false)
|
|
|
|
const fiatValueInput = useUSDCValue(trade.inputAmount)
|
|
const fiatValueOutput = useUSDCValue(trade.outputAmount)
|
|
|
|
return (
|
|
<AutoColumn gap={'4px'} style={{ marginTop: '1rem' }}>
|
|
<LightCard padding="0.75rem 1rem">
|
|
<AutoColumn gap={'8px'}>
|
|
<RowBetween align="center">
|
|
<RowFixed gap={'0px'}>
|
|
<TruncatedText
|
|
fontSize={24}
|
|
fontWeight={500}
|
|
color={showAcceptChanges && trade.tradeType === TradeType.EXACT_OUTPUT ? theme.primary1 : ''}
|
|
>
|
|
{trade.inputAmount.toSignificant(6)}
|
|
</TruncatedText>
|
|
</RowFixed>
|
|
<RowFixed gap={'0px'}>
|
|
<CurrencyLogo currency={trade.inputAmount.currency} size={'20px'} style={{ marginRight: '12px' }} />
|
|
<Text fontSize={20} fontWeight={500}>
|
|
{trade.inputAmount.currency.symbol}
|
|
</Text>
|
|
</RowFixed>
|
|
</RowBetween>
|
|
<RowBetween>
|
|
<FiatValue fiatValue={fiatValueInput} />
|
|
</RowBetween>
|
|
</AutoColumn>
|
|
</LightCard>
|
|
<ArrowWrapper>
|
|
<ArrowDown size="16" color={theme.text2} />
|
|
</ArrowWrapper>
|
|
<LightCard padding="0.75rem 1rem" style={{ marginBottom: '0.25rem' }}>
|
|
<AutoColumn gap={'8px'}>
|
|
<RowBetween align="flex-end">
|
|
<RowFixed gap={'0px'}>
|
|
<TruncatedText fontSize={24} fontWeight={500}>
|
|
{trade.outputAmount.toSignificant(6)}
|
|
</TruncatedText>
|
|
</RowFixed>
|
|
<RowFixed gap={'0px'}>
|
|
<CurrencyLogo currency={trade.outputAmount.currency} size={'20px'} style={{ marginRight: '12px' }} />
|
|
<Text fontSize={20} fontWeight={500}>
|
|
{trade.outputAmount.currency.symbol}
|
|
</Text>
|
|
</RowFixed>
|
|
</RowBetween>
|
|
<RowBetween>
|
|
<ThemedText.Body fontSize={14} color={theme.text3}>
|
|
<FiatValue
|
|
fiatValue={fiatValueOutput}
|
|
priceImpact={computeFiatValuePriceImpact(fiatValueInput, fiatValueOutput)}
|
|
/>
|
|
</ThemedText.Body>
|
|
</RowBetween>
|
|
</AutoColumn>
|
|
</LightCard>
|
|
<RowBetween style={{ marginTop: '0.25rem', padding: '0 1rem' }}>
|
|
<TradePrice price={trade.executionPrice} showInverted={showInverted} setShowInverted={setShowInverted} />
|
|
</RowBetween>
|
|
<LightCard style={{ padding: '.75rem', marginTop: '0.5rem' }}>
|
|
<AdvancedSwapDetails trade={trade} allowedSlippage={allowedSlippage} />
|
|
</LightCard>
|
|
{showAcceptChanges ? (
|
|
<SwapShowAcceptChanges justify="flex-start" gap={'0px'}>
|
|
<RowBetween>
|
|
<RowFixed>
|
|
<AlertTriangle size={20} style={{ marginRight: '8px', minWidth: 24 }} />
|
|
<ThemedText.Main color={theme.primary1}>
|
|
<Trans>Price Updated</Trans>
|
|
</ThemedText.Main>
|
|
</RowFixed>
|
|
<ButtonPrimary
|
|
style={{ padding: '.5rem', width: 'fit-content', fontSize: '0.825rem', borderRadius: '12px' }}
|
|
onClick={onAcceptChanges}
|
|
>
|
|
<Trans>Accept</Trans>
|
|
</ButtonPrimary>
|
|
</RowBetween>
|
|
</SwapShowAcceptChanges>
|
|
) : null}
|
|
|
|
<AutoColumn justify="flex-start" gap="sm" style={{ padding: '.75rem 1rem' }}>
|
|
{trade.tradeType === TradeType.EXACT_INPUT ? (
|
|
<ThemedText.Italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
|
|
<Trans>
|
|
Output is estimated. You will receive at least{' '}
|
|
<b>
|
|
{trade.minimumAmountOut(allowedSlippage).toSignificant(6)} {trade.outputAmount.currency.symbol}
|
|
</b>{' '}
|
|
or the transaction will revert.
|
|
</Trans>
|
|
</ThemedText.Italic>
|
|
) : (
|
|
<ThemedText.Italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
|
|
<Trans>
|
|
Input is estimated. You will sell at most{' '}
|
|
<b>
|
|
{trade.maximumAmountIn(allowedSlippage).toSignificant(6)} {trade.inputAmount.currency.symbol}
|
|
</b>{' '}
|
|
or the transaction will revert.
|
|
</Trans>
|
|
</ThemedText.Italic>
|
|
)}
|
|
</AutoColumn>
|
|
{recipient !== null ? (
|
|
<AutoColumn justify="flex-start" gap="sm" style={{ padding: '12px 0 0 0px' }}>
|
|
<ThemedText.Main>
|
|
<Trans>
|
|
Output will be sent to{' '}
|
|
<b title={recipient}>{isAddress(recipient) ? shortenAddress(recipient) : recipient}</b>
|
|
</Trans>
|
|
</ThemedText.Main>
|
|
</AutoColumn>
|
|
) : null}
|
|
</AutoColumn>
|
|
)
|
|
}
|