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:
Ian Lapham 2022-03-18 10:11:16 -07:00 committed by GitHub
parent 7d9657867d
commit e1abd81a1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 18 deletions

@ -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),