Commit 96a42f66 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

fix(widgets): disable interactions and don't show summary screen on unsupported networks (#3376)

* disable interactions and don't show summary screen on unsupported networks

* clear input values on unsupported network

* pr feedback

* pr feedback

* simpler active trade clearing

* rename some things
parent c446f20d
import { useLingui } from '@lingui/react' import { useLingui } from '@lingui/react'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { useUSDCValue } from 'hooks/useUSDCPrice' import { useUSDCValue } from 'hooks/useUSDCPrice'
import { loadingOpacityCss } from 'lib/css/loading' import { loadingOpacityCss } from 'lib/css/loading'
import { import {
...@@ -45,6 +46,27 @@ export interface InputProps { ...@@ -45,6 +46,27 @@ export interface InputProps {
focused: boolean focused: boolean
} }
interface UseFormattedFieldAmountArguments {
disabled: boolean
currencyAmount?: CurrencyAmount<Currency>
fieldAmount?: string
}
export function useFormattedFieldAmount({ disabled, currencyAmount, fieldAmount }: UseFormattedFieldAmountArguments) {
return useMemo(() => {
if (disabled) {
return ''
}
if (fieldAmount !== undefined) {
return fieldAmount
}
if (currencyAmount) {
return currencyAmount.toSignificant(6)
}
return ''
}, [disabled, currencyAmount, fieldAmount])
}
export default function Input({ disabled, focused }: InputProps) { export default function Input({ disabled, focused }: InputProps) {
const { i18n } = useLingui() const { i18n } = useLingui()
const { const {
...@@ -81,11 +103,17 @@ export default function Input({ disabled, focused }: InputProps) { ...@@ -81,11 +103,17 @@ export default function Input({ disabled, focused }: InputProps) {
return insufficientBalance ? 'error' : undefined return insufficientBalance ? 'error' : undefined
}, [balance, inputCurrencyAmount, swapInputCurrencyAmount]) }, [balance, inputCurrencyAmount, swapInputCurrencyAmount])
const amount = useFormattedFieldAmount({
disabled,
currencyAmount: inputCurrencyAmount,
fieldAmount: swapInputAmount,
})
return ( return (
<InputColumn gap={0.5} approved={mockApproved}> <InputColumn gap={0.5} approved={mockApproved}>
<TokenInput <TokenInput
currency={swapInputCurrency} currency={swapInputCurrency}
amount={(swapInputAmount !== undefined ? swapInputAmount : swapInputCurrencyAmount?.toSignificant(6)) ?? ''} amount={amount}
max={max} max={max}
disabled={disabled} disabled={disabled}
onChangeInput={updateSwapInputAmount} onChangeInput={updateSwapInputAmount}
......
...@@ -16,7 +16,7 @@ import { getPriceImpactWarning } from 'utils/prices' ...@@ -16,7 +16,7 @@ import { getPriceImpactWarning } from 'utils/prices'
import Column from '../Column' import Column from '../Column'
import Row from '../Row' import Row from '../Row'
import { Balance, InputProps, LoadingRow } from './Input' import { Balance, InputProps, LoadingRow, useFormattedFieldAmount } from './Input'
import TokenInput from './TokenInput' import TokenInput from './TokenInput'
export const colorAtom = atom<string | undefined>(undefined) export const colorAtom = atom<string | undefined>(undefined)
...@@ -78,6 +78,12 @@ export default function Output({ disabled, focused, children }: PropsWithChildre ...@@ -78,6 +78,12 @@ export default function Output({ disabled, focused, children }: PropsWithChildre
) )
}, [inputUSDC, outputUSDC]) }, [inputUSDC, outputUSDC])
const amount = useFormattedFieldAmount({
disabled,
currencyAmount: outputCurrencyAmount,
fieldAmount: swapOutputAmount,
})
return ( return (
<DynamicThemeProvider color={color}> <DynamicThemeProvider color={color}>
<OutputColumn hasColor={hasColor} gap={0.5}> <OutputColumn hasColor={hasColor} gap={0.5}>
...@@ -88,7 +94,7 @@ export default function Output({ disabled, focused, children }: PropsWithChildre ...@@ -88,7 +94,7 @@ export default function Output({ disabled, focused, children }: PropsWithChildre
</Row> </Row>
<TokenInput <TokenInput
currency={swapOutputCurrency} currency={swapOutputCurrency}
amount={(swapOutputAmount !== undefined ? swapOutputAmount : outputCurrencyAmount?.toSignificant(6)) ?? ''} amount={amount}
disabled={disabled} disabled={disabled}
onChangeInput={updateSwapOutputAmount} onChangeInput={updateSwapOutputAmount}
onChangeCurrency={updateSwapOutputCurrency} onChangeCurrency={updateSwapOutputCurrency}
......
...@@ -57,6 +57,11 @@ export default function SwapButton({ disabled }: SwapButtonProps) { ...@@ -57,6 +57,11 @@ export default function SwapButton({ disabled }: SwapButtonProps) {
setActiveTrade((activeTrade) => activeTrade && trade.trade) setActiveTrade((activeTrade) => activeTrade && trade.trade)
}, [trade]) }, [trade])
// clear active trade on chain change
useEffect(() => {
setActiveTrade(undefined)
}, [chainId])
// TODO(zzmp): Return an optimized trade directly from useSwapInfo. // TODO(zzmp): Return an optimized trade directly from useSwapInfo.
const optimizedTrade = const optimizedTrade =
// Use trade.trade if there is no swap optimized trade. This occurs if approvals are still pending. // Use trade.trade if there is no swap optimized trade. This occurs if approvals are still pending.
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { TokenInfo } from '@uniswap/token-lists' import { TokenInfo } from '@uniswap/token-lists'
import { ALL_SUPPORTED_CHAIN_IDS } from 'constants/chains'
import { useAtom } from 'jotai' import { useAtom } from 'jotai'
import { SwapInfoUpdater } from 'lib/hooks/swap/useSwapInfo' import { SwapInfoUpdater } from 'lib/hooks/swap/useSwapInfo'
import useSyncConvenienceFee from 'lib/hooks/swap/useSyncConvenienceFee' import useSyncConvenienceFee from 'lib/hooks/swap/useSyncConvenienceFee'
...@@ -8,6 +7,7 @@ import useSyncSwapDefaults from 'lib/hooks/swap/useSyncSwapDefaults' ...@@ -8,6 +7,7 @@ import useSyncSwapDefaults from 'lib/hooks/swap/useSyncSwapDefaults'
import { usePendingTransactions } from 'lib/hooks/transactions' import { usePendingTransactions } from 'lib/hooks/transactions'
import useActiveWeb3React from 'lib/hooks/useActiveWeb3React' import useActiveWeb3React from 'lib/hooks/useActiveWeb3React'
import useHasFocus from 'lib/hooks/useHasFocus' import useHasFocus from 'lib/hooks/useHasFocus'
import useOnSupportedNetwork from 'lib/hooks/useOnSupportedNetwork'
import useTokenList, { useSyncTokenList } from 'lib/hooks/useTokenList' import useTokenList, { useSyncTokenList } from 'lib/hooks/useTokenList'
import { displayTxHashAtom } from 'lib/state/swap' import { displayTxHashAtom } from 'lib/state/swap'
import { SwapTransactionInfo, Transaction, TransactionType, WrapTransactionInfo } from 'lib/state/transactions' import { SwapTransactionInfo, Transaction, TransactionType, WrapTransactionInfo } from 'lib/state/transactions'
...@@ -60,7 +60,7 @@ export default function Swap(props: SwapProps) { ...@@ -60,7 +60,7 @@ export default function Swap(props: SwapProps) {
useSyncSwapDefaults(props) useSyncSwapDefaults(props)
useSyncConvenienceFee(props) useSyncConvenienceFee(props)
const { active, account, chainId } = useActiveWeb3React() const { active, account } = useActiveWeb3React()
const [wrapper, setWrapper] = useState<HTMLDivElement | null>(null) const [wrapper, setWrapper] = useState<HTMLDivElement | null>(null)
const [displayTxHash, setDisplayTxHash] = useAtom(displayTxHashAtom) const [displayTxHash, setDisplayTxHash] = useAtom(displayTxHashAtom)
...@@ -68,27 +68,30 @@ export default function Swap(props: SwapProps) { ...@@ -68,27 +68,30 @@ export default function Swap(props: SwapProps) {
const displayTx = getTransactionFromMap(pendingTxs, displayTxHash) const displayTx = getTransactionFromMap(pendingTxs, displayTxHash)
const tokenList = useTokenList() const tokenList = useTokenList()
const onSupportedNetwork = useOnSupportedNetwork()
const isSwapSupported = useMemo( const isSwapSupported = useMemo(
() => Boolean(chainId && ALL_SUPPORTED_CHAIN_IDS.includes(chainId) && tokenList?.length), () => Boolean(active && onSupportedNetwork && tokenList?.length),
[chainId, tokenList] [active, onSupportedNetwork, tokenList?.length]
) )
const focused = useHasFocus(wrapper) const focused = useHasFocus(wrapper)
const isInteractive = Boolean(active && onSupportedNetwork)
return ( return (
<SwapPropValidator {...props}> <SwapPropValidator {...props}>
{isSwapSupported && <SwapInfoUpdater />} {isSwapSupported && <SwapInfoUpdater />}
<Header title={<Trans>Swap</Trans>}> <Header title={<Trans>Swap</Trans>}>
{active && <Wallet disabled={!account} onClick={props.onConnectWallet} />} {active && <Wallet disabled={!account} onClick={props.onConnectWallet} />}
<Settings disabled={!active} /> <Settings disabled={!isInteractive} />
</Header> </Header>
<div ref={setWrapper}> <div ref={setWrapper}>
<BoundaryProvider value={wrapper}> <BoundaryProvider value={wrapper}>
<Input disabled={!active} focused={focused} /> <Input disabled={!isInteractive} focused={focused} />
<ReverseButton disabled={!active} /> <ReverseButton disabled={!isInteractive} />
<Output disabled={!active} focused={focused}> <Output disabled={!isInteractive} focused={focused}>
<Toolbar disabled={!active} /> <Toolbar disabled={!active} />
<SwapButton disabled={!account} /> <SwapButton disabled={!isSwapSupported} />
</Output> </Output>
</BoundaryProvider> </BoundaryProvider>
</div> </div>
......
import { ALL_SUPPORTED_CHAIN_IDS } from 'constants/chains'
import { useMemo } from 'react'
import useActiveWeb3React from './useActiveWeb3React'
function useOnSupportedNetwork() {
const { chainId } = useActiveWeb3React()
return useMemo(() => chainId && ALL_SUPPORTED_CHAIN_IDS.includes(chainId), [chainId])
}
export default useOnSupportedNetwork
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