fix: add syncing state to trade loading (#3545)
* add syncing state to trade loading * remove log statement * update loading state * update useLast trade logic * nit fixes
This commit is contained in:
parent
7d9657867d
commit
e1abd81a1d
@ -100,7 +100,11 @@ export async function getClientSideQuote(
|
||||
)
|
||||
}
|
||||
|
||||
export function useFreshQuote(quoteResult: GetQuoteResult | undefined, maxBlockAge = 10): GetQuoteResult | undefined {
|
||||
/** Used to keep quotes up to date given a certain block age. Returns undefined if past limit. */
|
||||
export function useFilterFreshQuote(
|
||||
quoteResult: GetQuoteResult | undefined,
|
||||
maxBlockAge = 10
|
||||
): GetQuoteResult | undefined {
|
||||
const block = useBlockNumber()
|
||||
if (!block || !quoteResult) return undefined
|
||||
if (block - (Number(quoteResult.blockNumber) || 0) > maxBlockAge) return undefined
|
||||
|
@ -2,6 +2,7 @@ import { Protocol } from '@uniswap/router-sdk'
|
||||
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
|
||||
import { ChainId } from '@uniswap/smart-order-router'
|
||||
import useDebounce from 'hooks/useDebounce'
|
||||
import useLast from 'hooks/useLast'
|
||||
import { useStablecoinAmountFromFiatValue } from 'hooks/useUSDCPrice'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { GetQuoteResult, InterfaceTrade, TradeState } from 'state/routing/types'
|
||||
@ -10,7 +11,7 @@ import { computeRoutes, transformRoutesToTrade } from 'state/routing/utils'
|
||||
import useWrapCallback, { WrapType } from '../swap/useWrapCallback'
|
||||
import useActiveWeb3React from '../useActiveWeb3React'
|
||||
import usePoll from '../usePoll'
|
||||
import { getClientSideQuote, useFreshQuote } from './clientSideSmartOrderRouter'
|
||||
import { getClientSideQuote, useFilterFreshQuote } from './clientSideSmartOrderRouter'
|
||||
import { useRoutingAPIArguments } from './useRoutingAPIArguments'
|
||||
|
||||
/**
|
||||
@ -78,26 +79,38 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
|
||||
return { error: true }
|
||||
}
|
||||
}, [config, params, queryArgs, wrapType])
|
||||
|
||||
const { data, error } = usePoll(getQuoteResult, JSON.stringify(queryArgs)) ?? {
|
||||
error: undefined,
|
||||
}
|
||||
const quoteResult = useFreshQuote(data)
|
||||
|
||||
const quoteResult = useFilterFreshQuote(data)
|
||||
const isLoading = !quoteResult
|
||||
|
||||
const route = useMemo(
|
||||
() => computeRoutes(currencyIn, currencyOut, tradeType, quoteResult),
|
||||
[currencyIn, currencyOut, quoteResult, tradeType]
|
||||
)
|
||||
const gasUseEstimateUSD = useStablecoinAmountFromFiatValue(quoteResult?.gasUseEstimateUSD) ?? null
|
||||
const trade = useMemo(() => {
|
||||
if (route) {
|
||||
try {
|
||||
return route && transformRoutesToTrade(route, tradeType, gasUseEstimateUSD)
|
||||
} catch (e: unknown) {
|
||||
console.debug('transformRoutesToTrade failed: ', e)
|
||||
}
|
||||
}
|
||||
return
|
||||
}, [gasUseEstimateUSD, route, tradeType])
|
||||
const trade =
|
||||
useLast(
|
||||
useMemo(() => {
|
||||
if (route) {
|
||||
try {
|
||||
return route && transformRoutesToTrade(route, tradeType, gasUseEstimateUSD)
|
||||
} catch (e: unknown) {
|
||||
console.debug('transformRoutesToTrade failed: ', e)
|
||||
}
|
||||
}
|
||||
return
|
||||
}, [gasUseEstimateUSD, route, tradeType]),
|
||||
Boolean
|
||||
) ?? undefined
|
||||
|
||||
// Dont return old trade if currencies dont match.
|
||||
const isStale =
|
||||
(currencyIn && !trade?.inputAmount?.currency.equals(currencyIn)) ||
|
||||
(currencyOut && !trade?.outputAmount?.currency.equals(currencyOut))
|
||||
|
||||
return useMemo(() => {
|
||||
if (!currencyIn || !currencyOut) {
|
||||
@ -106,9 +119,11 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
|
||||
|
||||
// Returns the last trade state while syncing/loading to avoid jank from clearing the last trade while loading.
|
||||
if (!error) {
|
||||
if (isDebouncing) {
|
||||
if (isStale) {
|
||||
return { state: TradeState.LOADING, trade: undefined }
|
||||
} else if (isDebouncing) {
|
||||
return { state: TradeState.SYNCING, trade }
|
||||
} else if (!quoteResult) {
|
||||
} else if (isLoading) {
|
||||
return { state: TradeState.LOADING, trade }
|
||||
}
|
||||
}
|
||||
@ -133,5 +148,17 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
|
||||
return { state: TradeState.VALID, trade }
|
||||
}
|
||||
return { state: TradeState.INVALID, trade: undefined }
|
||||
}, [currencyIn, currencyOut, quoteResult, error, route, queryArgs, trade, isDebouncing, tradeType])
|
||||
}, [
|
||||
currencyIn,
|
||||
currencyOut,
|
||||
error,
|
||||
quoteResult,
|
||||
route,
|
||||
queryArgs,
|
||||
trade,
|
||||
isStale,
|
||||
isDebouncing,
|
||||
isLoading,
|
||||
tradeType,
|
||||
])
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { skipToken } from '@reduxjs/toolkit/query/react'
|
||||
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
|
||||
import { IMetric, MetricLoggerUnit, setGlobalMetric } from '@uniswap/smart-order-router'
|
||||
import { useStablecoinAmountFromFiatValue } from 'hooks/useUSDCPrice'
|
||||
import { useFreshQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter'
|
||||
import { useFilterFreshQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter'
|
||||
import { useRoutingAPIArguments } from 'lib/hooks/routing/useRoutingAPIArguments'
|
||||
import ms from 'ms.macro'
|
||||
import { useMemo } from 'react'
|
||||
@ -50,7 +50,7 @@ export function useRoutingAPITrade<TTradeType extends TradeType>(
|
||||
refetchOnFocus: true,
|
||||
})
|
||||
|
||||
const quoteResult: GetQuoteResult | undefined = useFreshQuote(data)
|
||||
const quoteResult: GetQuoteResult | undefined = useFilterFreshQuote(data)
|
||||
|
||||
const route = useMemo(
|
||||
() => computeRoutes(currencyIn, currencyOut, tradeType, quoteResult),
|
||||
|
Loading…
Reference in New Issue
Block a user