diff --git a/src/components/FeeComparison/index.tsx b/src/components/FeeComparison/index.tsx index 135da6d7..585e9e75 100644 --- a/src/components/FeeComparison/index.tsx +++ b/src/components/FeeComparison/index.tsx @@ -1,6 +1,5 @@ import Big from 'big.js'; -import { useMemo } from 'preact/hooks'; -import { useEffect, useRef } from 'preact/compat'; +import { useEffect, useRef, useMemo } from 'preact/hooks'; import { useQuery } from '@tanstack/react-query'; import { ChevronDownIcon } from '@heroicons/react/20/solid'; @@ -10,12 +9,21 @@ import { Skeleton } from '../Skeleton'; import { QuoteProvider, quoteProviders } from './quoteProviders'; import { OfframpingParameters, useEventsContext } from '../../contexts/events'; -type FeeProviderRowProps = FeeComparisonProps & { provider: QuoteProvider }; +interface BaseComparisonProps { + amount: Big; + sourceAssetSymbol: string; + targetAssetSymbol: string; + vortexPrice: Big; + network: Networks; +} -function VortexRow({ - targetAssetSymbol, - vortexPrice, -}: Omit) { +interface FeeComparisonProps extends BaseComparisonProps { + enabled: boolean; +} + +type VortexRowProps = Pick; + +function VortexRow({ targetAssetSymbol, vortexPrice }: VortexRowProps) { return (
@@ -23,13 +31,17 @@ function VortexRow({
- {vortexPrice.toFixed(2) + ' ' + targetAssetSymbol} + {`${vortexPrice.toFixed(2)} ${targetAssetSymbol}`}
); } +interface FeeProviderRowProps extends BaseComparisonProps { + provider: QuoteProvider; +} + function FeeProviderRow({ provider, amount, @@ -39,6 +51,9 @@ function FeeProviderRow({ network, }: FeeProviderRowProps) { const { scheduleQuote } = useEventsContext(); + // The vortex price is sometimes lagging behind the amount (as it first has to be calculated asynchronously) + // We keep a reference to the previous vortex price to avoid spamming the server with the same quote. + const prevVortexPrice = useRef(); const { isLoading, @@ -49,31 +64,26 @@ function FeeProviderRow({ queryFn: () => provider.query(sourceAssetSymbol, targetAssetSymbol, amount, network), retry: false, // We don't want to retry the request to avoid spamming the server }); - // The vortex price is sometimes lagging behind the amount (as it first has to be calculated asynchronously) - // We keep a reference to the previous vortex price to avoid spamming the server with the same quote. - const prevVortexPrice = useRef(undefined); const priceDiff = useMemo(() => { - if (isLoading || error || !providerPrice) { - return undefined; - } - + if (isLoading || error || !providerPrice) return undefined; return providerPrice.minus(vortexPrice); }, [isLoading, error, providerPrice, vortexPrice]); useEffect(() => { - if (!isLoading && (providerPrice || error)) { - const parameters: OfframpingParameters = { - from_amount: amount.toFixed(2), - from_asset: sourceAssetSymbol, - to_amount: vortexPrice.toFixed(2), - to_asset: targetAssetSymbol, - }; - if (!prevVortexPrice.current || vortexPrice !== prevVortexPrice.current) { - scheduleQuote(provider.name, providerPrice ? providerPrice.toFixed(2, 0) : '-1', parameters); - prevVortexPrice.current = vortexPrice; - } - } + if (isLoading || (!providerPrice && !error)) return; + + const parameters: OfframpingParameters = { + from_amount: amount.toFixed(2), + from_asset: sourceAssetSymbol, + to_amount: vortexPrice.toFixed(2), + to_asset: targetAssetSymbol, + }; + + if (prevVortexPrice.current?.eq(vortexPrice)) return; + + scheduleQuote(provider.name, providerPrice ? providerPrice.toFixed(2, 0) : '-1', parameters); + prevVortexPrice.current = vortexPrice; }, [ amount, provider.name, @@ -97,12 +107,12 @@ function FeeProviderRow({ ) : (
- {error || !providerPrice ? 'N/A' : providerPrice.toFixed(2) + ' ' + targetAssetSymbol} + {error || !providerPrice ? 'N/A' : `${providerPrice.toFixed(2)} ${targetAssetSymbol}`} {priceDiff && ( - {priceDiff.toFixed(2)}{' '} - {targetAssetSymbol} + + {`${priceDiff.toFixed(2)} ${targetAssetSymbol}`} )}
@@ -112,15 +122,9 @@ function FeeProviderRow({ ); } -type FeeComparisonTableProps = FeeComparisonProps; +function FeeComparisonTable(props: BaseComparisonProps) { + const { amount, sourceAssetSymbol, network, targetAssetSymbol, vortexPrice } = props; -function FeeComparisonTable({ - amount, - sourceAssetSymbol, - targetAssetSymbol, - vortexPrice, - network, -}: FeeComparisonTableProps) { return (
@@ -146,42 +150,41 @@ function FeeComparisonTable({
- - {quoteProviders.map((provider, index) => ( - <> + + {quoteProviders.map((provider) => ( +
- - + +
))}
); } -interface FeeComparisonProps { - amount: Big; - sourceAssetSymbol: string; - targetAssetSymbol: string; - vortexPrice: Big; - network: Networks; -} +export function FeeComparison({ enabled, ...props }: FeeComparisonProps) { + const feeComparisonRef = useRef(null); + + useEffect(() => { + if (!enabled) return; + if (!feeComparisonRef.current) return; + + const timer = setTimeout(() => { + window.scrollTo({ + top: feeComparisonRef.current!.offsetTop, + behavior: 'smooth', + }); + }, 300); + + return () => clearTimeout(timer); + }, [enabled]); + + if (!enabled) return null; -export function FeeComparison({ - amount, - sourceAssetSymbol, - targetAssetSymbol, - vortexPrice, - network, -}: FeeComparisonProps) { return ( -
+

Save on exchange rate markups

@@ -190,13 +193,7 @@ export function FeeComparison({

At Vortex, we’ll never do that and show our fees upfront.

- +
); } diff --git a/src/pages/swap/index.tsx b/src/pages/swap/index.tsx index 962e9f39..afbd8c9d 100644 --- a/src/pages/swap/index.tsx +++ b/src/pages/swap/index.tsx @@ -426,10 +426,6 @@ export const SwapPage = () => { onClick={(e) => { e.preventDefault(); setShowCompareFees(!showCompareFees); - // Smooth scroll to bottom of page - setTimeout(() => { - window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); - }, 300); }} > Compare fees @@ -466,6 +462,7 @@ export const SwapPage = () => { targetAssetSymbol={toToken.fiat.symbol} vortexPrice={vortexPrice} network={selectedNetwork} + enabled={showCompareFees} /> )}