diff --git a/ui/pages/Swap.tsx b/ui/pages/Swap.tsx index 1b781df85..8642f76c0 100644 --- a/ui/pages/Swap.tsx +++ b/ui/pages/Swap.tsx @@ -29,7 +29,6 @@ import { ReadOnlyAccountSigner } from "@tallyho/tally-background/services/signin import { NETWORKS_SUPPORTING_SWAPS, OPTIMISM, - SECOND, } from "@tallyho/tally-background/constants" import { @@ -52,12 +51,10 @@ import { getSellAssetAmounts, getOwnedSellAssetAmounts, } from "../utils/swap" -import { useOnMount, usePrevious, useInterval } from "../hooks/react-hooks" +import { useOnMount, usePrevious } from "../hooks/react-hooks" import SharedLoadingDoggo from "../components/Shared/SharedLoadingDoggo" import SharedBackButton from "../components/Shared/SharedBackButton" -const REFRESH_QUOTE_INTERVAL = 10 * SECOND - export default function Swap(): ReactElement { const { t } = useTranslation() const dispatch = useBackgroundDispatch() @@ -163,6 +160,8 @@ export default function Swap(): ReactElement { } }, [sellAsset, sellAssetAmounts]) + const [amountInputHasFocus, setAmountInputHasFocus] = useState(false) + const { loading: loadingQuote, loadingSellAmount, @@ -174,6 +173,7 @@ export default function Swap(): ReactElement { slippageTolerance: useBackgroundSelector(selectSlippageTolerance), networkSettings: useBackgroundSelector(selectDefaultNetworkFeeSettings), }, + pauseAutoRefresh: amountInputHasFocus, }) const inProgressApprovalContract = useBackgroundSelector( @@ -300,38 +300,6 @@ export default function Swap(): ReactElement { } } - const [amountInputHasFocus, setAmountInputHasFocus] = useState(false) - - useInterval(() => { - if (!isEnabled(FeatureFlags.SUPPORT_SWAP_QUOTE_REFRESH)) return - - const isRecentQuote = - quote && - // Time passed since last quote - Date.now() - quote.timestamp <= 3 * SECOND - - const skipRefresh = - loadingQuote || (isRecentQuote && quoteAppliesToCurrentAssets) - - if ( - !skipRefresh && - !amountInputHasFocus && - sellAsset && - buyAsset && - (sellAmount || buyAmount) - ) { - const type = sellAmount ? "getBuyAmount" : "getSellAmount" - const amount = sellAmount || buyAmount - - requestQuoteUpdate({ - type, - amount, - sellAsset, - buyAsset, - }) - } - }, REFRESH_QUOTE_INTERVAL) - useOnMount(() => { // Request a quote on mount if (sellAsset && buyAsset && sellAmount) { diff --git a/ui/utils/swap.ts b/ui/utils/swap.ts index 5edae4224..378e2c006 100644 --- a/ui/utils/swap.ts +++ b/ui/utils/swap.ts @@ -15,7 +15,7 @@ import { SwapQuoteRequest, } from "@tallyho/tally-background/redux-slices/utils/0x-swap-utils" import { debounce, DebouncedFunc } from "lodash" -import { useState, useRef, useCallback } from "react" +import { useState, useRef, useCallback, useEffect } from "react" import { CompleteAssetAmount } from "@tallyho/tally-background/redux-slices/accounts" import { isSameAsset, @@ -140,6 +140,7 @@ type RequestQuoteUpdateConfig = { export function useSwapQuote(useSwapConfig: { savedQuoteRequest?: SwapQuoteRequest initialSwapSettings: QuoteUpdate["swapTransactionSettings"] + pauseAutoRefresh?: boolean }): { quote: QuoteUpdate | null loading: boolean @@ -154,7 +155,6 @@ export function useSwapQuote(useSwapConfig: { useSwapConfig.initialSwapSettings, ) - // Quoted amounts const [quoteRequestState, setQuoteRequestState] = useSetState<{ quote: QuoteUpdate | null loading: boolean @@ -185,14 +185,12 @@ export function useSwapQuote(useSwapConfig: { const transactionSettings = config.transactionSettings ?? requestContext.initialTransactionSettings - // Swap amounts can't update unless both sell and buy assets are specified. if ( !sellAsset || !buyAsset || amount.trim() === "" || Number(amount) === 0 ) { - // noop return } @@ -224,7 +222,7 @@ export function useSwapQuote(useSwapConfig: { setQuoteRequestState({ quote: result, - // Finish loading once the last quote is fulfilled + ...(hasPendingRequests ? { loading: true } : { loading: false, loadingType: undefined }), @@ -250,6 +248,30 @@ export function useSwapQuote(useSwapConfig: { const loadingSellAmount = quoteRequestState.loadingType === "getSellAmount" const loadingBuyAmount = quoteRequestState.loadingType === "getBuyAmount" + useEffect(() => { + if (useSwapConfig.pauseAutoRefresh) { + return + } + + const interval = setInterval(() => { + if (quoteRequestState.quote) { + requestQuoteUpdate({ + type: "getSellAmount", + amount: quoteRequestState.quote.amount, + sellAsset: quoteRequestState.quote.sellAsset, + buyAsset: quoteRequestState.quote.buyAsset, + transactionSettings: quoteRequestState.quote.swapTransactionSettings, + }) + } + }, 10000) + + return () => clearInterval(interval) + }, [ + quoteRequestState.quote, + requestQuoteUpdate, + useSwapConfig.pauseAutoRefresh, + ]) + return { quote: quoteRequestState.quote, loading: quoteRequestState.loading,