From 285778797e10c1a9d6d97bd8239120f5c5a6ce36 Mon Sep 17 00:00:00 2001 From: memoyil <2213635+memoyil@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:33:11 +0100 Subject: [PATCH] fix: Back button not working after url changed by swap or query added (#10903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To reproduce: Go to swap Change tokens that will change the url Go to another page using menu Use back button to go back (not working) --- ## PR-Codex overview This PR focuses on refactoring the `replaceBrowserHistory` functionality to use `replaceBrowserHistoryMultiple`, allowing for multiple URL parameter updates in a single call. This enhances code readability and performance by consolidating history state updates. ### Detailed summary - Introduced `replaceBrowserHistoryMultiple` in `replaceBrowserHistoryMultiple.ts`. - Updated `replaceBrowserHistory` to handle undefined or null values using `isUndefinedOrNull`. - Replaced instances of `replaceBrowserHistory` with `replaceBrowserHistoryMultiple` across multiple components. - Enhanced URL state management in various files, including `FlipButton.tsx`, `FormMain.tsx`, and `Twap.tsx`, to handle multiple parameters efficiently. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` --- .../components/SearchModal/ManageTokens.tsx | 10 +++++-- apps/aptos/pages/swap.tsx | 28 ++++++++++--------- apps/web/src/views/LimitOrders/index.tsx | 24 ++++++++-------- apps/web/src/views/Swap/Twap/Twap.tsx | 10 +++---- .../Swap/V3Swap/containers/FlipButton.tsx | 8 ++++-- .../views/Swap/V3Swap/containers/FormMain.tsx | 10 +++---- .../views/SwapSimplify/V4Swap/FlipButton.tsx | 9 ++++-- .../views/SwapSimplify/V4Swap/FormMainV4.tsx | 10 +++---- packages/utils/replaceBrowserHistory.ts | 7 +++-- .../utils/replaceBrowserHistoryMultiple.ts | 18 ++++++++++++ 10 files changed, 84 insertions(+), 50 deletions(-) create mode 100644 packages/utils/replaceBrowserHistoryMultiple.ts diff --git a/apps/aptos/components/SearchModal/ManageTokens.tsx b/apps/aptos/components/SearchModal/ManageTokens.tsx index 65f711aa30cd8..333cd52191ba4 100644 --- a/apps/aptos/components/SearchModal/ManageTokens.tsx +++ b/apps/aptos/components/SearchModal/ManageTokens.tsx @@ -18,7 +18,7 @@ import { RowFixed, Text, } from '@pancakeswap/uikit' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import { CoinRegisterButton } from 'components/CoinRegisterButton' import { CurrencyLogo } from 'components/Logo' import { L0_USDC } from 'config/coins' @@ -97,13 +97,17 @@ export default function ManageTokens({ const clearQuery = useCallback( (address: string) => { if (query.inputCurrency === address || INPUT.currencyId === address) { - replaceBrowserHistory('inputCurrency', APTOS_COIN) dispatch(selectCurrency({ field: Field.INPUT, currencyId: APTOS_COIN })) } if (query.outputCurrency === address || OUTPUT.currencyId === address) { - replaceBrowserHistory('outputCurrency', L0_USDC[chainId]?.address) dispatch(selectCurrency({ field: Field.OUTPUT, currencyId: L0_USDC[chainId]?.address })) } + replaceBrowserHistoryMultiple({ + ...((query.inputCurrency === address || INPUT.currencyId === address) && { inputCurrency: APTOS_COIN }), + ...((query.outputCurrency === address || OUTPUT.currencyId === address) && { + outputCurrency: L0_USDC[chainId]?.address, + }), + }) }, [INPUT.currencyId, OUTPUT.currencyId, chainId, dispatch, query.inputCurrency, query.outputCurrency], ) diff --git a/apps/aptos/pages/swap.tsx b/apps/aptos/pages/swap.tsx index 022de0d5f7f2c..421273d06525f 100644 --- a/apps/aptos/pages/swap.tsx +++ b/apps/aptos/pages/swap.tsx @@ -28,7 +28,7 @@ import { import { Swap as SwapUI, useAsyncConfirmPriceImpactWithoutFee } from '@pancakeswap/widgets-internal' import { useQuery } from '@tanstack/react-query' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import tryParseAmount from '@pancakeswap/utils/tryParseAmount' import { useUserSlippage } from '@pancakeswap/utils/user' import { useIsExpertMode } from '@pancakeswap/utils/user/expertMode' @@ -292,12 +292,12 @@ const SwapPage = () => { (currency: Currency) => { shouldShowWarningModal(currency) - if (outputCurrency?.wrapped.equals(currency.wrapped) && inputCurrency) { - replaceBrowserHistory('outputCurrency', currencyId(inputCurrency)) - } - + replaceBrowserHistoryMultiple({ + ...(outputCurrency?.wrapped.equals(currency.wrapped) && + inputCurrency && { outputCurrency: currencyId(inputCurrency) }), + inputCurrency: currencyId(currency), + }) dispatch(selectCurrency({ field: Field.INPUT, currencyId: currency.wrapped.address })) - replaceBrowserHistory('inputCurrency', currencyId(currency)) }, [dispatch, inputCurrency, outputCurrency?.wrapped, shouldShowWarningModal], ) @@ -306,20 +306,22 @@ const SwapPage = () => { (currency: Currency) => { shouldShowWarningModal(currency) - if (inputCurrency?.wrapped.equals(currency.wrapped) && outputCurrency) { - replaceBrowserHistory('inputCurrency', currencyId(outputCurrency)) - } - + replaceBrowserHistoryMultiple({ + ...(inputCurrency?.wrapped.equals(currency.wrapped) && + outputCurrency && { inputCurrency: currencyId(outputCurrency) }), + outputCurrency: currencyId(currency), + }) dispatch(selectCurrency({ field: Field.OUTPUT, currencyId: currency.wrapped.address })) - replaceBrowserHistory('outputCurrency', currencyId(currency)) }, [dispatch, inputCurrency?.wrapped, outputCurrency, shouldShowWarningModal], ) const handleSwitch = useCallback(() => { dispatch(switchCurrencies()) - replaceBrowserHistory('inputCurrency', outputCurrencyId) - replaceBrowserHistory('outputCurrency', inputCurrencyId) + replaceBrowserHistoryMultiple({ + inputCurrency: outputCurrencyId, + outputCurrency: inputCurrencyId, + }) }, [dispatch, inputCurrencyId, outputCurrencyId]) const handleAcceptChanges = useCallback(() => { diff --git a/apps/web/src/views/LimitOrders/index.tsx b/apps/web/src/views/LimitOrders/index.tsx index d4fd99997e701..68736dc89ea7e 100644 --- a/apps/web/src/views/LimitOrders/index.tsx +++ b/apps/web/src/views/LimitOrders/index.tsx @@ -3,7 +3,7 @@ import { Currency, CurrencyAmount, Percent, Token, Trade, TradeType } from '@pan import { AutoColumn, BottomDrawer, Box, Button, Flex, Link, useMatchBreakpoints, useModal } from '@pancakeswap/uikit' import { Swap as SwapUI } from '@pancakeswap/widgets-internal' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import AccessRisk from 'components/AccessRisk' import { ACCESS_TOKEN_SUPPORT_CHAIN_IDS } from 'components/AccessRisk/config/supportedChains' import { AppBody } from 'components/App' @@ -145,10 +145,10 @@ const LimitOrders = () => { handleCurrencySelection(Field.INPUT, newInputCurrency) const newInputCurrencyId = currencyId(newInputCurrency) - if (newInputCurrencyId === currencyIds.output) { - replaceBrowserHistory('outputCurrency', currencyIds.input) - } - replaceBrowserHistory('inputCurrency', newInputCurrencyId) + replaceBrowserHistoryMultiple({ + ...(newInputCurrencyId === currencyIds.output && { outputCurrency: currencyIds.input }), + inputCurrency: newInputCurrencyId, + }) }, [currencyIds.input, currencyIds.output, handleCurrencySelection], ) @@ -176,10 +176,10 @@ const LimitOrders = () => { handleCurrencySelection(Field.OUTPUT, newOutputCurrency) const newOutputCurrencyId = currencyId(newOutputCurrency) - if (newOutputCurrencyId === currencyIds.input) { - replaceBrowserHistory('inputCurrency', currencyIds.output) - } - replaceBrowserHistory('outputCurrency', newOutputCurrencyId) + replaceBrowserHistoryMultiple({ + ...(newOutputCurrencyId === currencyIds.input && { inputCurrency: currencyIds.output }), + outputCurrency: newOutputCurrencyId, + }) }, [currencyIds.input, currencyIds.output, handleCurrencySelection], ) @@ -275,8 +275,10 @@ const LimitOrders = () => { const handleTokenSwitch = useCallback(() => { setApprovalSubmitted(false) handleSwitchTokens() - replaceBrowserHistory('inputCurrency', currencyIds.output) - replaceBrowserHistory('outputCurrency', currencyIds.input) + replaceBrowserHistoryMultiple({ + inputCurrency: currencyIds.output, + outputCurrency: currencyIds.input, + }) }, [handleSwitchTokens, currencyIds.output, currencyIds.input]) const { realExecutionPriceAsString } = useGasOverhead(parsedAmounts.input, parsedAmounts.output, rateType) diff --git a/apps/web/src/views/Swap/Twap/Twap.tsx b/apps/web/src/views/Swap/Twap/Twap.tsx index 9f7ff8591009c..eeddb4d33debb 100644 --- a/apps/web/src/views/Swap/Twap/Twap.tsx +++ b/apps/web/src/views/Swap/Twap/Twap.tsx @@ -25,7 +25,7 @@ import { useModal, useTooltip, } from '@pancakeswap/uikit' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import truncateHash from '@pancakeswap/utils/truncateHash' import { useUserSingleHopOnly } from '@pancakeswap/utils/user' import { ApproveModalContentV1, Swap, SwapTransactionReceiptModalContentV1 } from '@pancakeswap/widgets-internal' @@ -154,10 +154,10 @@ export function TWAPPanel({ limit }: { limit?: boolean }) { const oldCurrencyId = isInput ? inputCurrencyId : outputCurrencyId const otherCurrencyId = isInput ? outputCurrencyId : inputCurrencyId const newCurrencyId = currencyId(newCurrency) - if (newCurrencyId === otherCurrencyId) { - replaceBrowserHistory(isInput ? 'outputCurrency' : 'inputCurrency', oldCurrencyId) - } - replaceBrowserHistory(isInput ? 'inputCurrency' : 'outputCurrency', newCurrencyId) + replaceBrowserHistoryMultiple({ + ...(newCurrencyId === otherCurrencyId && { [isInput ? 'outputCurrency' : 'inputCurrency']: oldCurrencyId }), + [isInput ? 'inputCurrency' : 'outputCurrency']: newCurrencyId, + }) }, [onCurrencySelection, warningSwapHandler, inputCurrencyId, outputCurrencyId], ) diff --git a/apps/web/src/views/Swap/V3Swap/containers/FlipButton.tsx b/apps/web/src/views/Swap/V3Swap/containers/FlipButton.tsx index c67bd1ceb2598..c75951f61a119 100644 --- a/apps/web/src/views/Swap/V3Swap/containers/FlipButton.tsx +++ b/apps/web/src/views/Swap/V3Swap/containers/FlipButton.tsx @@ -2,7 +2,7 @@ import { AutoColumn, Button } from '@pancakeswap/uikit' import { Swap as SwapUI } from '@pancakeswap/widgets-internal' import { useCallback, memo } from 'react' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import { useTranslation } from '@pancakeswap/localization' import { useExpertMode } from '@pancakeswap/utils/user' @@ -26,8 +26,10 @@ export const FlipButton = memo(function FlipButton() { const onFlip = useCallback(() => { onSwitchTokens() - replaceBrowserHistory('inputCurrency', outputCurrencyId) - replaceBrowserHistory('outputCurrency', inputCurrencyId) + replaceBrowserHistoryMultiple({ + inputCurrency: outputCurrencyId, + outputCurrency: inputCurrencyId, + }) }, [onSwitchTokens, inputCurrencyId, outputCurrencyId]) return ( diff --git a/apps/web/src/views/Swap/V3Swap/containers/FormMain.tsx b/apps/web/src/views/Swap/V3Swap/containers/FormMain.tsx index 51ce4657776f5..3462a1f73f834 100644 --- a/apps/web/src/views/Swap/V3Swap/containers/FormMain.tsx +++ b/apps/web/src/views/Swap/V3Swap/containers/FormMain.tsx @@ -1,7 +1,7 @@ import { useTranslation } from '@pancakeswap/localization' import { Currency, CurrencyAmount, Percent } from '@pancakeswap/sdk' import { formatAmount } from '@pancakeswap/utils/formatFractions' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import { ReactNode, useCallback, useMemo } from 'react' import CurrencyInputPanel from 'components/CurrencyInputPanel' @@ -80,10 +80,10 @@ export function FormMain({ pricingAndSlippage, inputAmount, outputAmount, tradeL const oldCurrencyId = isInput ? currentInputCurrencyId : currentOutputCurrencyId const otherCurrencyId = isInput ? currentOutputCurrencyId : currentInputCurrencyId const newCurrencyId = currencyId(newCurrency) - if (newCurrencyId === otherCurrencyId) { - replaceBrowserHistory(isInput ? 'outputCurrency' : 'inputCurrency', oldCurrencyId) - } - replaceBrowserHistory(isInput ? 'inputCurrency' : 'outputCurrency', newCurrencyId) + replaceBrowserHistoryMultiple({ + ...(newCurrencyId === otherCurrencyId && { [isInput ? 'outputCurrency' : 'inputCurrency']: oldCurrencyId }), + [isInput ? 'inputCurrency' : 'outputCurrency']: newCurrencyId, + }) }, [onCurrencySelection, warningSwapHandler], ) diff --git a/apps/web/src/views/SwapSimplify/V4Swap/FlipButton.tsx b/apps/web/src/views/SwapSimplify/V4Swap/FlipButton.tsx index 4f713b490ff81..5523396516b00 100644 --- a/apps/web/src/views/SwapSimplify/V4Swap/FlipButton.tsx +++ b/apps/web/src/views/SwapSimplify/V4Swap/FlipButton.tsx @@ -1,7 +1,7 @@ import { AutoColumn, Button } from '@pancakeswap/uikit' import { useTranslation } from '@pancakeswap/localization' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import { memo, useCallback } from 'react' import { AutoRow } from 'components/Layout/Row' @@ -11,6 +11,7 @@ import { useSwapActionHandlers } from 'state/swap/useSwapActionHandlers' import { styled } from 'styled-components' import { SwapUIV2 } from '@pancakeswap/widgets-internal' +import { useRouter } from 'next/router' import { useAllowRecipient } from '../../Swap/V3Swap/hooks' export const Line = styled.div` @@ -33,8 +34,10 @@ export const FlipButton = memo(function FlipButton() { const onFlip = useCallback(() => { onSwitchTokens() - replaceBrowserHistory('inputCurrency', outputCurrencyId) - replaceBrowserHistory('outputCurrency', inputCurrencyId) + replaceBrowserHistoryMultiple({ + inputCurrency: outputCurrencyId, + outputCurrency: inputCurrencyId, + }) }, [onSwitchTokens, inputCurrencyId, outputCurrencyId]) return ( diff --git a/apps/web/src/views/SwapSimplify/V4Swap/FormMainV4.tsx b/apps/web/src/views/SwapSimplify/V4Swap/FormMainV4.tsx index ff34ad71eefd8..862b23eb21e47 100644 --- a/apps/web/src/views/SwapSimplify/V4Swap/FormMainV4.tsx +++ b/apps/web/src/views/SwapSimplify/V4Swap/FormMainV4.tsx @@ -2,7 +2,7 @@ import { useTranslation } from '@pancakeswap/localization' import { Currency, CurrencyAmount, Percent } from '@pancakeswap/sdk' import { Text } from '@pancakeswap/uikit' import { formatAmount } from '@pancakeswap/utils/formatFractions' -import replaceBrowserHistory from '@pancakeswap/utils/replaceBrowserHistory' +import replaceBrowserHistoryMultiple from '@pancakeswap/utils/replaceBrowserHistoryMultiple' import { ReactNode, useCallback, useMemo } from 'react' import CurrencyInputPanelSimplify from 'components/CurrencyInputPanelSimplify' @@ -81,10 +81,10 @@ export function FormMain({ inputAmount, outputAmount, tradeLoading, isUserInsuff const oldCurrencyId = isInput ? currentInputCurrencyId : currentOutputCurrencyId const otherCurrencyId = isInput ? currentOutputCurrencyId : currentInputCurrencyId const newCurrencyId = currencyId(newCurrency) - if (newCurrencyId === otherCurrencyId) { - replaceBrowserHistory(isInput ? 'outputCurrency' : 'inputCurrency', oldCurrencyId) - } - replaceBrowserHistory(isInput ? 'inputCurrency' : 'outputCurrency', newCurrencyId) + replaceBrowserHistoryMultiple({ + ...(newCurrencyId === otherCurrencyId && { [isInput ? 'outputCurrency' : 'inputCurrency']: oldCurrencyId }), + [isInput ? 'inputCurrency' : 'outputCurrency']: newCurrencyId, + }) }, [onCurrencySelection, warningSwapHandler], ) diff --git a/packages/utils/replaceBrowserHistory.ts b/packages/utils/replaceBrowserHistory.ts index 68dd85ee7d74f..4ce849ec18601 100644 --- a/packages/utils/replaceBrowserHistory.ts +++ b/packages/utils/replaceBrowserHistory.ts @@ -1,11 +1,14 @@ +import isUndefinedOrNull from './isUndefinedOrNull' + const replaceBrowserHistory = (key: string, value?: string | number | null) => { const url = new URL(window.location.href) - if (!value) { + if (isUndefinedOrNull(value)) { url.searchParams.delete(key) } else { url.searchParams.set(key, String(value)) } - window.history.replaceState({}, '', url) + const urlString = url.toString() + window.history.replaceState({ ...window.history.state, as: urlString, url: urlString }, '', url) } export default replaceBrowserHistory diff --git a/packages/utils/replaceBrowserHistoryMultiple.ts b/packages/utils/replaceBrowserHistoryMultiple.ts new file mode 100644 index 0000000000000..469bb881eeffc --- /dev/null +++ b/packages/utils/replaceBrowserHistoryMultiple.ts @@ -0,0 +1,18 @@ +import isUndefinedOrNull from './isUndefinedOrNull' + +const replaceBrowserHistoryMultiple = (params: { [key: string]: string | number | null | undefined }) => { + const url = new URL(window.location.href) + + Object.entries(params).forEach(([key, value]) => { + if (isUndefinedOrNull(value)) { + url.searchParams.delete(key) + } else { + url.searchParams.set(key, String(value)) + } + }) + + const urlString = url.toString() + window.history.replaceState({ ...window.history.state, as: urlString, url: urlString }, '', url) +} + +export default replaceBrowserHistoryMultiple