From ff54d023a146a6e8c46064a8244d77a66e54aca9 Mon Sep 17 00:00:00 2001 From: Louis Paquet Date: Thu, 15 Feb 2024 15:23:32 +0100 Subject: [PATCH] Bugfix/countdown timer refresh swap form (#6178) * fix(LIVE-11267): regression on analytics refreshing every 1 sec * fix(LIVE-11267): add changeset * Revert "[fix/LIVE-11122]: update quotes when timeout reaches 0 in swap. (#6118)" This reverts commit 63099cc6dc08dfde9957aeb246368252e5591ba1. * fix(LIVE-11267): remove useless files --- .changeset/brown-experts-fly.md | 6 ---- .changeset/early-turtles-join.md | 5 +++ .../Swap2/Form/FormRates/SectionRate.tsx | 9 ++++-- .../exchange/Swap2/Form/FormRates/index.tsx | 20 ++++++------ .../Swap2/Form/Migrations/SwapMigrationUI.tsx | 7 +++- .../exchange/Swap2/Form/Rates/Countdown.tsx | 31 ++++++++++++++---- .../exchange/Swap2/Form/Rates/index.tsx | 17 +++++----- .../Swap2/Form/hooks/useRefreshRates.ts | 32 +++++++++++++++++++ .../screens/exchange/Swap2/Form/index.tsx | 8 +++++ libs/ledger-live-common/package.json | 1 - .../exchange/swap/hooks/useSwapTransaction.ts | 3 +- .../swap/hooks/v5/useProviderRates.ts | 23 +------------ .../src/exchange/swap/types.ts | 1 - pnpm-lock.yaml | 13 -------- 14 files changed, 104 insertions(+), 72 deletions(-) delete mode 100644 .changeset/brown-experts-fly.md create mode 100644 .changeset/early-turtles-join.md create mode 100644 apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/hooks/useRefreshRates.ts diff --git a/.changeset/brown-experts-fly.md b/.changeset/brown-experts-fly.md deleted file mode 100644 index a4f2853a3a29..000000000000 --- a/.changeset/brown-experts-fly.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@ledgerhq/live-common": minor -"ledger-live-desktop": patch ---- - -Return countdown and refresh rates from the useProviderRates hook diff --git a/.changeset/early-turtles-join.md b/.changeset/early-turtles-join.md new file mode 100644 index 000000000000..c90c2a88a8e0 --- /dev/null +++ b/.changeset/early-turtles-join.md @@ -0,0 +1,5 @@ +--- +"ledger-live-desktop": patch +--- + +Revert counter and refresh rate changes and fix moonpay not refreshing diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/SectionRate.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/SectionRate.tsx index a2717986655f..954eded4a94e 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/SectionRate.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/SectionRate.tsx @@ -11,7 +11,8 @@ export type SectionRateProps = { ratesState: RatesReducerState; fromCurrency: SwapSelectorStateType["currency"]; toCurrency: SwapSelectorStateType["currency"]; - countdownSecondsToRefresh: number | undefined; + refreshTime: number; + countdown: boolean; }; const SectionRate = ({ @@ -19,7 +20,8 @@ const SectionRate = ({ fromCurrency, toCurrency, ratesState, - countdownSecondsToRefresh, + refreshTime, + countdown, }: SectionRateProps) => { const rates = ratesState.value; @@ -31,7 +33,8 @@ const SectionRate = ({ toCurrency, rates, provider, - countdownSecondsToRefresh, + refreshTime, + countdown, }} /> diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/index.tsx index 9ad9a7b7cc40..504dc3772d9d 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/index.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/index.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useMemo } from "react"; import styled from "styled-components"; import SectionRate from "./SectionRate"; import { SwapDataType } from "@ledgerhq/live-common/exchange/swap/types"; @@ -10,26 +10,28 @@ const Form = styled.section` `; type SwapFormProvidersProps = { swap: SwapDataType; - countdownSecondsToRefresh: number | undefined; provider?: string; + refreshTime: number; + countdown: boolean; }; -const SwapFormProviders = ({ - swap, - provider, - countdownSecondsToRefresh, -}: SwapFormProvidersProps) => { +const SwapFormProviders = ({ swap, provider, refreshTime, countdown }: SwapFormProvidersProps) => { const { currency: fromCurrency } = swap.from; const { currency: toCurrency } = swap.to; + const updatedRatesState = useMemo(() => { + return swap.rates; + }, [swap.rates]); + return (
); diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Migrations/SwapMigrationUI.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Migrations/SwapMigrationUI.tsx index 2d04ffd91f3c..d7708722e4c1 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Migrations/SwapMigrationUI.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Migrations/SwapMigrationUI.tsx @@ -22,6 +22,8 @@ type SwapMigrationUIProps = { pageState: ReturnType; swapTransaction: SwapTransactionType; provider?: string; + refreshTime: number; + countdown: boolean; // Demo 0 props disabled: boolean; onClick: () => void; @@ -35,6 +37,8 @@ export const SwapMigrationUI = (props: SwapMigrationUIProps) => { pageState, swapTransaction, provider, + refreshTime, + countdown, disabled, onClick, } = props; @@ -45,7 +49,8 @@ export const SwapMigrationUI = (props: SwapMigrationUIProps) => { ) : null; diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Countdown.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Countdown.tsx index 25742ce14284..674f1cef07e8 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Countdown.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Countdown.tsx @@ -1,21 +1,40 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { Trans } from "react-i18next"; import styled from "styled-components"; import Box from "~/renderer/components/Box"; import Text from "~/renderer/components/Text"; import AnimatedCountdown from "~/renderer/components/AnimatedCountdown"; import { formatCountdown } from "~/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown"; -import { DEFAULT_SWAP_RATES_INTERVAL_MS } from "@ledgerhq/live-common/exchange/swap/const/timeout"; +import { RatesReducerState } from "@ledgerhq/live-common/exchange/swap/types"; export type Props = { - countdown: number; + rates: RatesReducerState["value"]; + refreshTime: number; }; const CountdownText = styled(Text)` color: ${p => p.theme.colors.neutral.c70}; `; -export default function Countdown({ countdown }: Props) { +export default function Countdown({ refreshTime, rates }: Props) { + const getSeconds = (time: number) => Math.round(time / 1000); + const [countdown, setCountdown] = useState(getSeconds(refreshTime)); + const [iconKey, setIconKey] = useState(0); + + useEffect(() => { + setIconKey(key => key + 1); + const startTime = new Date().getTime(); + setCountdown(getSeconds(refreshTime)); + const countdownInterval = window.setInterval(() => { + const now = new Date().getTime(); + const newCountdown = refreshTime + startTime - now; + setCountdown(getSeconds(newCountdown)); + }, 1000); + return () => { + clearInterval(countdownInterval); + }; + }, [rates, refreshTime]); + return ( <> {countdown >= 0 ? ( @@ -23,8 +42,8 @@ export default function Countdown({ countdown }: Props) { - - + + (null); const selectedRate = useSelector(rateSelector); const filteredRates = useMemo(() => filterRates(rates, filter), [rates, filter]); - const providers = useMemo(() => [...new Set(rates?.map(rate => rate.provider) ?? [])], [rates]); - const exchangeRates = useMemo(() => { - return toCurrency && rates + const providers = [...new Set(rates?.map(rate => rate.provider) ?? [])]; + const exchangeRates = + toCurrency && rates ? rates.map(({ toAmount }) => formatCurrencyUnit(getFeesUnit(toCurrency), toAmount)) : []; - }, [toCurrency, rates]); const updateRate = useCallback( (rate: ExchangeRate) => { const value = rate.rate ?? rate.provider; @@ -146,9 +147,9 @@ export default function ProviderRate({ > - {countdownSecondsToRefresh && ( + {countdown && ( - + )} diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/hooks/useRefreshRates.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/hooks/useRefreshRates.ts new file mode 100644 index 000000000000..631c91dc3dc4 --- /dev/null +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/hooks/useRefreshRates.ts @@ -0,0 +1,32 @@ +import { useRef, useEffect } from "react"; +import { SwapDataType } from "@ledgerhq/live-common/exchange/swap/types"; +import { DEFAULT_SWAP_RATES_INTERVAL_MS } from "@ledgerhq/live-common/exchange/swap/const/timeout"; + +const useRefreshRates = ( + swap: SwapDataType, + { + pause, + }: { + pause: boolean; + }, +) => { + const refreshInterval = useRef(); + const refreshTime = DEFAULT_SWAP_RATES_INTERVAL_MS; + + useEffect(() => { + clearTimeout(refreshInterval.current); + refreshInterval.current = setTimeout(() => { + if (!pause) { + swap.refetchRates(); + } + }, refreshTime); + return () => { + clearTimeout(refreshInterval.current); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [pause, refreshTime, swap.rates?.value]); + + return refreshTime; +}; + +export default useRefreshRates; diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/index.tsx index ec14baa8e73d..41d3f6f9a146 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/index.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/index.tsx @@ -26,6 +26,7 @@ import ExchangeDrawer from "./ExchangeDrawer/index"; import SwapFormSelectors from "./FormSelectors"; import useFeature from "@ledgerhq/live-common/featureFlags/useFeature"; import { accountToWalletAPIAccount } from "@ledgerhq/live-common/wallet-api/converters"; +import useRefreshRates from "./hooks/useRefreshRates"; import LoadingState from "./Rates/LoadingState"; import EmptyState from "./Rates/EmptyState"; import { AccountLike } from "@ledgerhq/types-live"; @@ -123,6 +124,11 @@ const SwapForm = () => { ); const { setDrawer } = React.useContext(context); + const pauseRefreshing = !!swapError || idleState; + const refreshTime = useRefreshRates(swapTransaction.swap, { + pause: pauseRefreshing, + }); + const getExchangeSDKParams = useCallback(() => { const { swap, transaction } = swapTransaction; const { to, from } = swap; @@ -462,6 +468,8 @@ const SwapForm = () => { pageState={pageState} swapTransaction={swapTransaction} provider={provider} + refreshTime={refreshTime} + countdown={!pauseRefreshing} // Demo 0 props disabled={!isSwapReady} onClick={onSubmit} diff --git a/libs/ledger-live-common/package.json b/libs/ledger-live-common/package.json index 9d678ac84e71..0e870399b47c 100644 --- a/libs/ledger-live-common/package.json +++ b/libs/ledger-live-common/package.json @@ -244,7 +244,6 @@ "thor-devkit": "^2.0.6", "triple-beam": "^1.3.0", "tronweb": "^5.2.0", - "usehooks-ts": "^2.13.0", "utility-types": "^3.10.0", "varuint-bitcoin": "1.1.2", "winston": "^3.4.0", diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts b/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts index 843a1c9150d6..0152039b01b9 100644 --- a/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts +++ b/libs/ledger-live-common/src/exchange/swap/hooks/useSwapTransaction.ts @@ -154,7 +154,7 @@ export const useSwapTransaction = ({ bridge: bridgeTransaction, }); - const { rates, refetchRates, updateSelectedRate, countdown } = useProviderRates({ + const { rates, refetchRates, updateSelectedRate } = useProviderRates({ fromState, toState, onNoRates, @@ -176,7 +176,6 @@ export const useSwapTransaction = ({ value: rates.value.filter(v => v.tradeMethod !== "fixed"), } : rates, - countdown, refetchRates, updateSelectedRate, targetAccounts, diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/v5/useProviderRates.ts b/libs/ledger-live-common/src/exchange/swap/hooks/v5/useProviderRates.ts index 3b5817c25c01..847b69f6304e 100644 --- a/libs/ledger-live-common/src/exchange/swap/hooks/v5/useProviderRates.ts +++ b/libs/ledger-live-common/src/exchange/swap/hooks/v5/useProviderRates.ts @@ -3,9 +3,7 @@ import { OnNoRatesCallback, RatesReducerState, SwapSelectorStateType } from "../ import { useFetchRates } from "./useFetchRates"; import { SetExchangeRateCallback } from "../useSwapTransaction"; import { useFeature } from "../../../../featureFlags"; -import { useCallback, useEffect } from "react"; -import { useCountdown } from "usehooks-ts"; -import { DEFAULT_SWAP_RATES_INTERVAL_MS } from "../../const/timeout"; +import { useCallback } from "react"; type Props = { fromState: SwapSelectorStateType; @@ -18,7 +16,6 @@ export type UseProviderRatesResponse = { rates: RatesReducerState; refetchRates(): void; updateSelectedRate(): void; - countdown: undefined | number; }; export function useProviderRates({ @@ -27,10 +24,6 @@ export function useProviderRates({ onNoRates, setExchangeRate, }: Props): UseProviderRatesResponse { - const [countdown, { startCountdown, resetCountdown, stopCountdown }] = useCountdown({ - countStart: DEFAULT_SWAP_RATES_INTERVAL_MS / 1000, - countStop: 0, - }); const ptxSwapMoonpayProviderFlag = useFeature("ptxSwapMoonpayProvider"); const filterMoonpay = useCallback( rates => { @@ -45,24 +38,15 @@ export function useProviderRates({ toCurrency: toState.currency, fromCurrencyAmount: fromState.amount ?? BigNumber(0), onSuccess(data) { - resetCountdown(); const rates = filterMoonpay(data); if (rates.length === 0) { - stopCountdown(); onNoRates?.({ fromState, toState }); } else { - startCountdown(); setExchangeRate?.(rates[0]); } }, }); - useEffect(() => { - if (countdown <= 0) { - refetch(); - } - }, [countdown, refetch]); - if (!fromState.amount || fromState.amount.lte(0)) { setExchangeRate?.(undefined); return { @@ -73,7 +57,6 @@ export function useProviderRates({ }, refetchRates: () => undefined, updateSelectedRate: () => undefined, - countdown: undefined, }; } @@ -87,7 +70,6 @@ export function useProviderRates({ }, refetchRates: () => undefined, updateSelectedRate: () => undefined, - countdown: undefined, }; } if (error) { @@ -100,7 +82,6 @@ export function useProviderRates({ }, refetchRates: () => undefined, updateSelectedRate: () => undefined, - countdown: undefined, }; } @@ -113,7 +94,6 @@ export function useProviderRates({ }, refetchRates: refetch, updateSelectedRate: () => undefined, - countdown, }; } @@ -125,6 +105,5 @@ export function useProviderRates({ }, refetchRates: () => undefined, updateSelectedRate: () => undefined, - countdown: undefined, }; } diff --git a/libs/ledger-live-common/src/exchange/swap/types.ts b/libs/ledger-live-common/src/exchange/swap/types.ts index 32aa9b6800cb..1caa9404b379 100644 --- a/libs/ledger-live-common/src/exchange/swap/types.ts +++ b/libs/ledger-live-common/src/exchange/swap/types.ts @@ -322,7 +322,6 @@ export type SwapDataType = { refetchRates: () => void; updateSelectedRate: (selected?: ExchangeRate) => void; targetAccounts?: Account[]; - countdown: undefined | number; }; export type SwapTransactionType = UseBridgeTransactionResult & { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f08ebf5b721a..bf3e18216ccb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2441,9 +2441,6 @@ importers: tronweb: specifier: ^5.2.0 version: 5.2.0 - usehooks-ts: - specifier: ^2.13.0 - version: 2.13.0(react@18.2.0) utility-types: specifier: ^3.10.0 version: 3.10.0 @@ -56110,16 +56107,6 @@ packages: requiresBuild: true dev: true - /usehooks-ts@2.13.0(react@18.2.0): - resolution: {integrity: sha512-3yZ2dwbc5BTaejBvamckAqv/q29sKFeqNCdi1z9Im4GzsTT5XbdIdbB94KEoh9xSvZy/qRoztjR14pF5voEU5Q==} - engines: {node: '>=16.15.0'} - peerDependencies: - react: ^16.8.0 || ^17 || ^18 - dependencies: - lodash.debounce: 4.0.8 - react: 18.2.0 - dev: false - /utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==, tarball: https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz} engines: {node: '>=6.14.2'}