From 64fc5dbd59f25e09965ca15d5d707c7a29f38bd5 Mon Sep 17 00:00:00 2001 From: woodenfurniture <125113430+woodenfurniture@users.noreply.github.com> Date: Thu, 26 Sep 2024 12:44:46 +1000 Subject: [PATCH] fix: dont display loading state when completed quote request has no results --- .../TradeInput/components/ConfirmSummary.tsx | 20 ++++++++++++++-- src/state/slices/tradeQuoteSlice/selectors.ts | 23 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/components/MultiHopTrade/components/TradeInput/components/ConfirmSummary.tsx b/src/components/MultiHopTrade/components/TradeInput/components/ConfirmSummary.tsx index 82c6895dfdc..c6ef4e56463 100644 --- a/src/components/MultiHopTrade/components/TradeInput/components/ConfirmSummary.tsx +++ b/src/components/MultiHopTrade/components/TradeInput/components/ConfirmSummary.tsx @@ -31,7 +31,9 @@ import { selectBuyAmountAfterFeesCryptoPrecision, selectBuyAmountBeforeFeesCryptoPrecision, selectFirstHop, + selectIsAnySwapperQuoteAvailable, selectIsAnyTradeQuoteLoaded, + selectIsAnyTradeQuoteLoading, selectTotalNetworkFeeUserCurrencyPrecision, selectTotalProtocolFeeByAsset, selectTradeQuoteRequestErrors, @@ -79,6 +81,8 @@ export const ConfirmSummary = ({ const quoteResponseErrors = useAppSelector(selectTradeQuoteResponseErrors) const isAnyTradeQuoteLoaded = useAppSelector(selectIsAnyTradeQuoteLoaded) const isTradeQuoteApiQueryPending = useAppSelector(selectIsTradeQuoteApiQueryPending) + const isAnyTradeQuoteLoading = useAppSelector(selectIsAnyTradeQuoteLoading) + const isAnySwapperQuoteAvailable = useAppSelector(selectIsAnySwapperQuoteAvailable) const hasUserEnteredAmount = useAppSelector(selectHasUserEnteredAmount) const activeSwapperName = useAppSelector(selectActiveSwapperName) const sellAsset = useAppSelector(selectInputSellAsset) @@ -141,8 +145,16 @@ export const ConfirmSummary = ({ const quoteHasError = useMemo(() => { if (!isAnyTradeQuoteLoaded) return false + if (hasUserEnteredAmount && !isAnyTradeQuoteLoading && !isAnySwapperQuoteAvailable) return true return !!activeQuoteErrors?.length || !!quoteRequestErrors?.length - }, [activeQuoteErrors?.length, isAnyTradeQuoteLoaded, quoteRequestErrors?.length]) + }, [ + activeQuoteErrors?.length, + hasUserEnteredAmount, + isAnySwapperQuoteAvailable, + isAnyTradeQuoteLoaded, + isAnyTradeQuoteLoading, + quoteRequestErrors?.length, + ]) const isLoading = useMemo(() => { return isParentLoading || isReceiveAddressByteCodeLoading || !buyAssetFeeAsset @@ -202,6 +214,8 @@ export const ConfirmSummary = ({ return getQuoteRequestErrorTranslation(quoteResponseError) case !!tradeQuoteError: return getQuoteErrorTranslation(tradeQuoteError!) + case !isAnyTradeQuoteLoading && !isAnySwapperQuoteAvailable: + return 'trade.noRateAvailable' case !isConnected || isDemoWallet: // We got a happy path quote, but we may still be in the context of the demo wallet return 'common.connectWallet' @@ -212,11 +226,13 @@ export const ConfirmSummary = ({ quoteRequestErrors, quoteResponseErrors, activeQuoteErrors, + isAccountMetadataLoading, isAnyTradeQuoteLoaded, hasUserEnteredAmount, + isAnyTradeQuoteLoading, + isAnySwapperQuoteAvailable, isConnected, isDemoWallet, - isAccountMetadataLoading, ]) const handleOpenCompactQuoteList = useCallback(() => { diff --git a/src/state/slices/tradeQuoteSlice/selectors.ts b/src/state/slices/tradeQuoteSlice/selectors.ts index 090aa88ae3b..fefd6f8fbbc 100644 --- a/src/state/slices/tradeQuoteSlice/selectors.ts +++ b/src/state/slices/tradeQuoteSlice/selectors.ts @@ -118,6 +118,13 @@ const selectIsSwapperQuoteAvailable = createSelector( }, ) +export const selectIsAnySwapperQuoteAvailable = createSelector( + selectIsSwapperQuoteAvailable, + isSwapperQuoteAvailable => { + return Object.values(isSwapperQuoteAvailable).some(identity) + }, +) + // Returns the top-level errors related to the request for a trade quote. Not related to individual // quote responses. export const selectTradeQuoteRequestErrors = createDeepEqualOutputSelector( @@ -725,6 +732,18 @@ export const selectIsAnyTradeQuoteLoading = createSelector( export const selectIsAnyTradeQuoteLoaded = createSelector( selectIsSwapperQuoteAvailable, selectHasUserEnteredAmount, - (isSwapperQuoteAvailable, hasUserEnteredAmount) => - !hasUserEnteredAmount || Object.values(isSwapperQuoteAvailable).some(identity), + selectIsAnyTradeQuoteLoading, + (isSwapperQuoteAvailable, hasUserEnteredAmount, isAnyTradeQuoteLoading) => { + if (!hasUserEnteredAmount) { + return true + } + + // If we're still loading, return true if there is any quote available + if (isAnyTradeQuoteLoading) { + return Object.values(isSwapperQuoteAvailable).some(identity) + } + + // Otherwise, an empty result should default to true to allow the app to stop loading state. + return true + }, )