Commit 72936322 authored by Jack Short's avatar Jack Short Committed by GitHub

feat: adding price impact modal (#6681)

parent 1bc6eb9a
......@@ -391,6 +391,7 @@ export enum ButtonEmphasis {
low,
warning,
destructive,
failure,
}
interface BaseThemeButtonProps {
size: ButtonSize
......@@ -411,6 +412,8 @@ function pickThemeButtonBackgroundColor({ theme, emphasis }: { theme: DefaultThe
return theme.accentWarningSoft
case ButtonEmphasis.destructive:
return theme.accentCritical
case ButtonEmphasis.failure:
return theme.accentFailureSoft
case ButtonEmphasis.medium:
default:
return theme.backgroundInteractive
......@@ -465,6 +468,8 @@ function pickThemeButtonTextColor({ theme, emphasis }: { theme: DefaultTheme; em
return theme.accentWarning
case ButtonEmphasis.destructive:
return theme.accentTextDarkPrimary
case ButtonEmphasis.failure:
return theme.accentFailure
case ButtonEmphasis.medium:
default:
return theme.textPrimary
......
import { Trans } from '@lingui/macro'
import { formatPriceImpact } from '@uniswap/conedison/format'
import { Percent } from '@uniswap/sdk-core'
import { ButtonEmphasis, ButtonSize, ThemeButton } from 'components/Button'
import { ColumnCenter } from 'components/Column'
import Row from 'components/Row'
import { AlertTriangle } from 'react-feather'
import styled from 'styled-components/macro'
import { CloseIcon, ThemedText } from 'theme'
import Modal from '../Modal'
const Wrapper = styled(ColumnCenter)`
padding: 16px 24px;
`
const IconContainer = styled.div`
padding: 32px 0px;
`
const WarningIcon = styled(AlertTriangle)`
color: ${({ theme }) => theme.accentCritical};
`
const ButtonContainer = styled(ColumnCenter)`
padding: 12px 0px 0px;
`
const StyledThemeButton = styled(ThemeButton)`
width: 100%;
`
interface PriceImpactModalProps {
priceImpact: Percent
onDismiss: () => void
onContinue: () => void
}
export default function PriceImpactModal({ priceImpact, onDismiss, onContinue }: PriceImpactModalProps) {
return (
<Modal isOpen onDismiss={onDismiss}>
<Wrapper gap="md">
<Row padding="8px 0px 4px">
<CloseIcon size={24} onClick={onDismiss} />
</Row>
<IconContainer>
<WarningIcon size={48} />
</IconContainer>
<ColumnCenter gap="sm">
<ThemedText.HeadlineSmall fontWeight={500}>
<Trans>Warning</Trans>
</ThemedText.HeadlineSmall>
<ThemedText.BodyPrimary lineHeight="24px" textAlign="center">
<Trans>
This transaction will result in a{' '}
<ThemedText.BodyPrimary lineHeight="24px" color="accentFailure" display="inline">
{formatPriceImpact(priceImpact)}
</ThemedText.BodyPrimary>{' '}
price impact on the market price of this pool. Do you wish to continue?
</Trans>
</ThemedText.BodyPrimary>
</ColumnCenter>
<ButtonContainer gap="md">
<StyledThemeButton size={ButtonSize.large} emphasis={ButtonEmphasis.failure} onClick={onContinue}>
<Trans>Continue</Trans>
</StyledThemeButton>
<StyledThemeButton size={ButtonSize.medium} emphasis={ButtonEmphasis.low} onClick={onDismiss}>
<Trans>Cancel</Trans>
</StyledThemeButton>
</ButtonContainer>
</Wrapper>
</Modal>
)
}
......@@ -39,7 +39,7 @@ export default function PriceImpactWarning({ priceImpact }: PriceImpactWarningPr
<Trans>Price impact warning</Trans>
</ThemedText.DeprecatedSubHeader>
</RowFixed>
<ThemedText.DeprecatedLabel textAlign="right" fontSize={14} color={theme.accentFailure}>
<ThemedText.DeprecatedLabel textAlign="right" fontSize={14} color="accentFailure">
{formatPriceImpact(priceImpact)}
</ThemedText.DeprecatedLabel>
</RowBetween>
......
......@@ -15,6 +15,7 @@ import { useWeb3React } from '@web3-react/core'
import { useToggleAccountDrawer } from 'components/AccountDrawer'
import { sendEvent } from 'components/analytics'
import { NetworkAlert } from 'components/NetworkAlert/NetworkAlert'
import PriceImpactModal from 'components/swap/PriceImpactModal'
import PriceImpactWarning from 'components/swap/PriceImpactWarning'
import SwapDetailsDropdown from 'components/swap/SwapDetailsDropdown'
import TokenSafetyModal from 'components/TokenSafety/TokenSafetyModal'
......@@ -190,6 +191,8 @@ export function Swap({
}, [prefilledInputCurrency, prefilledOutputCurrency])
const [dismissTokenWarning, setDismissTokenWarning] = useState<boolean>(false)
const [showPriceImpactModal, setShowPriceImpactModal] = useState<boolean>(false)
const urlLoadedTokens: Token[] = useMemo(
() => [loadedInputCurrency, loadedOutputCurrency]?.filter((c): c is Token => c?.isToken ?? false) ?? [],
[loadedInputCurrency, loadedOutputCurrency]
......@@ -390,6 +393,15 @@ export function Swap({
allowance.state === AllowanceState.ALLOWED ? allowance.permitSignature : undefined
)
const handleContinueToReview = useCallback(() => {
setSwapState({
tradeToConfirm: trade,
swapError: undefined,
showConfirm: true,
txHash: undefined,
})
}, [trade])
const handleSwap = useCallback(() => {
if (!swapCallback) {
return
......@@ -500,7 +512,6 @@ export function Swap({
[onCurrencyChange, onCurrencySelection, state]
)
const priceImpactTooHigh = priceImpactSeverity > 3
const showPriceImpactWarning = largerPriceImpact && priceImpactSeverity > 3
const prevTrade = usePrevious(trade)
......@@ -545,6 +556,16 @@ export function Swap({
fiatValueOutput={fiatValueTradeOutput}
/>
)}
{showPriceImpactModal && showPriceImpactWarning && (
<PriceImpactModal
priceImpact={largerPriceImpact}
onDismiss={() => setShowPriceImpactModal(false)}
onContinue={() => {
setShowPriceImpactModal(false)
handleContinueToReview()
}}
/>
)}
<div style={{ display: 'relative' }}>
<SwapSection>
......@@ -698,16 +719,11 @@ export function Swap({
>
<ButtonError
onClick={() => {
setSwapState({
tradeToConfirm: trade,
swapError: undefined,
showConfirm: true,
txHash: undefined,
})
showPriceImpactWarning ? setShowPriceImpactModal(true) : handleContinueToReview()
}}
id="swap-button"
data-testid="swap-button"
disabled={!isValid || routeIsSyncing || routeIsLoading || priceImpactTooHigh}
disabled={!isValid || routeIsSyncing || routeIsLoading}
error={isValid && priceImpactSeverity > 2 && allowance.state === AllowanceState.ALLOWED}
>
<Text fontSize={20} fontWeight={600}>
......@@ -715,8 +731,6 @@ export function Swap({
swapInputError
) : routeIsSyncing || routeIsLoading ? (
<Trans>Swap</Trans>
) : priceImpactTooHigh ? (
<Trans>Price Impact Too High</Trans>
) : priceImpactSeverity > 2 ? (
<Trans>Swap Anyway</Trans>
) : (
......
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