Commit 2a7b1e7f authored by Sam Chen's avatar Sam Chen Committed by GitHub

chore: upgrade react-router-dom to v6 (#4143)

* chore: upgrade react-router-dom to v6

* migrate Redirect to Navigate

* use Routes instead of Switch

* migrate useHistory to useNavigate

* use To type

* use element

* work around activeClassName

* fix typing for useParams

* deduplicate

* fix Navigate

* add e2e tests

* visit /swap directly
Co-authored-by: default avatarVignesh Mohankumar <me@vig.xyz>
parent 8836ae19
describe('Redirect', () => {
it('should redirect to /vote/create-proposal when visiting /create-proposal', () => {
cy.visit('/create-proposal')
cy.url().should('match', /\/vote\/create-proposal/)
})
it('should redirect to /swap when visiting nonexist url', () => {
cy.visit('/none-exist-url')
cy.url().should('match', /\/swap/)
})
})
......@@ -2,7 +2,7 @@ import { TEST_ADDRESS_NEVER_USE_SHORTENED } from '../support/ethereum'
describe('Wallet', () => {
before(() => {
cy.visit('/')
cy.visit('/swap')
})
it('displays account details', () => {
......
......@@ -9,7 +9,7 @@ import { darken } from 'polished'
import { ParsedQs } from 'qs'
import { useCallback, useEffect, useRef, useState } from 'react'
import { AlertTriangle, ArrowDownCircle, ChevronDown } from 'react-feather'
import { useHistory } from 'react-router-dom'
import { useLocation, useNavigate } from 'react-router-dom'
import { useCloseModal, useModalIsOpen, useOpenModal, useToggleModal } from 'state/application/hooks'
import { addPopup, ApplicationModal } from 'state/application/reducer'
import { updateConnectionError } from 'state/connection/reducer'
......@@ -319,7 +319,8 @@ export default function NetworkSelector() {
const urlChainId = getParsedChainId(parsedQs)
const previousUrlChainId = usePrevious(urlChainId)
const history = useHistory()
const navigate = useNavigate()
const { search } = useLocation()
const node = useRef<HTMLDivElement>(null)
const isOpen = useModalIsOpen(ApplicationModal.NETWORK_SELECTOR)
......@@ -331,9 +332,9 @@ export default function NetworkSelector() {
const replaceURLChainParam = useCallback(() => {
if (chainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
navigate({ search: replaceURLParam(search, 'chain', getChainNameFromId(chainId)) }, { replace: true })
}
}, [chainId, history])
}, [chainId, search, navigate])
const onSelectChain = useCallback(
async (targetChain: SupportedChainId, skipClose?: boolean) => {
......
......@@ -5,7 +5,7 @@ import { getChainInfoOrDefault } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import useTheme from 'hooks/useTheme'
import { darken } from 'polished'
import { NavLink } from 'react-router-dom'
import { NavLink, useLocation } from 'react-router-dom'
import { Text } from 'rebass'
import { useShowClaimPopup, useToggleSelfClaimModal } from 'state/application/hooks'
import { useUserHasAvailableClaim } from 'state/claim/hooks'
......@@ -185,11 +185,11 @@ const UniIcon = styled.div`
position: relative;
`
const activeClassName = 'ACTIVE'
// can't be customized under react-router-dom v6
// so we have to persist to the default one, i.e., .active
const activeClassName = 'active'
const StyledNavLink = styled(NavLink).attrs({
activeClassName,
})`
const StyledNavLink = styled(NavLink)`
${({ theme }) => theme.flexRowNoWrap}
align-items: left;
border-radius: 3rem;
......@@ -217,9 +217,7 @@ const StyledNavLink = styled(NavLink).attrs({
}
`
const StyledExternalLink = styled(ExternalLink).attrs({
activeClassName,
})<{ isActive?: boolean }>`
const StyledExternalLink = styled(ExternalLink)`
${({ theme }) => theme.flexRowNoWrap}
align-items: left;
border-radius: 3rem;
......@@ -262,11 +260,22 @@ export default function Header() {
const scrollY = useScrollPosition()
const { pathname } = useLocation()
const {
infoLink,
nativeCurrency: { symbol: nativeCurrencySymbol },
} = getChainInfoOrDefault(chainId)
// work around https://github.com/remix-run/react-router/issues/8161
// as we can't pass function `({isActive}) => ''` to className with styled-components
const isPoolActive =
pathname.startsWith('/pool') ||
pathname.startsWith('/add') ||
pathname.startsWith('/remove') ||
pathname.startsWith('/increase') ||
pathname.startsWith('/find')
return (
<HeaderFrame showBackground={scrollY > 45}>
<ClaimModal />
......@@ -284,13 +293,7 @@ export default function Header() {
data-cy="pool-nav-link"
id={`pool-nav-link`}
to={'/pool'}
isActive={(match, { pathname }) =>
Boolean(match) ||
pathname.startsWith('/add') ||
pathname.startsWith('/remove') ||
pathname.startsWith('/increase') ||
pathname.startsWith('/find')
}
className={isPoolActive ? activeClassName : undefined}
>
<Trans>Pool</Trans>
</StyledNavLink>
......
import { sendEvent } from 'components/analytics'
import { SupportedLocale } from 'constants/locales'
import { LocationDescriptor } from 'history'
import useParsedQueryString from 'hooks/useParsedQueryString'
import { stringify } from 'qs'
import { useMemo } from 'react'
import type { To } from 'react-router-dom'
import { useLocation } from 'react-router-dom'
import { useActiveLocale } from './useActiveLocale'
export function useLocationLinkProps(locale: SupportedLocale | null): {
to?: LocationDescriptor
to?: To
onClick?: () => void
} {
const location = useLocation()
......
......@@ -11,7 +11,7 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter
import useParsedQueryString from 'hooks/useParsedQueryString'
import { useCallback, useContext, useEffect, useState } from 'react'
import { AlertTriangle } from 'react-feather'
import { useHistory, useParams } from 'react-router-dom'
import { useNavigate, useParams } from 'react-router-dom'
import { Text } from 'rebass'
import {
useRangeHopCallbacks,
......@@ -78,7 +78,7 @@ import {
const DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
export default function AddLiquidity() {
const history = useHistory()
const navigate = useNavigate()
const {
currencyIdA,
currencyIdB,
......@@ -360,33 +360,33 @@ export default function AddLiquidity() {
(currencyANew: Currency) => {
const [idA, idB] = handleCurrencySelect(currencyANew, currencyIdB)
if (idB === undefined) {
history.push(`/add/${idA}`)
navigate(`/add/${idA}`)
} else {
history.push(`/add/${idA}/${idB}`)
navigate(`/add/${idA}/${idB}`)
}
},
[handleCurrencySelect, currencyIdB, history]
[handleCurrencySelect, currencyIdB, navigate]
)
const handleCurrencyBSelect = useCallback(
(currencyBNew: Currency) => {
const [idB, idA] = handleCurrencySelect(currencyBNew, currencyIdA)
if (idA === undefined) {
history.push(`/add/${idB}`)
navigate(`/add/${idB}`)
} else {
history.push(`/add/${idA}/${idB}`)
navigate(`/add/${idA}/${idB}`)
}
},
[handleCurrencySelect, currencyIdA, history]
[handleCurrencySelect, currencyIdA, navigate]
)
const handleFeePoolSelect = useCallback(
(newFeeAmount: FeeAmount) => {
onLeftRangeInput('')
onRightRangeInput('')
history.push(`/add/${currencyIdA}/${currencyIdB}/${newFeeAmount}`)
navigate(`/add/${currencyIdA}/${currencyIdB}/${newFeeAmount}`)
},
[currencyIdA, currencyIdB, history, onLeftRangeInput, onRightRangeInput]
[currencyIdA, currencyIdB, navigate, onLeftRangeInput, onRightRangeInput]
)
const handleDismissConfirmation = useCallback(() => {
......@@ -395,10 +395,10 @@ export default function AddLiquidity() {
if (txHash) {
onFieldAInput('')
// dont jump to pool page if creating
history.push('/pool')
navigate('/pool')
}
setTxHash('')
}, [history, onFieldAInput, txHash])
}, [navigate, onFieldAInput, txHash])
const addIsUnsupported = useIsSwapUnsupported(currencies?.CURRENCY_A, currencies?.CURRENCY_B)
......@@ -407,8 +407,8 @@ export default function AddLiquidity() {
onFieldBInput('')
onLeftRangeInput('')
onRightRangeInput('')
history.push(`/add`)
}, [history, onFieldAInput, onFieldBInput, onLeftRangeInput, onRightRangeInput])
navigate(`/add`)
}, [navigate, onFieldAInput, onFieldBInput, onLeftRangeInput, onRightRangeInput])
// get value and prices at ticks
const { [Bound.LOWER]: tickLower, [Bound.UPPER]: tickUpper } = ticks
......@@ -564,7 +564,7 @@ export default function AddLiquidity() {
onRightRangeInput((invertPrice ? priceUpper : priceLower?.invert())?.toSignificant(6) ?? '')
onFieldAInput(formattedAmounts[Field.CURRENCY_B] ?? '')
}
history.push(
navigate(
`/add/${currencyIdB as string}/${currencyIdA as string}${feeAmount ? '/' + feeAmount : ''}`
)
}}
......
import { useWeb3React } from '@web3-react/core'
import { Redirect, useParams } from 'react-router-dom'
import { Navigate, useParams } from 'react-router-dom'
import { WRAPPED_NATIVE_CURRENCY } from '../../constants/tokens'
import AddLiquidity from './index'
......@@ -20,7 +20,7 @@ export function RedirectDuplicateTokenIds() {
currencyIdB &&
(currencyIdA.toLowerCase() === currencyIdB.toLowerCase() || (isETHOrWETHA && isETHOrWETHB))
) {
return <Redirect to={`/add/${currencyIdA}`} />
return <Navigate to={`/add/${currencyIdA}`} replace />
}
return <AddLiquidity />
}
......@@ -10,7 +10,7 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import { useCallback, useContext, useState } from 'react'
import { Plus } from 'react-feather'
import { useHistory, useParams } from 'react-router-dom'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { Text } from 'rebass'
import { ThemeContext } from 'styled-components/macro'
......@@ -51,7 +51,7 @@ const DEFAULT_ADD_V2_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
export default function AddLiquidity() {
const { currencyIdA, currencyIdB } = useParams<{ currencyIdA?: string; currencyIdB?: string }>()
const history = useHistory()
const navigate = useNavigate()
const { account, chainId, provider } = useWeb3React()
const theme = useContext(ThemeContext)
......@@ -283,27 +283,27 @@ export default function AddLiquidity() {
(currencyA: Currency) => {
const newCurrencyIdA = currencyId(currencyA)
if (newCurrencyIdA === currencyIdB) {
history.push(`/add/v2/${currencyIdB}/${currencyIdA}`)
navigate(`/add/v2/${currencyIdB}/${currencyIdA}`)
} else {
history.push(`/add/v2/${newCurrencyIdA}/${currencyIdB}`)
navigate(`/add/v2/${newCurrencyIdA}/${currencyIdB}`)
}
},
[currencyIdB, history, currencyIdA]
[currencyIdB, navigate, currencyIdA]
)
const handleCurrencyBSelect = useCallback(
(currencyB: Currency) => {
const newCurrencyIdB = currencyId(currencyB)
if (currencyIdA === newCurrencyIdB) {
if (currencyIdB) {
history.push(`/add/v2/${currencyIdB}/${newCurrencyIdB}`)
navigate(`/add/v2/${currencyIdB}/${newCurrencyIdB}`)
} else {
history.push(`/add/v2/${newCurrencyIdB}`)
navigate(`/add/v2/${newCurrencyIdB}`)
}
} else {
history.push(`/add/v2/${currencyIdA ? currencyIdA : 'ETH'}/${newCurrencyIdB}`)
navigate(`/add/v2/${currencyIdA ? currencyIdA : 'ETH'}/${newCurrencyIdB}`)
}
},
[currencyIdA, history, currencyIdB]
[currencyIdA, navigate, currencyIdB]
)
const handleDismissConfirmation = useCallback(() => {
......@@ -315,7 +315,8 @@ export default function AddLiquidity() {
setTxHash('')
}, [onFieldAInput, txHash])
const isCreate = history.location.pathname.includes('/create')
const { pathname } = useLocation()
const isCreate = pathname.includes('/create')
const addIsUnsupported = useIsSwapUnsupported(currencies?.CURRENCY_A, currencies?.CURRENCY_B)
......
import { Redirect, useParams } from 'react-router-dom'
import { Navigate, useParams } from 'react-router-dom'
import AddLiquidityV2 from './index'
......@@ -6,7 +6,7 @@ export function RedirectDuplicateTokenIdsV2() {
const { currencyIdA, currencyIdB } = useParams<{ currencyIdA: string; currencyIdB: string }>()
if (currencyIdA && currencyIdB && currencyIdA.toLowerCase() === currencyIdB.toLowerCase()) {
return <Redirect to={`/add/v2/${currencyIdA}`} />
return <Navigate to={`/add/v2/${currencyIdA}`} replace />
}
return <AddLiquidityV2 />
......
......@@ -6,7 +6,7 @@ import TopLevelModals from 'components/TopLevelModals'
import ApeModeQueryParamReader from 'hooks/useApeModeQueryParamReader'
import { lazy, Suspense } from 'react'
import { useEffect } from 'react'
import { Redirect, Route, Switch, useLocation } from 'react-router-dom'
import { Navigate, Route, Routes, useLocation } from 'react-router-dom'
import styled from 'styled-components/macro'
import { useAnalyticsReporter } from '../components/analytics'
......@@ -31,6 +31,7 @@ import RemoveLiquidityV3 from './RemoveLiquidity/V3'
import Swap from './Swap'
import { OpenClaimAddressModalAndRedirectToSwap, RedirectPathToSwapOnly, RedirectToSwap } from './Swap/redirects'
// lazy load vote related pages
const Vote = lazy(() => import('./Vote'))
const AppWrapper = styled.div`
......@@ -80,9 +81,8 @@ function getCurrentPageFromLocation(locationPathname: string): PageName | undefi
}
export default function App() {
const location = useLocation()
const { pathname } = location
const currentPage = getCurrentPageFromLocation(location.pathname)
const { pathname } = useLocation()
const currentPage = getCurrentPageFromLocation(pathname)
useAnalyticsReporter()
initializeAnalytics()
......@@ -104,75 +104,48 @@ export default function App() {
<Polling />
<TopLevelModals />
<Suspense fallback={<Loader />}>
<Switch>
<Route strict path="/vote">
<Vote />
</Route>
<Route exact strict path="/create-proposal">
<Redirect to="/vote/create-proposal" />
</Route>
<Route exact strict path="/claim">
<OpenClaimAddressModalAndRedirectToSwap />
</Route>
<Route exact strict path="/uni">
<Earn />
</Route>
<Route exact strict path="/uni/:currencyIdA/:currencyIdB">
<Manage />
</Route>
<Routes>
<Route path="vote/*" element={<Vote />} />
<Route path="create-proposal" element={<Navigate to="/vote/create-proposal" replace />} />
<Route path="claim" element={<OpenClaimAddressModalAndRedirectToSwap />} />
<Route path="uni" element={<Earn />} />
<Route path="uni/:currencyIdA/:currencyIdB" element={<Manage />} />
<Route exact strict path="/send">
<RedirectPathToSwapOnly />
</Route>
<Route exact strict path="/swap/:outputCurrency">
<RedirectToSwap />
</Route>
<Route exact strict path="/swap">
<Swap />
</Route>
<Route path="send" element={<RedirectPathToSwapOnly />} />
<Route path="swap/:outputCurrency" element={<RedirectToSwap />} />
<Route path="swap" element={<Swap />} />
<Route exact strict path="/pool/v2/find">
<PoolFinder />
</Route>
<Route exact strict path="/pool/v2">
<PoolV2 />
</Route>
<Route exact strict path="/pool">
<Pool />
</Route>
<Route exact strict path="/pool/:tokenId">
<PositionPage />
</Route>
<Route path="pool/v2/find" element={<PoolFinder />} />
<Route path="pool/v2" element={<PoolV2 />} />
<Route path="pool" element={<Pool />} />
<Route path="pool/:tokenId" element={<PositionPage />} />
<Route exact strict path="/add/v2/:currencyIdA?/:currencyIdB?">
<RedirectDuplicateTokenIdsV2 />
<Route path="add/v2" element={<RedirectDuplicateTokenIdsV2 />}>
<Route path=":currencyIdA" />
<Route path=":currencyIdA/:currencyIdB" />
</Route>
<Route exact strict path="/add/:currencyIdA?/:currencyIdB?/:feeAmount?">
<RedirectDuplicateTokenIds />
<Route path="add" element={<RedirectDuplicateTokenIds />}>
{/* this is workaround since react-router-dom v6 doesn't support optional parameters any more */}
<Route path=":currencyIdA" />
<Route path=":currencyIdA/:currencyIdB" />
<Route path=":currencyIdA/:currencyIdB/:feeAmount" />
</Route>
<Route exact strict path="/increase/:currencyIdA?/:currencyIdB?/:feeAmount?/:tokenId?">
<AddLiquidity />
<Route path="increase" element={<AddLiquidity />}>
<Route path=":currencyIdA" />
<Route path=":currencyIdA/:currencyIdB" />
<Route path=":currencyIdA/:currencyIdB/:feeAmount" />
<Route path=":currencyIdA/:currencyIdB/:feeAmount/:tokenId" />
</Route>
<Route exact strict path="/remove/v2/:currencyIdA/:currencyIdB">
<RemoveLiquidity />
</Route>
<Route exact strict path="/remove/:tokenId">
<RemoveLiquidityV3 />
</Route>
<Route path="remove/v2/:currencyIdA/:currencyIdB" element={<RemoveLiquidity />} />
<Route path="remove/:tokenId" element={<RemoveLiquidityV3 />} />
<Route exact strict path="/migrate/v2">
<MigrateV2 />
</Route>
<Route exact strict path="/migrate/v2/:address">
<MigrateV2Pair />
</Route>
<Route path="migrate/v2" element={<MigrateV2 />} />
<Route path="migrate/v2/:address" element={<MigrateV2Pair />} />
<Route>
<RedirectPathToSwapOnly />
</Route>
</Switch>
<Route path="*" element={<RedirectPathToSwapOnly />} />
</Routes>
</Suspense>
<Marginer />
</BodyWrapper>
......
......@@ -24,8 +24,7 @@ import JSBI from 'jsbi'
import { NEVER_RELOAD, useSingleCallResult } from 'lib/hooks/multicall'
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
import { AlertCircle, AlertTriangle, ArrowDown } from 'react-feather'
import { Redirect } from 'react-router'
import { useParams } from 'react-router-dom'
import { Navigate, useParams } from 'react-router-dom'
import { Text } from 'rebass'
import { useAppDispatch } from 'state/hooks'
import { Bound, resetMintState } from 'state/mint/v3/actions'
......@@ -719,7 +718,7 @@ export default function MigrateV2Pair() {
!token0Address)
) {
console.error('Invalid pair address')
return <Redirect to="/migrate/v2" />
return <Navigate to="/migrate/v2" replace />
}
return (
......
......@@ -25,7 +25,7 @@ import useTransactionDeadline from 'hooks/useTransactionDeadline'
import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { useCallback, useMemo, useState } from 'react'
import { Redirect, useLocation, useParams } from 'react-router-dom'
import { Navigate, useLocation, useParams } from 'react-router-dom'
import { Text } from 'rebass'
import { useBurnV3ActionHandlers, useBurnV3State, useDerivedV3BurnInfo } from 'state/burn/v3/hooks'
import { useTransactionAdder } from 'state/transactions/hooks'
......@@ -55,7 +55,7 @@ export default function RemoveLiquidityV3() {
}, [tokenId])
if (parsedTokenId === null || parsedTokenId.eq(0)) {
return <Redirect to={{ ...location, pathname: '/pool' }} />
return <Navigate to={{ ...location, pathname: '/pool' }} replace />
}
return <Remove tokenId={parsedTokenId} />
......
......@@ -10,7 +10,7 @@ import { sendEvent } from 'components/analytics'
import { useV2LiquidityTokenPermit } from 'hooks/useV2LiquidityTokenPermit'
import { useCallback, useContext, useMemo, useState } from 'react'
import { ArrowDown, Plus } from 'react-feather'
import { useHistory, useParams } from 'react-router-dom'
import { useNavigate, useParams } from 'react-router-dom'
import { Text } from 'rebass'
import { ThemeContext } from 'styled-components/macro'
......@@ -48,7 +48,7 @@ import { ClickableText, MaxButton, Wrapper } from '../Pool/styleds'
const DEFAULT_REMOVE_LIQUIDITY_SLIPPAGE_TOLERANCE = new Percent(5, 100)
export default function RemoveLiquidity() {
const history = useHistory()
const navigate = useNavigate()
const { currencyIdA, currencyIdB } = useParams<{ currencyIdA: string; currencyIdB: string }>()
const [currencyA, currencyB] = [useCurrency(currencyIdA) ?? undefined, useCurrency(currencyIdB) ?? undefined]
const { account, chainId, provider } = useWeb3React()
......@@ -396,22 +396,22 @@ export default function RemoveLiquidity() {
const handleSelectCurrencyA = useCallback(
(currency: Currency) => {
if (currencyIdB && currencyId(currency) === currencyIdB) {
history.push(`/remove/v2/${currencyId(currency)}/${currencyIdA}`)
navigate(`/remove/v2/${currencyId(currency)}/${currencyIdA}`)
} else {
history.push(`/remove/v2/${currencyId(currency)}/${currencyIdB}`)
navigate(`/remove/v2/${currencyId(currency)}/${currencyIdB}`)
}
},
[currencyIdA, currencyIdB, history]
[currencyIdA, currencyIdB, navigate]
)
const handleSelectCurrencyB = useCallback(
(currency: Currency) => {
if (currencyIdA && currencyId(currency) === currencyIdA) {
history.push(`/remove/v2/${currencyIdB}/${currencyId(currency)}`)
navigate(`/remove/v2/${currencyIdB}/${currencyId(currency)}`)
} else {
history.push(`/remove/v2/${currencyIdA}/${currencyId(currency)}`)
navigate(`/remove/v2/${currencyIdA}/${currencyId(currency)}`)
}
},
[currencyIdA, currencyIdB, history]
[currencyIdA, currencyIdB, navigate]
)
const handleDismissConfirmation = useCallback(() => {
......
......@@ -20,7 +20,7 @@ import JSBI from 'jsbi'
import { Context, useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { ReactNode } from 'react'
import { ArrowDown, CheckCircle, HelpCircle } from 'react-feather'
import { useHistory } from 'react-router-dom'
import { useNavigate } from 'react-router-dom'
import { Text } from 'rebass'
import { useToggleWalletModal } from 'state/application/hooks'
import { InterfaceTrade } from 'state/routing/types'
......@@ -79,7 +79,7 @@ export function getIsValidSwapQuote(
}
export default function Swap() {
const history = useHistory()
const navigate = useNavigate()
const { account, chainId } = useWeb3React()
const loadedUrlParams = useDefaultsFromURLSearch()
......@@ -194,8 +194,8 @@ export default function Swap() {
// reset if they close warning without tokens in params
const handleDismissTokenWarning = useCallback(() => {
setDismissTokenWarning(true)
history.push('/swap/')
}, [history])
navigate('/swap/')
}, [navigate])
// modal and loading
const [{ showConfirm, tradeToConfirm, swapErrorMessage, attemptingTxn, txHash }, setSwapState] = useState<{
......
import { useEffect } from 'react'
import { Redirect, useLocation, useParams } from 'react-router-dom'
import { Navigate, useLocation, useParams } from 'react-router-dom'
import { useAppDispatch } from 'state/hooks'
import { ApplicationModal, setOpenModal } from '../../state/application/reducer'
......@@ -7,7 +7,7 @@ import { ApplicationModal, setOpenModal } from '../../state/application/reducer'
// Redirects to swap but only replace the pathname
export function RedirectPathToSwapOnly() {
const location = useLocation()
return <Redirect to={{ ...location, pathname: '/swap' }} />
return <Navigate to={{ ...location, pathname: '/swap' }} replace />
}
// Redirects from the /swap/:outputCurrency path to the /swap?outputCurrency=:outputCurrency format
......@@ -17,7 +17,7 @@ export function RedirectToSwap() {
const { outputCurrency } = useParams<{ outputCurrency: string }>()
return (
<Redirect
<Navigate
to={{
...location,
pathname: '/swap',
......@@ -26,6 +26,7 @@ export function RedirectToSwap() {
? `${search}&outputCurrency=${outputCurrency}`
: `?outputCurrency=${outputCurrency}`,
}}
replace
/>
)
}
......
......@@ -153,7 +153,8 @@ function getDateFromBlock(
}
export default function VotePage() {
const { governorIndex, id } = useParams<{ governorIndex: string; id: string }>()
// see https://github.com/remix-run/react-router/issues/8200#issuecomment-962520661
const { governorIndex, id } = useParams() as { governorIndex: string; id: string }
const parsedGovernorIndex = Number.parseInt(governorIndex)
const { chainId, account } = useWeb3React()
......
import CreateProposal from 'pages/CreateProposal'
import { Route } from 'react-router-dom'
import { Route, Routes } from 'react-router-dom'
import Landing from './Landing'
import VotePage from './VotePage'
export default function Vote() {
return (
<>
<Route exact strict path="/vote/:governorIndex/:id">
<VotePage />
</Route>
<Route exact strict path="/vote/create-proposal">
<CreateProposal />
</Route>
<Route exact strict path="/vote">
<Landing />
</Route>
</>
<Routes>
<Route path="/" element={<Landing />} />
<Route path=":governorIndex/:id" element={<VotePage />} />
<Route path="create-proposal" element={<CreateProposal />} />
</Routes>
)
}
......@@ -16,7 +16,7 @@ import { usePool } from 'hooks/usePools'
import JSBI from 'jsbi'
import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { ReactNode, useCallback, useMemo } from 'react'
import { useHistory } from 'react-router-dom'
import { useLocation, useNavigate } from 'react-router-dom'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { getTickToPrice } from 'utils/getTickToPrice'
import { replaceURLParam } from 'utils/routes'
......@@ -48,7 +48,7 @@ export function useV3MintActionHandlers(noLiquidity: boolean | undefined): {
onStartPriceInput: (typedValue: string) => void
} {
const dispatch = useAppDispatch()
const history = useHistory()
const navigate = useNavigate()
const onFieldAInput = useCallback(
(typedValue: string) => {
......@@ -64,20 +64,22 @@ export function useV3MintActionHandlers(noLiquidity: boolean | undefined): {
[dispatch, noLiquidity]
)
const { search } = useLocation()
const onLeftRangeInput = useCallback(
(typedValue: string) => {
dispatch(typeLeftRangeInput({ typedValue }))
history.replace({ search: replaceURLParam(history.location.search, 'minPrice', typedValue) })
navigate({ search: replaceURLParam(search, 'minPrice', typedValue) }, { replace: true })
},
[dispatch, history]
[dispatch, navigate, search]
)
const onRightRangeInput = useCallback(
(typedValue: string) => {
dispatch(typeRightRangeInput({ typedValue }))
history.replace({ search: replaceURLParam(history.location.search, 'maxPrice', typedValue) })
navigate({ search: replaceURLParam(search, 'maxPrice', typedValue) }, { replace: true })
},
[dispatch, history]
[dispatch, navigate, search]
)
const onStartPriceInput = useCallback(
......
......@@ -1019,10 +1019,10 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.17.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.0.tgz#b8d142fc0f7664fb3d9b5833fd40dcbab89276c0"
integrity sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ==
"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
dependencies:
regenerator-runtime "^0.13.4"
......@@ -10166,17 +10166,12 @@ hex-color-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
history@^4.9.0:
version "4.10.1"
resolved "https://registry.npmjs.org/history/-/history-4.10.1.tgz"
integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
history@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b"
integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==
dependencies:
"@babel/runtime" "^7.1.2"
loose-envify "^1.2.0"
resolve-pathname "^3.0.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
value-equal "^1.0.1"
"@babel/runtime" "^7.7.6"
hmac-drbg@^1.0.1:
version "1.0.1"
......@@ -10187,7 +10182,7 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
......@@ -11157,11 +11152,6 @@ is-wsl@^2.1.1, is-wsl@^2.2.0:
dependencies:
is-docker "^2.0.0"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
......@@ -12385,7 +12375,7 @@ long@^4.0.0:
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
......@@ -12705,14 +12695,6 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
mini-create-react-context@^0.4.0:
version "0.4.1"
resolved "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz"
integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
dependencies:
"@babel/runtime" "^7.12.1"
tiny-warning "^1.0.3"
mini-css-extract-plugin@0.11.3:
version "0.11.3"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz#15b0910a7f32e62ffde4a7430cfefbd700724ea6"
......@@ -13740,13 +13722,6 @@ path-to-regexp@2.2.1:
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz"
integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==
path-to-regexp@^1.7.0:
version "1.8.0"
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz"
integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
dependencies:
isarray "0.0.1"
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
......@@ -15056,7 +15031,7 @@ react-ga4@^1.4.1:
resolved "https://registry.yarnpkg.com/react-ga4/-/react-ga4-1.4.1.tgz#6ee2a2db115ed235b2f2092bc746b4eeeca9e206"
integrity sha512-ioBMEIxd4ePw4YtaloTUgqhQGqz5ebDdC4slEpLgy2sLx1LuZBC9iYCwDymTXzcntw6K1dHX183ulP32nNdG7w==
react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6:
react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
......@@ -15129,34 +15104,20 @@ react-remove-scroll@^2.3.0:
use-callback-ref "^1.2.3"
use-sidecar "^1.0.1"
react-router-dom@^5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.3.tgz#8779fc28e6691d07afcaf98406d3812fe6f11199"
integrity sha512-Ov0tGPMBgqmbu5CDmN++tv2HQ9HlWDuWIIqn4b88gjlAN5IHI+4ZUZRcpz9Hl0azFIwihbLDYw1OiHGRo7ZIng==
react-router-dom@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d"
integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
loose-envify "^1.3.1"
prop-types "^15.6.2"
react-router "5.3.3"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
history "^5.2.0"
react-router "6.3.0"
react-router@5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.3.tgz#8e3841f4089e728cf82a429d92cdcaa5e4a3a288"
integrity sha512-mzQGUvS3bM84TnbtMYR8ZjKnuPJ71IjSzR+DE6UkUqvN4czWIqEs17yLL8xkAycv4ev0AiN+IGrWu88vJs/p2w==
react-router@6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557"
integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
hoist-non-react-statics "^3.1.0"
loose-envify "^1.3.1"
mini-create-react-context "^0.4.0"
path-to-regexp "^1.7.0"
prop-types "^15.6.2"
react-is "^16.6.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
history "^5.2.0"
react-scripts@^4.0.3:
version "4.0.3"
......@@ -15676,11 +15637,6 @@ resolve-from@^4.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve-pathname@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz"
integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
resolve-url-loader@^3.1.2:
version "3.1.4"
resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz#3c16caebe0b9faea9c7cc252fa49d2353c412320"
......@@ -17157,12 +17113,12 @@ timsort@^0.3.0:
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tiny-invariant@^1.0.2, tiny-invariant@^1.1.0, tiny-invariant@^1.2.0:
tiny-invariant@^1.1.0, tiny-invariant@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
tiny-warning@^1.0.0, tiny-warning@^1.0.3:
tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
......@@ -17892,11 +17848,6 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
value-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz"
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
value-or-promise@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.6.tgz#218aa4794aa2ee24dcf48a29aba4413ed584747f"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment