diff --git a/packages/web/.env.development.example b/packages/web/.env.development.example index 8db96b67..4c2c3994 100644 --- a/packages/web/.env.development.example +++ b/packages/web/.env.development.example @@ -19,3 +19,4 @@ REACT_APP_FIREBASE_API_KEY= REACT_APP_FIREBASE_APP_ID= REACT_APP_RPCPOOL_API_KEY= REACT_APP_NAME_SERVICE_URL= +REACT_APP_ORCA_CACHE_URL= diff --git a/packages/web/package.json b/packages/web/package.json index f5ac8853..40fca671 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -78,7 +78,6 @@ "flagged": "^2.0.1", "fuse.js": "^6.5.3", "highcharts": "^9.0.0", - "history": "4.9.0", "idb": "^7.1.0", "jsbi": "^4.1.0", "lodash.throttle": "^4.1.1", @@ -99,8 +98,7 @@ "react-laag": "2.0.3", "react-loading-skeleton": "^3.0.1", "react-query": "^3.34.6", - "react-router": "^5.2.0", - "react-router-dom": "^5.2.0", + "react-router-dom": "^6.4.3", "react-solana-jazzicon": "^0.1.5", "react-spring": "^8.0.27", "react-stickynode": "^3.1.0", @@ -142,8 +140,6 @@ "@types/react-dom": "^17.0.11", "@types/react-helmet": "^6.1.1", "@types/react-highcharts": "^16.0.2", - "@types/react-router": "^5.1.8", - "@types/react-router-dom": "^5.1.6", "@types/react-stickynode": "^3.0.1", "@types/webpack-env": "^1.16.0", "assert": "^2.0.0", diff --git a/packages/web/src/App.tsx b/packages/web/src/App.tsx index c9ecaf14..42cd3f37 100644 --- a/packages/web/src/App.tsx +++ b/packages/web/src/App.tsx @@ -1,7 +1,7 @@ import 'new/services/Defaults'; import * as React from 'react'; -import { BrowserRouter, HashRouter, Route, Switch } from 'react-router-dom'; +import { BrowserRouter, HashRouter, Route, Routes } from 'react-router-dom'; import * as Sentry from '@sentry/react'; import dayjs from 'dayjs'; @@ -9,8 +9,6 @@ import localizedFormat from 'dayjs/plugin/localizedFormat'; import { observer } from 'mobx-react-lite'; import { Intercom } from 'components/common/Intercom'; -import { NotifyToast } from 'components/common/NotifyToast'; -import { ToastManager } from 'components/common/ToastManager'; import { Buy, Home, @@ -31,7 +29,7 @@ import { NotificationManager, } from 'new/ui/managers'; import { Landing } from 'pages/Landing'; -import { AuthRequiredRoute } from 'utils/routes/UserRequiredRoute'; +import { AuthRequiredRoute } from 'utils/routes'; import { Providers } from './Providers'; @@ -39,33 +37,38 @@ dayjs.extend(localizedFormat); const App: React.FC = observer(() => { const Router: React.ElementType = process.env.REACT_APP_STAGING ? HashRouter : BrowserRouter; + // const Router: React.ElementType = BrowserRouter; return ( <> + Какой то текст + - - - - -
- - - - - - - - - - -
-
+ + } /> + } /> + + }> + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + - } /> + + {__DEVELOPMENT__ || process.env.REACT_APP_STAGING ? ( ) : null} diff --git a/packages/web/src/components/common/Intercom/Intercom.tsx b/packages/web/src/components/common/Intercom/Intercom.tsx index a2470221..78f5d3c4 100644 --- a/packages/web/src/components/common/Intercom/Intercom.tsx +++ b/packages/web/src/components/common/Intercom/Intercom.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; import { useEffect } from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import { useIntercom } from 'react-use-intercom'; import { useIsMobile } from '@p2p-wallet-web/ui'; diff --git a/packages/web/src/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx b/packages/web/src/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx index f9ffa610..1afbb590 100644 --- a/packages/web/src/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx +++ b/packages/web/src/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx @@ -1,6 +1,5 @@ import type { FunctionComponent } from 'react'; -import { useLocation } from 'react-router'; -import { Link, NavLink } from 'react-router-dom'; +import { Link, NavLink, useLocation } from 'react-router-dom'; import { styled } from '@linaria/react'; import { borders, shadows, theme, up } from '@p2p-wallet-web/ui'; diff --git a/packages/web/src/components/ui/Modal/Modal.tsx b/packages/web/src/components/ui/Modal/Modal.tsx index d55ee5b2..69bff2d7 100644 --- a/packages/web/src/components/ui/Modal/Modal.tsx +++ b/packages/web/src/components/ui/Modal/Modal.tsx @@ -1,7 +1,7 @@ import type { FunctionComponent } from 'react'; import * as React from 'react'; import { useEffect, useMemo, useRef, useState } from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import { animated, useSpring, useTransition } from 'react-spring'; import { styled } from '@linaria/react'; diff --git a/packages/web/src/new/scenes/Main/Auth/Auth.tsx b/packages/web/src/new/scenes/Main/Auth/Auth.tsx index 73beacaa..4e5e3711 100644 --- a/packages/web/src/new/scenes/Main/Auth/Auth.tsx +++ b/packages/web/src/new/scenes/Main/Auth/Auth.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import { Redirect, useLocation } from 'react-router-dom'; +import { Navigate, useLocation } from 'react-router-dom'; import { observer } from 'mobx-react-lite'; @@ -17,7 +17,7 @@ export const Auth: FC = observer(() => { const fromPage = (location.state as RedirectState)?.fromPage || '/wallets'; if (authViewModel.connected) { - return ; + return ; } return ; diff --git a/packages/web/src/new/scenes/Main/Auth/Subviews/Wizard.tsx b/packages/web/src/new/scenes/Main/Auth/Subviews/Wizard.tsx index 0e5d5e2a..217ebc97 100644 --- a/packages/web/src/new/scenes/Main/Auth/Subviews/Wizard.tsx +++ b/packages/web/src/new/scenes/Main/Auth/Subviews/Wizard.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react'; -import { useHistory } from 'react-router'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { observer } from 'mobx-react-lite'; @@ -16,17 +15,17 @@ import { RestoreOptions } from './Restore/RestoreOptions'; export const Wizard: FC = observer(({ authViewModel }) => { const location = useLocation(); - const history = useHistory(); + const navigate = useNavigate(); // @FIXME remove and replace with react-router if (location.search === '?restore') { authViewModel.setRestoreStart(); - history.replace({}); + navigate({}, { replace: true }); } if (location.search === '?create') { authViewModel.setCreateStart(); - history.replace({}); + navigate({}, { replace: true }); } const VIEW_MAP: ViewMap = { diff --git a/packages/web/src/new/scenes/Main/Buy/Buy.ViewModel.ts b/packages/web/src/new/scenes/Main/Buy/Buy.ViewModel.ts index 850b1551..847edacc 100644 --- a/packages/web/src/new/scenes/Main/Buy/Buy.ViewModel.ts +++ b/packages/web/src/new/scenes/Main/Buy/Buy.ViewModel.ts @@ -144,10 +144,8 @@ export class BuyViewModel extends ViewModel { } private _getSymbolFromParams(): CryptoCurrencySymbol { - return ( - this._locationService.getParams<{ symbol?: CryptoCurrencySymbol }>('/buy/:symbol?').symbol || - 'SOL' - ); + const symbol = this._locationService.getParams<'symbol'>('/buy/:symbol').symbol || 'SOL'; + return symbol as CryptoCurrencySymbol; } private _startUpdating(): void { diff --git a/packages/web/src/new/scenes/Main/Buy/Subviews/Moonpay/CurrencySelector/CurrencySelector.tsx b/packages/web/src/new/scenes/Main/Buy/Subviews/Moonpay/CurrencySelector/CurrencySelector.tsx index c887d6f3..c227883e 100644 --- a/packages/web/src/new/scenes/Main/Buy/Subviews/Moonpay/CurrencySelector/CurrencySelector.tsx +++ b/packages/web/src/new/scenes/Main/Buy/Subviews/Moonpay/CurrencySelector/CurrencySelector.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; import { useCallback } from 'react'; -import { useHistory } from 'react-router'; +import { useNavigate } from 'react-router-dom'; import { styled } from '@linaria/react'; import { theme } from '@p2p-wallet-web/ui'; @@ -52,7 +52,7 @@ const Normal = styled.span` `; export const CurrencySelect: FC = observer(({ viewModel }) => { - const history = useHistory(); + const navigate = useNavigate(); const handleItemClick = useCallback( (nextCurrency: CryptoCurrency) => () => { @@ -73,7 +73,7 @@ export const CurrencySelect: FC = observer(({ viewModel }) => }); // change coin - history.push(`/buy/${nextCurrency.symbol}`); + navigate(`/buy/${nextCurrency.symbol}`); }, [], ); diff --git a/packages/web/src/new/scenes/Main/Home/Subviews/EmptyWalletView/EmptyWalletView.tsx b/packages/web/src/new/scenes/Main/Home/Subviews/EmptyWalletView/EmptyWalletView.tsx index c08ce027..c70779b6 100644 --- a/packages/web/src/new/scenes/Main/Home/Subviews/EmptyWalletView/EmptyWalletView.tsx +++ b/packages/web/src/new/scenes/Main/Home/Subviews/EmptyWalletView/EmptyWalletView.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import { useHistory, useLocation } from 'react-router'; +import { useLocation, useNavigate } from 'react-router-dom'; import { styled } from '@linaria/react'; import { theme, up, useIsMobile } from '@p2p-wallet-web/ui'; @@ -70,7 +70,7 @@ type Props = { }; export const EmptyWalletView: FC = ({ viewModel }) => { - const history = useHistory(); + const navigate = useNavigate(); const location = useLocation(); const isMobile = useIsMobile(); @@ -91,7 +91,7 @@ export const EmptyWalletView: FC = ({ viewModel }) => { }; const goToRoute = (route: string) => () => { - history.push(route, { fromPage: location.pathname }); + navigate(route, { state: { fromPage: location.pathname } }); }; return ( diff --git a/packages/web/src/new/scenes/Main/Home/Subviews/NavButtonsMenu/NavButtonsMenu.tsx b/packages/web/src/new/scenes/Main/Home/Subviews/NavButtonsMenu/NavButtonsMenu.tsx index 048479f5..c5d6df06 100644 --- a/packages/web/src/new/scenes/Main/Home/Subviews/NavButtonsMenu/NavButtonsMenu.tsx +++ b/packages/web/src/new/scenes/Main/Home/Subviews/NavButtonsMenu/NavButtonsMenu.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; import { useEffect, useRef, useState } from 'react'; -import { useHistory, useLocation } from 'react-router'; +import { useLocation, useNavigate } from 'react-router-dom'; import { styled } from '@linaria/react'; import classNames from 'classnames'; @@ -32,7 +32,7 @@ interface Props { } export const NavButtonsMenu: FC = ({ viewModel }) => { - const history = useHistory(); + const navigate = useNavigate(); const location = useLocation(); const menuRef = useRef(null); @@ -58,8 +58,8 @@ export const NavButtonsMenu: FC = ({ viewModel }) => { }; }, []); - const handleButtonClick = (route: string) => () => { - history.push(route, { fromPage: location.pathname }); + const handleButtonClick = (to: string) => () => { + navigate(to, { state: { fromPage: location.pathname } }); }; return ( diff --git a/packages/web/src/new/scenes/Main/Home/Subviews/WalletsCollectionView/common/BaseWalletCell/TokenMenu/TokenMenu.tsx b/packages/web/src/new/scenes/Main/Home/Subviews/WalletsCollectionView/common/BaseWalletCell/TokenMenu/TokenMenu.tsx index 416e7179..f8eba649 100644 --- a/packages/web/src/new/scenes/Main/Home/Subviews/WalletsCollectionView/common/BaseWalletCell/TokenMenu/TokenMenu.tsx +++ b/packages/web/src/new/scenes/Main/Home/Subviews/WalletsCollectionView/common/BaseWalletCell/TokenMenu/TokenMenu.tsx @@ -1,6 +1,6 @@ import type { FC, HTMLAttributes } from 'react'; import { useCallback } from 'react'; -import { useHistory, useLocation } from 'react-router'; +import { useLocation, useNavigate } from 'react-router-dom'; import { styled } from '@linaria/react'; import { observer } from 'mobx-react-lite'; @@ -24,14 +24,14 @@ interface Props extends HTMLAttributes { export const TokenMenu: FC = observer( ({ wallet, isHidden = false, onToggleClick, className }) => { - const history = useHistory(); + const navigate = useNavigate(); const location = useLocation(); const handleButtonClick = useCallback( (route: string) => () => { - history.push(route, { fromPage: location.pathname }); + navigate(route, { state: { fromPage: location.pathname } }); }, - [history, location.pathname], + [navigate, location.pathname], ); return ( @@ -46,7 +46,7 @@ export const TokenMenu: FC = observer( Send {wallet.token.symbol} {wallet.token.symbol ? ( - + Swap {wallet.token.symbol} ) : undefined} diff --git a/packages/web/src/new/scenes/Main/Main.tsx b/packages/web/src/new/scenes/Main/Main.tsx index c27e523c..39f86bac 100644 --- a/packages/web/src/new/scenes/Main/Main.tsx +++ b/packages/web/src/new/scenes/Main/Main.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import React from 'react'; +import { Outlet } from 'react-router-dom'; import { observer } from 'mobx-react-lite'; @@ -7,13 +7,9 @@ import { useViewModel } from 'new/core/viewmodels/useViewModel'; import { MainViewModel } from './Main.ViewModel'; -interface Props { - children: React.ReactNode; -} - -export const Main: FC = observer(({ children }) => { +export const Main: FC = observer(() => { // resolve viewModel useViewModel(MainViewModel); - return <>{children}; + return ; }); diff --git a/packages/web/src/new/scenes/Main/Receive/Receive.tsx b/packages/web/src/new/scenes/Main/Receive/Receive.tsx index 9f8b7697..0e2e2e02 100644 --- a/packages/web/src/new/scenes/Main/Receive/Receive.tsx +++ b/packages/web/src/new/scenes/Main/Receive/Receive.tsx @@ -1,6 +1,5 @@ import type { FC } from 'react'; -import { Route, useRouteMatch } from 'react-router'; -import { Switch } from 'react-router-dom'; +import { Route, Routes } from 'react-router-dom'; import { useTrackOpenPageAction } from 'new/sdk/Analytics'; @@ -10,16 +9,10 @@ import { SupportedTokens } from './SupportedTokens'; export const Receive: FC = () => { useTrackOpenPageAction('Receive_Start_Screen'); - const match = useRouteMatch(); - return ( - - - - - - - - + + } /> + } /> + ); }; diff --git a/packages/web/src/new/scenes/Main/Send/Send.ViewModel.ts b/packages/web/src/new/scenes/Main/Send/Send.ViewModel.ts index b282d439..2c05d0b1 100644 --- a/packages/web/src/new/scenes/Main/Send/Send.ViewModel.ts +++ b/packages/web/src/new/scenes/Main/Send/Send.ViewModel.ts @@ -14,6 +14,7 @@ import type * as SolanaSDK from 'new/sdk/SolanaSDK'; import type { Wallet } from 'new/sdk/SolanaSDK'; import { convertToBalance, FeeAmount, toLamport } from 'new/sdk/SolanaSDK'; import { Defaults } from 'new/services/Defaults'; +import { LocationService } from 'new/services/LocationService'; import { ModalService, ModalType } from 'new/services/ModalService'; import { PricesService } from 'new/services/PriceAPIs/PricesService'; import { WalletsRepository } from 'new/services/Repositories'; @@ -104,6 +105,7 @@ export class SendViewModel public selectAddressViewModel: Readonly, private _walletModel: WalletModel, private _modalService: ModalService, + private _locationService: LocationService, ) { super(); @@ -198,6 +200,23 @@ export class SendViewModel } private _bind(): void { + // wallet was changed + this.addReaction( + reaction( + () => this.wallet, + (wallet) => { + if (!wallet) { + return; + } + // @web: sync url with source wallet + const newPath = `/send/${wallet.pubkey}`; + if (location.pathname !== newPath) { + this._locationService.push(newPath); + } + }, + ), + ); + // Smart select fee token this.addReaction( reaction( @@ -343,7 +362,11 @@ export class SendViewModel runInAction(() => { this.loadingState = LoadableState.loaded; if (!this.wallet) { - this.wallet = this.walletsRepository.nativeWallet; + const pubkey = this._getPubkey(); + const wallet = this.walletsRepository + .getWallets() + .find((wallet) => wallet.pubkey === pubkey); + this.wallet = wallet || this.walletsRepository.nativeWallet; } const payingWallet = this.walletsRepository .getWallets() @@ -361,6 +384,10 @@ export class SendViewModel }); } + private _getPubkey(): string | undefined { + return this._locationService.getParams<'publicKey'>('/send/:publicKey').publicKey; + } + private _send() { const wallet = this.wallet; let amount = this.amount; diff --git a/packages/web/src/new/scenes/Main/Settings/Settings.tsx b/packages/web/src/new/scenes/Main/Settings/Settings.tsx index e68f2540..950105ee 100644 --- a/packages/web/src/new/scenes/Main/Settings/Settings.tsx +++ b/packages/web/src/new/scenes/Main/Settings/Settings.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import { useHistory } from 'react-router'; +import { useNavigate } from 'react-router-dom'; import { styled } from '@linaria/react'; import classNames from 'classnames'; @@ -144,10 +144,10 @@ const FIATS = [Fiat.usd, Fiat.eur, Fiat.rub]; export const Settings: FC = observer(() => { const viewModel = useViewModel(SettingsViewModel); - const history = useHistory(); + const navigate = useNavigate(); const handleNetworkClick = () => { - history.push('/settings/network'); + navigate('/settings/network'); }; const handleLogoutClick = () => { diff --git a/packages/web/src/new/scenes/Main/Swap/Swap/GoBackButton/GoBackButton.tsx b/packages/web/src/new/scenes/Main/Swap/Swap/GoBackButton/GoBackButton.tsx index 30378421..e658939b 100644 --- a/packages/web/src/new/scenes/Main/Swap/Swap/GoBackButton/GoBackButton.tsx +++ b/packages/web/src/new/scenes/Main/Swap/Swap/GoBackButton/GoBackButton.tsx @@ -1,12 +1,10 @@ -import { generatePath, useHistory, useParams } from 'react-router'; +import { generatePath, useNavigate, useParams } from 'react-router-dom'; import { styled } from '@linaria/react'; import { theme } from '@p2p-wallet-web/ui'; import { Button, Icon } from 'components/ui'; -import type { SwapRouteParams } from '../types'; - const Wrapper = styled.div``; const ActionIcon = styled(Icon)` @@ -22,11 +20,12 @@ const ButtonStyled = styled(Button)` `; export const GoBackButton = () => { - const history = useHistory(); - const { publicKey } = useParams(); + const navigate = useNavigate(); + const { publicKey } = useParams<{ publicKey?: string }>(); const handleButtonClick = () => { - history.push(generatePath('/swap/:publicKey?', { publicKey })); + const pathTemplate = `/swap${publicKey ? '/:publicKey' : ''}`; + navigate(generatePath(pathTemplate, { publicKey })); }; return ( diff --git a/packages/web/src/new/scenes/Main/Swap/Swap/SettingsButton/SettingsButton.tsx b/packages/web/src/new/scenes/Main/Swap/Swap/SettingsButton/SettingsButton.tsx index 16d4dfc3..ce3dba72 100644 --- a/packages/web/src/new/scenes/Main/Swap/Swap/SettingsButton/SettingsButton.tsx +++ b/packages/web/src/new/scenes/Main/Swap/Swap/SettingsButton/SettingsButton.tsx @@ -1,13 +1,11 @@ import type { FC } from 'react'; -import { generatePath, useHistory, useParams } from 'react-router'; +import { generatePath, useNavigate, useParams } from 'react-router-dom'; import { styled } from '@linaria/react'; import { theme } from '@p2p-wallet-web/ui'; import { Button, Icon } from 'components/ui'; -import type { SwapRouteParams } from '../types'; - const ActionIcon = styled(Icon)` width: 16px; height: 16px; @@ -21,11 +19,12 @@ const ButtonStyled = styled(Button)` `; export const SettingsButton: FC = () => { - const history = useHistory(); - const { publicKey } = useParams(); + const navigate = useNavigate(); + const { publicKey } = useParams<{ publicKey?: string }>(); const handleShowSettings = () => { - history.push(generatePath('/swap/settings/:publicKey?', { publicKey })); + const pathTemplate = `/swap/settings${publicKey ? '/:publicKey' : ''}`; + navigate(generatePath(pathTemplate, { publicKey })); }; return ( diff --git a/packages/web/src/new/scenes/Main/Swap/Swap/Subviews/DetailsView/SlippageView/SlippageView.tsx b/packages/web/src/new/scenes/Main/Swap/Swap/Subviews/DetailsView/SlippageView/SlippageView.tsx index 3632fa91..756d4cec 100644 --- a/packages/web/src/new/scenes/Main/Swap/Swap/Subviews/DetailsView/SlippageView/SlippageView.tsx +++ b/packages/web/src/new/scenes/Main/Swap/Swap/Subviews/DetailsView/SlippageView/SlippageView.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; import { useCallback } from 'react'; -import { generatePath, useHistory, useParams } from 'react-router'; +import { generatePath, useNavigate, useParams } from 'react-router-dom'; import { styled } from '@linaria/react'; import { theme } from '@p2p-wallet-web/ui'; @@ -8,7 +8,6 @@ import { theme } from '@p2p-wallet-web/ui'; import { Icon } from 'components/ui'; import { Row, Text } from 'components/ui/AccordionDetails/common'; import type { SwapViewModel } from 'new/scenes/Main/Swap'; -import type { SwapRouteParams } from 'new/scenes/Main/Swap/Swap/types'; const PenIcon = styled(Icon)` width: 16px; @@ -26,12 +25,13 @@ interface Props { } export const SlippageView: FC = ({ viewModel }) => { - const history = useHistory(); - const { symbol } = useParams(); + const navigate = useNavigate(); + const { publicKey } = useParams<{ publicKey?: string }>(); const handleShowSettings = useCallback(() => { - history.push(generatePath('/swap/settings/:symbol?', { symbol })); - }, [history, symbol]); + const pathTemplate = `/swap/settings${publicKey ? '/:publicKey' : ''}`; + navigate(generatePath(pathTemplate, { publicKey })); + }, [navigate, publicKey]); return ( diff --git a/packages/web/src/new/scenes/Main/Swap/Swap/Swap.ViewModel.ts b/packages/web/src/new/scenes/Main/Swap/Swap/Swap.ViewModel.ts index 91f79b02..152fc2c7 100644 --- a/packages/web/src/new/scenes/Main/Swap/Swap/Swap.ViewModel.ts +++ b/packages/web/src/new/scenes/Main/Swap/Swap/Swap.ViewModel.ts @@ -167,23 +167,26 @@ export class SwapViewModel extends ViewModel implements SwapViewModelType { this.payingWallet = this._walletsRepository.nativeWallet; this.reload(); - const pubkey = this._getPubkey(); - const initialWallet = this._walletsRepository - .getWallets() - .find((wallet) => wallet.pubkey === pubkey); - // redirect to swap if don't found wallet with pubkey from URL - if (pubkey && !initialWallet) { - this._locationService.push('/swap'); - } + setTimeout(() => { + const pubkey = this._getPubkey(); + const initialWallet = this._walletsRepository + .getWallets() + .find((wallet) => wallet.pubkey === pubkey); + + // redirect to swap if don't found wallet with pubkey from URL + if (pubkey && !initialWallet) { + this._locationService.replace('/swap'); + } - this._bind(initialWallet ?? this._walletsRepository.nativeWallet); + this._bind(initialWallet ?? this._walletsRepository.nativeWallet); + }); }, ), ); } private _getPubkey(): string | undefined { - return this._locationService.getParams<{ publicKey?: string }>('/swap/:publicKey?').publicKey; + return this._locationService.getParams<'publicKey'>('/swap/:publicKey').publicKey; } protected override afterReactionsRemoved(): void { @@ -335,7 +338,10 @@ export class SwapViewModel extends ViewModel implements SwapViewModelType { return; } // @web: sync url with source wallet - this._locationService.push(`/swap/${wallet.pubkey}`); + const newPath = `/swap/${wallet.pubkey}`; + if (location.pathname !== newPath) { + this._locationService.push(newPath); + } this.payingWallet = wallet; }, diff --git a/packages/web/src/new/scenes/Main/Swap/Swap/types.ts b/packages/web/src/new/scenes/Main/Swap/Swap/types.ts index 4dcfee6b..d06ba060 100644 --- a/packages/web/src/new/scenes/Main/Swap/Swap/types.ts +++ b/packages/web/src/new/scenes/Main/Swap/Swap/types.ts @@ -1,7 +1,3 @@ -export interface SwapRouteParams { - publicKey?: string; -} - export enum VerificationError { swappingIsNotAvailable = 'swappingIsNotAvailable', sourceWalletIsEmpty = 'sourceWalletIsEmpty', diff --git a/packages/web/src/new/scenes/Main/Swap/SwapPage.tsx b/packages/web/src/new/scenes/Main/Swap/SwapPage.tsx index 65f971cc..5f24f776 100644 --- a/packages/web/src/new/scenes/Main/Swap/SwapPage.tsx +++ b/packages/web/src/new/scenes/Main/Swap/SwapPage.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; import { useMemo } from 'react'; -import { Route, Switch } from 'react-router-dom'; +import { Route, Routes } from 'react-router-dom'; import { useIsMobile } from '@p2p-wallet-web/ui'; @@ -29,27 +29,21 @@ export const SwapPage: FC = () => { } return ( - - - - - - - - + + } /> + } /> + ); }, [isMobile]); return ( - - - - - - - - + + } /> + } /> + + } /> + ); }; diff --git a/packages/web/src/new/scenes/Main/Swap/SwapSettings/SwapSettings.tsx b/packages/web/src/new/scenes/Main/Swap/SwapSettings/SwapSettings.tsx index 73973451..c243c17b 100644 --- a/packages/web/src/new/scenes/Main/Swap/SwapSettings/SwapSettings.tsx +++ b/packages/web/src/new/scenes/Main/Swap/SwapSettings/SwapSettings.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; import { useMemo } from 'react'; -import { generatePath, useParams } from 'react-router'; +import { generatePath, useParams } from 'react-router-dom'; import { styled } from '@linaria/react'; import { theme } from '@p2p-wallet-web/ui'; @@ -10,7 +10,6 @@ import { WidgetPageWithBottom } from 'components/common/WidgetPageWithBottom'; import { FeesView } from '../Subviews/FeesView'; import type { SwapViewModel } from '../Swap/Swap.ViewModel'; -import type { SwapRouteParams } from '../Swap/types'; import { DescriptionView } from './Subviews/DescriptionView'; import { SegmentedControl } from './Subviews/SegmentedControl'; @@ -57,9 +56,10 @@ interface Props { export const SwapSettings: FC = observer(({ viewModel: vm }) => { const viewModel = vm.swapSettingsViewModel; - // const viewModel = useViewModel(SwapSettingsViewModel); - const { symbol } = useParams(); - const backToPath = useMemo(() => generatePath('/swap/:symbol?', { symbol }), [symbol]); + + const { publicKey } = useParams<{ publicKey?: string }>(); + const pathTemplate = `/swap/${publicKey ? '/:publicKey' : ''}`; + const backToPath = useMemo(() => generatePath(pathTemplate, { publicKey }), [publicKey]); return ( diff --git a/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.ViewModel.ts b/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.ViewModel.ts index 4be98381..26f4bfc3 100644 --- a/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.ViewModel.ts +++ b/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.ViewModel.ts @@ -137,7 +137,7 @@ export class WalletDetailViewModel extends ViewModel { // @web: listen to changes in url this.addReaction( reaction( - () => this._locationService.getParams<{ pubkey?: string }>('/wallet/:pubkey').pubkey, + () => this._locationService.getParams<'pubkey'>('/wallet/:pubkey').pubkey, (pubkey) => { if (pubkey) { this.pubkey = pubkey; diff --git a/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.tsx b/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.tsx index 50110999..07f07899 100644 --- a/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.tsx +++ b/packages/web/src/new/scenes/Main/WalletDetail/WalletDetail.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import { observer } from 'mobx-react-lite'; import { expr } from 'mobx-utils'; diff --git a/packages/web/src/new/scenes/Root/Root.tsx b/packages/web/src/new/scenes/Root/Root.tsx index 4d79e3a8..51c815e3 100644 --- a/packages/web/src/new/scenes/Root/Root.tsx +++ b/packages/web/src/new/scenes/Root/Root.tsx @@ -1,6 +1,6 @@ import type { FC } from 'react'; import React from 'react'; -import { Redirect, useLocation } from 'react-router-dom'; +import { Navigate, useLocation } from 'react-router-dom'; import { observer } from 'mobx-react-lite'; @@ -18,14 +18,7 @@ export const Root: FC = observer(({ children }) => { const isAuth = location.pathname === '/' || location.pathname === '/onboard'; if (!rootViewModel.walletModel.connected && !isAuth) { - return ( - - ); + return ; } return <>{children}; diff --git a/packages/web/src/new/sdk/Analytics/hooks/useTrackOpenPageAction.ts b/packages/web/src/new/sdk/Analytics/hooks/useTrackOpenPageAction.ts index 4a32b7e3..ca7a667c 100644 --- a/packages/web/src/new/sdk/Analytics/hooks/useTrackOpenPageAction.ts +++ b/packages/web/src/new/sdk/Analytics/hooks/useTrackOpenPageAction.ts @@ -1,16 +1,16 @@ import { useEffect } from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import { trackEvent } from '../amplitude'; import type { OpenPageActionNames } from '../types'; export const useTrackOpenPageAction = (eventName: OpenPageActionNames) => { - const location = useLocation<{ fromPage?: string }>(); + const location = useLocation(); useEffect(() => { let lastScreen = null; - if (location.state?.fromPage && location.state?.fromPage !== location.pathname) { - lastScreen = location.state?.fromPage; + if (location.state?.fromPage && location.state.fromPage !== location.pathname) { + lastScreen = location.state.fromPage; } trackEvent({ diff --git a/packages/web/src/new/services/LocationService/LocationService.ts b/packages/web/src/new/services/LocationService/LocationService.ts index e05d5d01..429f8dda 100644 --- a/packages/web/src/new/services/LocationService/LocationService.ts +++ b/packages/web/src/new/services/LocationService/LocationService.ts @@ -1,68 +1,70 @@ -import { matchPath } from 'react-router'; +import isEqual from 'react-fast-compare'; +import type { Location, NavigateFunction, Params, Path } from 'react-router-dom'; +import { matchPath } from 'react-router-dom'; -import type { History, Location, LocationState, Path, UnregisterCallback } from 'history'; import { action, makeObservable, observable } from 'mobx'; import assert from 'ts-invariant'; import { singleton } from 'tsyringe'; @singleton() export class LocationService { - _location?: Location; - - private _history?: History; - private _removeListener?: UnregisterCallback; + private _location?: Location; + private _navigate?: NavigateFunction; constructor() { - makeObservable(this, { + makeObservable(this, { _location: observable, + + setLocation: action, }); } - private _assertHistory(): void { - assert(this._history, 'History is not set in LocationService'); + private _assertNavigate(): void { + assert(this._navigate, 'NavigateFunction is not set in LocationService'); } private _assertLocation(): void { assert(this._location, 'Location is not set in LocationService'); } - private _listenHistory(): void { - if (this._removeListener) { - this._removeListener(); + setLocation(location: Location): void { + if (!isEqual(this._location, location)) { + this._location = location; } - - this._assertHistory(); - this._removeListener = this._history!.listen( - action((location) => { - this._location = location; - }), - ); } - setHistory(history: History): void { - this._history = history; - - this._listenHistory(); + setNavigate(navigate: NavigateFunction): void { + this._navigate = navigate; } - getParams(pathTemplate: string): Params { + getParams(pathTemplate: string): Params { this._assertLocation(); - const match = matchPath(this._location!.pathname || '', { path: pathTemplate }); + + const match = matchPath( + { path: pathTemplate }, + this._location!.pathname || '', + ); if (!match) { - return {} as Params; + return {} as Params; } return match.params; } - push(pathname: Path, props?: LocationState): void { - this._assertHistory(); - this._history!.push(pathname, props ?? { fromPage: this._location?.pathname }); + push(pathname: Path | string, props?: Record): void { + this._assertNavigate(); + this._navigate!(pathname, { state: props ?? { fromPage: this._location?.pathname } }); + } + + replace(pathname: Path | string, props?: Record): void { + this._assertNavigate(); + this._assertLocation(); + this._navigate!(pathname, { state: props || this._location!.state, replace: true }); } reload(): void { - this._assertHistory(); - this._history!.go(0); + this._assertNavigate(); + this._navigate!(0); } } diff --git a/packages/web/src/new/ui/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx b/packages/web/src/new/ui/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx index 31b7f6fd..cef822e7 100644 --- a/packages/web/src/new/ui/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx +++ b/packages/web/src/new/ui/components/common/Layout/DesktopLayout/ColumnLeft/LeftNavMenu/LeftNavMenu.tsx @@ -1,6 +1,5 @@ import type { FunctionComponent } from 'react'; -import { useLocation } from 'react-router'; -import { Link, NavLink } from 'react-router-dom'; +import { Link, NavLink, useLocation } from 'react-router-dom'; import { styled } from '@linaria/react'; import { borders, shadows, theme, up } from '@p2p-wallet-web/ui'; @@ -147,10 +146,7 @@ export const LeftNavMenu: FunctionComponent = () => { return ( - + @@ -159,10 +155,7 @@ export const LeftNavMenu: FunctionComponent = () => { - + @@ -171,10 +164,7 @@ export const LeftNavMenu: FunctionComponent = () => { - + @@ -182,10 +172,7 @@ export const LeftNavMenu: FunctionComponent = () => { Receive - + @@ -193,10 +180,7 @@ export const LeftNavMenu: FunctionComponent = () => { Send - + @@ -204,10 +188,7 @@ export const LeftNavMenu: FunctionComponent = () => { Swap - + @@ -219,7 +200,7 @@ export const LeftNavMenu: FunctionComponent = () => { { = ({ viewModel }) => { @@ -120,7 +121,8 @@ export const MobileFooterTabs: FC = ({ viewModel }) => { diff --git a/packages/web/src/new/ui/managers/LocationManager/LocationManager.ViewModel.ts b/packages/web/src/new/ui/managers/LocationManager/LocationManager.ViewModel.ts index 623b26d8..324b7e0f 100644 --- a/packages/web/src/new/ui/managers/LocationManager/LocationManager.ViewModel.ts +++ b/packages/web/src/new/ui/managers/LocationManager/LocationManager.ViewModel.ts @@ -1,4 +1,5 @@ -import type { History } from 'history'; +import type { Location, NavigateFunction } from 'react-router-dom'; + import { singleton } from 'tsyringe'; import { ViewModel } from 'new/core/viewmodels/ViewModel'; @@ -16,7 +17,11 @@ export class LocationManagerViewModel extends ViewModel { protected override afterReactionsRemoved() {} - setHistory(history: History): void { - this._locationService.setHistory(history); + setLocation(location: Location): void { + this._locationService.setLocation(location); + } + + setNavigate(navigate: NavigateFunction): void { + this._locationService.setNavigate(navigate); } } diff --git a/packages/web/src/new/ui/managers/LocationManager/LocationManager.ts b/packages/web/src/new/ui/managers/LocationManager/LocationManager.tsx similarity index 52% rename from packages/web/src/new/ui/managers/LocationManager/LocationManager.ts rename to packages/web/src/new/ui/managers/LocationManager/LocationManager.tsx index abdfe597..f23ce5f1 100644 --- a/packages/web/src/new/ui/managers/LocationManager/LocationManager.ts +++ b/packages/web/src/new/ui/managers/LocationManager/LocationManager.tsx @@ -1,5 +1,5 @@ import { useLayoutEffect } from 'react'; -import { useHistory } from 'react-router'; +import { useLocation, useNavigate } from 'react-router-dom'; import { useViewModel } from 'new/core/viewmodels/useViewModel'; @@ -8,9 +8,11 @@ import { LocationManagerViewModel } from './LocationManager.ViewModel'; export const LocationManager = () => { const viewModel = useViewModel(LocationManagerViewModel); - const history = useHistory(); + const navigate = useNavigate(); + const location = useLocation(); - useLayoutEffect(() => viewModel.setHistory(history), [history]); + useLayoutEffect(() => viewModel.setNavigate(navigate), [navigate]); + useLayoutEffect(() => viewModel.setLocation(location), [location]); return null; }; diff --git a/packages/web/src/new/ui/modals/ActionsMobileModal/ActionsMobileModal.tsx b/packages/web/src/new/ui/modals/ActionsMobileModal/ActionsMobileModal.tsx index 2ad69966..54526b35 100644 --- a/packages/web/src/new/ui/modals/ActionsMobileModal/ActionsMobileModal.tsx +++ b/packages/web/src/new/ui/modals/ActionsMobileModal/ActionsMobileModal.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import { useHistory, useLocation } from 'react-router'; +import { useLocation, useNavigate } from 'react-router-dom'; import { styled } from '@linaria/react'; @@ -20,14 +20,14 @@ interface Props { } export const ActionsMobileModal: FC = ({ close, layoutViewModel }) => { - const history = useHistory(); + const navigate = useNavigate(); const location = useLocation(); const handleButtonClick = (route: string) => () => { close(false); if (location.pathname !== route) { - history.push(route, { fromPage: location.pathname }); + navigate(route, { state: { fromPage: location.pathname } }); } }; diff --git a/packages/web/src/new/ui/modals/ChooseBuyTokenMobileModal/ChooseBuyTokenMobileModal.tsx b/packages/web/src/new/ui/modals/ChooseBuyTokenMobileModal/ChooseBuyTokenMobileModal.tsx index 29e69c9e..81d0a858 100644 --- a/packages/web/src/new/ui/modals/ChooseBuyTokenMobileModal/ChooseBuyTokenMobileModal.tsx +++ b/packages/web/src/new/ui/modals/ChooseBuyTokenMobileModal/ChooseBuyTokenMobileModal.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import { useHistory, useLocation } from 'react-router'; +import { useLocation, useNavigate } from 'react-router-dom'; import { observer } from 'mobx-react-lite'; @@ -11,7 +11,7 @@ import { ChooseBuyTokenMobileModalViewModel } from 'new/ui/modals/ChooseBuyToken import { Modal } from 'new/ui/modals/Modal'; export const ChooseBuyTokenMobileModal: FC = observer(({ close }) => { - const history = useHistory(); + const navigate = useNavigate(); const location = useLocation(); const { solWallet, solToken, usdcWallet, usdcToken } = useViewModel( ChooseBuyTokenMobileModalViewModel, @@ -27,7 +27,7 @@ export const ChooseBuyTokenMobileModal: FC = observer(({ close } const newPath = `/buy/${cryptoCurrency.symbol}`; if (location.pathname !== newPath) { - history.push(newPath); + navigate(newPath); } }; diff --git a/packages/web/src/new/ui/modals/Modal/Modal.tsx b/packages/web/src/new/ui/modals/Modal/Modal.tsx index ef4acc6d..470d7108 100644 --- a/packages/web/src/new/ui/modals/Modal/Modal.tsx +++ b/packages/web/src/new/ui/modals/Modal/Modal.tsx @@ -1,7 +1,7 @@ import type { FunctionComponent } from 'react'; import * as React from 'react'; import { useEffect, useMemo, useRef, useState } from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import { animated, useSpring, useTransition } from 'react-spring'; import { styled } from '@linaria/react'; diff --git a/packages/web/src/new/ui/modals/ReceiveBitcoinModal/TopUp/TopUp.tsx b/packages/web/src/new/ui/modals/ReceiveBitcoinModal/TopUp/TopUp.tsx index c546515a..a59019e8 100644 --- a/packages/web/src/new/ui/modals/ReceiveBitcoinModal/TopUp/TopUp.tsx +++ b/packages/web/src/new/ui/modals/ReceiveBitcoinModal/TopUp/TopUp.tsx @@ -1,5 +1,5 @@ import type { FC } from 'react'; -import { useHistory } from 'react-router'; +import { useLocation, useNavigate } from 'react-router-dom'; import { styled } from '@linaria/react'; @@ -15,11 +15,12 @@ const IconStyled = styled(Icon)` `; export const TopUp: FC = ({ close }) => { - const history = useHistory(); + const navigate = useNavigate(); + const location = useLocation(); const handleTopUpClick = () => { close(false); - history.push('/buy'); + navigate('/buy', { state: { fromPage: location.pathname } }); }; return ( diff --git a/packages/web/src/utils/routes/UserRequiredRoute.tsx b/packages/web/src/utils/routes/UserRequiredRoute.tsx index 5725f6d9..825f468c 100644 --- a/packages/web/src/utils/routes/UserRequiredRoute.tsx +++ b/packages/web/src/utils/routes/UserRequiredRoute.tsx @@ -1,6 +1,6 @@ import type { FunctionComponent } from 'react'; -import type { RouteProps } from 'react-router'; -import { Redirect, Route, useLocation } from 'react-router-dom'; +import type { RouteProps } from 'react-router-dom'; +import { Navigate, Outlet, useLocation } from 'react-router-dom'; import { useViewModel } from 'new/core/viewmodels/useViewModel'; import { RootViewModel } from 'new/scenes/Root/Root.ViewModel'; @@ -10,29 +10,24 @@ export const ProtectedRoute: FunctionComponent< allow: boolean; redirect: string; } & RouteProps -> = ({ allow, redirect, ...props }) => { +> = ({ allow, redirect }) => { const location = useLocation(); - if (allow) { - return ; + if (!allow) { + return ( + + ); } - return ( - - ); + return ; }; // ProtectedRoute is used to create specific types.ts of protected routes like this... -export const AuthRequiredRoute: FunctionComponent = ({ ...props }) => { +export const AuthRequiredRoute: FunctionComponent = () => { const rootViewModel = useViewModel(RootViewModel); - return ( - - ); + return ; }; diff --git a/yarn.lock b/yarn.lock index 79922293..8a417e8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1559,7 +1559,7 @@ core-js-pure "^3.19.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.7.7", "@babel/runtime@^7.8.4": version "7.16.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== @@ -4809,6 +4809,11 @@ tiny-warning "^1.0.3" tslib "^2.3.0" +"@remix-run/router@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" + integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== + "@renproject/chains-bitcoin@^3.4.5": version "3.4.5" resolved "https://registry.yarnpkg.com/@renproject/chains-bitcoin/-/chains-bitcoin-3.4.5.tgz#39c391d99d5b16bb4787b7a979e97a7900d79c94" @@ -7070,7 +7075,7 @@ dependencies: "@types/geojson" "*" -"@types/history@*", "@types/history@^4.7.8": +"@types/history@^4.7.8": version "4.7.9" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.9.tgz#1cfb6d60ef3822c589f18e70f8b12f9a28ce8724" integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ== @@ -7417,23 +7422,6 @@ "@types/highcharts" "^5.0.44" "@types/react" "*" -"@types/react-router-dom@^5.1.6": - version "5.3.2" - resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.2.tgz#ebd8e145cf056db5c66eb1dac63c72f52e8542ee" - integrity sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ== - dependencies: - "@types/history" "*" - "@types/react" "*" - "@types/react-router" "*" - -"@types/react-router@*", "@types/react-router@^5.1.8": - version "5.1.17" - resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.17.tgz#087091006213b11042f39570e5cd414863693968" - integrity sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ== - dependencies: - "@types/history" "*" - "@types/react" "*" - "@types/react-stickynode@^3.0.1": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/react-stickynode/-/react-stickynode-3.0.2.tgz#5f71353344e8ad9f7b594fd19a8c10a65a310e4f" @@ -14987,18 +14975,6 @@ highlight.js@^10.1.1, highlight.js@~10.7.0: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== -history@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca" - integrity sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA== - dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^2.2.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^0.4.0" - history@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/history/-/history-5.0.0.tgz#0cabbb6c4bbf835addb874f8259f6d25101efd08" @@ -15006,18 +14982,6 @@ history@5.0.0: dependencies: "@babel/runtime" "^7.7.6" -history@^4.9.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" - integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== - 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" - history@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/history/-/history-5.2.0.tgz#7cdd31cf9bac3c5d31f09c231c9928fad0007b7c" @@ -15034,7 +14998,7 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -16331,11 +16295,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.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - 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" @@ -18218,7 +18177,7 @@ longest-streak@^2.0.0, longest-streak@^2.0.1: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== -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.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -18818,14 +18777,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.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e" - 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" @@ -20447,13 +20398,6 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - 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" @@ -22460,7 +22404,7 @@ react-is@17.0.2, "react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1, react-is@^17. resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: +react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -22547,19 +22491,6 @@ react-responsive@^9.0.0-beta.6: prop-types "^15.6.1" shallow-equal "^1.2.1" -react-router-dom@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363" - integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ== - dependencies: - "@babel/runtime" "^7.12.13" - history "^4.9.0" - loose-envify "^1.3.1" - prop-types "^15.6.2" - react-router "5.2.1" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - react-router-dom@^6.0.0: version "6.2.1" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.2.1.tgz#32ec81829152fbb8a7b045bf593a22eadf019bec" @@ -22568,21 +22499,13 @@ react-router-dom@^6.0.0: history "^5.2.0" react-router "6.2.1" -react-router@5.2.1, react-router@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d" - integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ== +react-router-dom@^6.4.3: + version "6.4.3" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.4.3.tgz#70093b5f65f85f1df9e5d4182eb7ff3a08299275" + integrity sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ== 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" + "@remix-run/router" "1.0.3" + react-router "6.4.3" react-router@6.2.1, react-router@^6.0.0: version "6.2.1" @@ -22591,6 +22514,13 @@ react-router@6.2.1, react-router@^6.0.0: dependencies: history "^5.2.0" +react-router@6.4.3: + version "6.4.3" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.4.3.tgz#9ed3ee4d6e95889e9b075a5d63e29acc7def0d49" + integrity sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA== + dependencies: + "@remix-run/router" "1.0.3" + react-scripts@4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345" @@ -23375,16 +23305,6 @@ resolve-global@1.0.0, resolve-global@^1.0.0: dependencies: global-dirs "^0.1.1" -resolve-pathname@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" - integrity sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg== - -resolve-pathname@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" - 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" @@ -25622,7 +25542,7 @@ 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.0.6, tiny-invariant@^1.1.0, tiny-invariant@^1.2.0: +tiny-invariant@^1.0.6, 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== @@ -25638,7 +25558,7 @@ tiny-secp256k1@^1.1.3: elliptic "^6.4.0" nan "^2.13.2" -tiny-warning@^1.0.0, tiny-warning@^1.0.3: +tiny-warning@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== @@ -26710,16 +26630,6 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -value-equal@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" - integrity sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw== - -value-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" - integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== - varint@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4"