From c269825309227d4600b3806fc217280917b46e5e Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:28:40 +0100 Subject: [PATCH 1/8] fix: use location.state to store background route to prevent unmount using modals, closes #4028 --- src/app/common/hooks/use-location-state.ts | 4 ---- .../receive/receive-collectible.tsx | 12 ++++++----- src/app/features/asset-list/asset-list.tsx | 3 +-- .../components/bitcoin/inscription.tsx | 4 +++- .../settings-dropdown/settings-dropdown.tsx | 17 ++++++++++++--- src/app/pages/home/components/home-tabs.tsx | 10 ++++----- .../pages/home/components/receive-button.tsx | 10 +++++++-- src/app/pages/home/home.tsx | 18 ++++++++++++---- .../components/receive-tokens.layout.tsx | 6 +++--- .../pages/receive-tokens/receive-modal.tsx | 21 ++++++++++++++++--- src/app/routes/app-routes.tsx | 5 +++-- 11 files changed, 76 insertions(+), 34 deletions(-) diff --git a/src/app/common/hooks/use-location-state.ts b/src/app/common/hooks/use-location-state.ts index db1a95f496e..32ea45c1aef 100644 --- a/src/app/common/hooks/use-location-state.ts +++ b/src/app/common/hooks/use-location-state.ts @@ -5,15 +5,11 @@ import get from 'lodash.get'; import { isUndefined } from '@shared/utils'; -export function useLocationState(propName: string): string | undefined; -export function useLocationState(propName: string, defaultValue: string): string; export function useLocationState(propName: string, defaultValue?: string) { const location = useLocation(); return get(location, `state.${propName}`, defaultValue); } -export function useLocationStateWithCache(propName: string): T | undefined; -export function useLocationStateWithCache(propName: string, defaultValue: T): T; export function useLocationStateWithCache(propName: string, defaultValue?: T) { const location = useLocation(); const [value, setValue] = useState(defaultValue); diff --git a/src/app/components/receive/receive-collectible.tsx b/src/app/components/receive/receive-collectible.tsx index bfb5b40e389..85844cca0a3 100644 --- a/src/app/components/receive/receive-collectible.tsx +++ b/src/app/components/receive/receive-collectible.tsx @@ -1,14 +1,14 @@ import toast from 'react-hot-toast'; -import { useLocation, useNavigate } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import BitcoinStampImg from '@assets/images/bitcoin-stamp.png'; import { Box, Stack, useClipboard } from '@stacks/ui'; import { HomePageSelectors } from '@tests/selectors/home.selectors'; -import get from 'lodash.get'; import { RouteUrls } from '@shared/route-urls'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar'; import { OrdinalIcon } from '@app/components/icons/ordinal-icon'; import { useZeroIndexTaprootAddress } from '@app/query/bitcoin/ordinals/use-zero-index-taproot-address'; @@ -19,9 +19,9 @@ import { ReceiveCollectibleItem } from './receive-collectible-item'; export function ReceiveCollectible() { const analytics = useAnalytics(); - const location = useLocation(); + const backgroundLocation = useLocationState('backgroundLocation'); + const accountIndex = useLocationState('accountIndex'); const navigate = useNavigate(); - const accountIndex = get(location.state, 'accountIndex', undefined); const btcAddressNativeSegwit = useCurrentAccountNativeSegwitAddressIndexZero(); const btcAddressTaproot = useZeroIndexTaprootAddress(accountIndex); @@ -54,7 +54,9 @@ export function ReceiveCollectible() { data-testid={HomePageSelectors.ReceiveBtcTaprootQrCodeBtn} onCopyAddress={() => { void analytics.track('select_inscription_to_add_new_collectible'); - navigate(RouteUrls.ReceiveCollectibleOrdinal, { state: { btcAddressTaproot } }); + navigate(RouteUrls.ReceiveCollectibleOrdinal, { + state: { btcAddressTaproot, backgroundLocation }, + }); }} title="Ordinal inscription" /> diff --git a/src/app/features/asset-list/asset-list.tsx b/src/app/features/asset-list/asset-list.tsx index 6052f794b11..683b727c302 100644 --- a/src/app/features/asset-list/asset-list.tsx +++ b/src/app/features/asset-list/asset-list.tsx @@ -1,5 +1,4 @@ -import { Outlet } from 'react-router-dom'; -import { useNavigate } from 'react-router-dom'; +import { Outlet, useNavigate } from 'react-router-dom'; import { Box, Stack } from '@stacks/ui'; import { HomePageSelectorsLegacy } from '@tests-legacy/page-objects/home.selectors'; diff --git a/src/app/features/collectibles/components/bitcoin/inscription.tsx b/src/app/features/collectibles/components/bitcoin/inscription.tsx index 4a6b4cb78f3..7efebf78904 100644 --- a/src/app/features/collectibles/components/bitcoin/inscription.tsx +++ b/src/app/features/collectibles/components/bitcoin/inscription.tsx @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { Inscription as InscriptionType } from '@shared/models/inscription.model'; import { RouteUrls } from '@shared/route-urls'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { openInNewTab } from '@app/common/utils/open-in-new-tab'; import { OrdinalIconFull } from '@app/components/icons/ordinal-icon-full'; import { OrdinalMinimalIcon } from '@app/components/icons/ordinal-minimal-icon'; @@ -18,10 +19,11 @@ interface InscriptionProps { export function Inscription({ rawInscription }: InscriptionProps) { const inscription = convertInscriptionToSupportedInscriptionType(rawInscription); const navigate = useNavigate(); + const backgroundLocation = useLocationState('backgroundLocation'); function openSendInscriptionModal() { navigate(RouteUrls.SendOrdinalInscription, { - state: { inscription }, + state: { inscription, backgroundLocation }, }); } diff --git a/src/app/features/settings-dropdown/settings-dropdown.tsx b/src/app/features/settings-dropdown/settings-dropdown.tsx index 8e4850ab034..71848890bfb 100644 --- a/src/app/features/settings-dropdown/settings-dropdown.tsx +++ b/src/app/features/settings-dropdown/settings-dropdown.tsx @@ -11,6 +11,7 @@ import { RouteUrls } from '@shared/route-urls'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; import { useDrawers } from '@app/common/hooks/use-drawers'; import { useKeyActions } from '@app/common/hooks/use-key-actions'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { useModifierKey } from '@app/common/hooks/use-modifier-key'; import { useOnClickOutside } from '@app/common/hooks/use-onclickoutside'; import { useWalletType } from '@app/common/use-wallet-type'; @@ -47,6 +48,7 @@ export function SettingsDropdown() { const key = useCurrentKeyDetails(); const { isPressed: showAdvancedMenuOptions } = useModifierKey('alt', 120); const location = useLocation(); + const backgroundLocation = useLocationState('backgroundLocation'); const handleClose = useCallback(() => setIsShowingSettings(false), [setIsShowingSettings]); @@ -95,7 +97,10 @@ export function SettingsDropdown() { data-testid={SettingsSelectors.ToggleTheme} onClick={wrappedCloseCallback(() => { void analytics.track('click_change_theme_menu_item'); - navigate(RouteUrls.ChangeTheme, { relative: 'path' }); + navigate(RouteUrls.ChangeTheme, { + relative: 'path', + state: { backgroundLocation }, + }); })} > Change theme @@ -147,7 +152,10 @@ export function SettingsDropdown() { data-testid={SettingsSelectors.ChangeNetworkAction} onClick={wrappedCloseCallback(() => { void analytics.track('click_change_network_menu_item'); - navigate(RouteUrls.SelectNetwork, { relative: 'path' }); + navigate(RouteUrls.SelectNetwork, { + relative: 'path', + state: { backgroundLocation }, + }); })} > @@ -178,7 +186,10 @@ export function SettingsDropdown() { - navigate(RouteUrls.SignOutConfirm, { relative: 'path' }) + navigate(RouteUrls.SignOutConfirm, { + relative: 'path', + state: { backgroundLocation }, + }) )} data-testid="settings-sign-out" > diff --git a/src/app/pages/home/components/home-tabs.tsx b/src/app/pages/home/components/home-tabs.tsx index a15a314d07a..003462906a0 100644 --- a/src/app/pages/home/components/home-tabs.tsx +++ b/src/app/pages/home/components/home-tabs.tsx @@ -6,6 +6,7 @@ import type { StackProps } from '@stacks/ui'; import { RouteUrls } from '@shared/route-urls'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { LoadingSpinner } from '@app/components/loading-spinner'; import { Tabs } from '@app/components/tabs'; @@ -16,6 +17,7 @@ interface HomeTabsProps extends StackProps { export function HomeTabs({ children }: HomeTabsProps) { const navigate = useNavigate(); const { pathname } = useLocation(); + const backgroundLocation = useLocationState('backgroundLocation'); const tabs = useMemo( () => [ @@ -25,16 +27,14 @@ export function HomeTabs({ children }: HomeTabsProps) { [] ); - const getActiveTab = useCallback( - () => tabs.findIndex(tab => tab.slug === pathname), - [tabs, pathname] - ); + const path = backgroundLocation ? backgroundLocation.pathname : pathname; + + const getActiveTab = useCallback(() => tabs.findIndex(tab => tab.slug === path), [tabs, path]); const setActiveTab = useCallback( (index: number) => navigate(tabs[index]?.slug), [navigate, tabs] ); - return ( navigate(isBitcoinEnabled ? RouteUrls.Receive : RouteUrls.ReceiveStx)} + onClick={() => + navigate(receivePath, { + state: { backgroundLocation: location }, + }) + } {...props} /> ); diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index 6e7a64f7190..55745215340 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -1,16 +1,18 @@ -import { Outlet, useNavigate } from 'react-router-dom'; +import { Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; import { RouteUrls } from '@shared/route-urls'; import { useTrackFirstDeposit } from '@app/common/hooks/analytics/transactions-analytics.hooks'; import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { useOnMount } from '@app/common/hooks/use-on-mount'; import { useRouteHeader } from '@app/common/hooks/use-route-header'; import { Header } from '@app/components/header'; +import { ActivityList } from '@app/features/activity-list/activity-list'; +import { AssetsList } from '@app/features/asset-list/asset-list'; import { InAppMessages } from '@app/features/hiro-messages/in-app-messages'; import { SuggestedFirstSteps } from '@app/features/suggested-first-steps/suggested-first-steps'; import { HomeActions } from '@app/pages/home/components/home-actions'; -import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; import { CurrentAccount } from './components/account-area'; import { HomeTabs } from './components/home-tabs'; @@ -19,8 +21,10 @@ import { HomeLayout } from './components/home.layout'; export function Home() { const { decodedAuthRequest } = useOnboardingState(); - const stacksAccount = useCurrentStacksAccount(); const navigate = useNavigate(); + + const location = useLocation(); + const backgroundLocation = useLocationState('backgroundLocation'); useTrackFirstDeposit(); useRouteHeader( @@ -41,7 +45,13 @@ export function Home() { actions={} > - + <> + + } /> + } /> + + {backgroundLocation && } + ); diff --git a/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx b/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx index bb15e7b778a..8446f828605 100644 --- a/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx +++ b/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx @@ -4,8 +4,7 @@ import { useNavigate } from 'react-router-dom'; import { Box, Button, Flex, Text, color } from '@stacks/ui'; import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; -import { RouteUrls } from '@shared/route-urls'; - +import { useLocationState } from '@app/common/hooks/use-location-state'; import { AddressDisplayer } from '@app/components/address-displayer/address-displayer'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; import { Title } from '@app/components/typography'; @@ -23,9 +22,10 @@ interface ReceiveTokensLayoutProps { export function ReceiveTokensLayout(props: ReceiveTokensLayoutProps) { const { address, accountName, onCopyAddressToClipboard, title, warning, hasSubtitle } = props; const navigate = useNavigate(); + const { pathname } = useLocationState('backgroundLocation'); return ( - navigate(RouteUrls.Home)}> + navigate(pathname)}> {hasSubtitle && ( diff --git a/src/app/pages/receive-tokens/receive-modal.tsx b/src/app/pages/receive-tokens/receive-modal.tsx index 859d256f5c5..ed053f2505c 100644 --- a/src/app/pages/receive-tokens/receive-modal.tsx +++ b/src/app/pages/receive-tokens/receive-modal.tsx @@ -9,6 +9,7 @@ import { HomePageSelectors } from '@tests/selectors/home.selectors'; import { RouteUrls } from '@shared/route-urls'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { StxAvatar } from '@app/components/crypto-assets/stacks/components/stx-avatar'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; import { BtcIcon } from '@app/components/icons/btc-icon'; @@ -22,6 +23,7 @@ import { useCurrentAccountStxAddressState } from '@app/store/accounts/blockchain export function ReceiveModal() { const analytics = useAnalytics(); const navigate = useNavigate(); + const backgroundLocation = useLocationState('backgroundLocation'); const btcAddress = useCurrentAccountNativeSegwitAddressIndexZero(); const stxAddress = useCurrentAccountStxAddressState(); const { onCopy: onCopyStacks } = useClipboard(stxAddress); @@ -31,8 +33,13 @@ export function ReceiveModal() { toast.success('Copied to clipboard!'); copyHandler(); } + return ( - navigate('../')}> + navigate(backgroundLocation?.pathname)} + > Tokens @@ -49,7 +56,11 @@ export function ReceiveModal() { borderRadius="10px" data-testid={HomePageSelectors.ReceiveBtcNativeSegwitQrCodeBtn} mode="tertiary" - onClick={() => navigate(RouteUrls.ReceiveBtc)} + onClick={() => + navigate(RouteUrls.ReceiveBtc, { + state: { backgroundLocation }, + }) + } > @@ -79,7 +90,11 @@ export function ReceiveModal() { borderRadius="10px" data-testid={HomePageSelectors.ReceiveStxQrCodeBtn} mode="tertiary" - onClick={() => navigate(RouteUrls.ReceiveStx)} + onClick={() => + navigate(RouteUrls.ReceiveStx, { + state: { backgroundLocation }, + }) + } > diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index ebe47cc768e..b2bda7a3f31 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -187,8 +187,9 @@ function useAppRoutes() { } > } /> - } /> - + }> + {settingsModalRoutes} + {requestBitcoinKeysRoutes} {requestStacksKeysRoutes} } /> From 5c0e4a381aa288c281d7b9f164073ae8f7554a8f Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Thu, 27 Jul 2023 09:58:41 +0100 Subject: [PATCH 2/8] fix: use useLocationState for cleaner code, closes #4028 --- src/app/features/settings-dropdown/settings-dropdown.tsx | 8 ++++---- .../receive-collectible/receive-collectible-oridinal.tsx | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/features/settings-dropdown/settings-dropdown.tsx b/src/app/features/settings-dropdown/settings-dropdown.tsx index 71848890bfb..7da8015918b 100644 --- a/src/app/features/settings-dropdown/settings-dropdown.tsx +++ b/src/app/features/settings-dropdown/settings-dropdown.tsx @@ -48,7 +48,7 @@ export function SettingsDropdown() { const key = useCurrentKeyDetails(); const { isPressed: showAdvancedMenuOptions } = useModifierKey('alt', 120); const location = useLocation(); - const backgroundLocation = useLocationState('backgroundLocation'); + // const backgroundLocation = useLocationState('backgroundLocation'); const handleClose = useCallback(() => setIsShowingSettings(false), [setIsShowingSettings]); @@ -99,7 +99,7 @@ export function SettingsDropdown() { void analytics.track('click_change_theme_menu_item'); navigate(RouteUrls.ChangeTheme, { relative: 'path', - state: { backgroundLocation }, + state: { backgroundLocation: location }, }); })} > @@ -154,7 +154,7 @@ export function SettingsDropdown() { void analytics.track('click_change_network_menu_item'); navigate(RouteUrls.SelectNetwork, { relative: 'path', - state: { backgroundLocation }, + state: { backgroundLocation: location }, }); })} > @@ -188,7 +188,7 @@ export function SettingsDropdown() { onClick={wrappedCloseCallback(() => navigate(RouteUrls.SignOutConfirm, { relative: 'path', - state: { backgroundLocation }, + state: { backgroundLocation: location }, }) )} data-testid="settings-sign-out" diff --git a/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx b/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx index 7b774ff3750..1e5a08dec01 100644 --- a/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx +++ b/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx @@ -6,6 +6,7 @@ import { Box, Flex, Stack, color, useClipboard } from '@stacks/ui'; import { truncateMiddle } from '@stacks/ui-utils'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { openInNewTab } from '@app/common/utils/open-in-new-tab'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; import { ErrorLabel } from '@app/components/error-label'; @@ -18,6 +19,7 @@ export function ReceiveCollectibleOrdinal() { const navigate = useNavigate(); const analytics = useAnalytics(); const { state } = useLocation(); + const { pathname } = useLocationState('backgroundLocation'); const { onCopy } = useClipboard(state.btcAddressTaproot); function copyToClipboard() { @@ -27,7 +29,7 @@ export function ReceiveCollectibleOrdinal() { } return ( - navigate('../')}> + navigate(pathname)}> From de2e7c50f331a76589c1f219a28c76437ad6acd6 Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Thu, 27 Jul 2023 10:05:52 +0100 Subject: [PATCH 3/8] fix: use useLocationState for cleaner code, closes #4028 --- .../components/bitcoin/inscription.tsx | 7 +++---- .../settings-dropdown/settings-dropdown.tsx | 2 -- src/app/pages/home/home.tsx | 5 ++++- src/app/routes/app-routes.tsx | 16 ++++++++-------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/app/features/collectibles/components/bitcoin/inscription.tsx b/src/app/features/collectibles/components/bitcoin/inscription.tsx index 7efebf78904..079ce31291d 100644 --- a/src/app/features/collectibles/components/bitcoin/inscription.tsx +++ b/src/app/features/collectibles/components/bitcoin/inscription.tsx @@ -1,9 +1,8 @@ -import { useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { Inscription as InscriptionType } from '@shared/models/inscription.model'; import { RouteUrls } from '@shared/route-urls'; -import { useLocationState } from '@app/common/hooks/use-location-state'; import { openInNewTab } from '@app/common/utils/open-in-new-tab'; import { OrdinalIconFull } from '@app/components/icons/ordinal-icon-full'; import { OrdinalMinimalIcon } from '@app/components/icons/ordinal-minimal-icon'; @@ -19,11 +18,11 @@ interface InscriptionProps { export function Inscription({ rawInscription }: InscriptionProps) { const inscription = convertInscriptionToSupportedInscriptionType(rawInscription); const navigate = useNavigate(); - const backgroundLocation = useLocationState('backgroundLocation'); + const location = useLocation(); function openSendInscriptionModal() { navigate(RouteUrls.SendOrdinalInscription, { - state: { inscription, backgroundLocation }, + state: { inscription, backgroundLocation: location }, }); } diff --git a/src/app/features/settings-dropdown/settings-dropdown.tsx b/src/app/features/settings-dropdown/settings-dropdown.tsx index 7da8015918b..9e859e9cdb9 100644 --- a/src/app/features/settings-dropdown/settings-dropdown.tsx +++ b/src/app/features/settings-dropdown/settings-dropdown.tsx @@ -11,7 +11,6 @@ import { RouteUrls } from '@shared/route-urls'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; import { useDrawers } from '@app/common/hooks/use-drawers'; import { useKeyActions } from '@app/common/hooks/use-key-actions'; -import { useLocationState } from '@app/common/hooks/use-location-state'; import { useModifierKey } from '@app/common/hooks/use-modifier-key'; import { useOnClickOutside } from '@app/common/hooks/use-onclickoutside'; import { useWalletType } from '@app/common/use-wallet-type'; @@ -48,7 +47,6 @@ export function SettingsDropdown() { const key = useCurrentKeyDetails(); const { isPressed: showAdvancedMenuOptions } = useModifierKey('alt', 120); const location = useLocation(); - // const backgroundLocation = useLocationState('backgroundLocation'); const handleClose = useCallback(() => setIsShowingSettings(false), [setIsShowingSettings]); diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index 55745215340..fa30da712f5 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -13,6 +13,7 @@ import { AssetsList } from '@app/features/asset-list/asset-list'; import { InAppMessages } from '@app/features/hiro-messages/in-app-messages'; import { SuggestedFirstSteps } from '@app/features/suggested-first-steps/suggested-first-steps'; import { HomeActions } from '@app/pages/home/components/home-actions'; +import { settingsModalRoutes } from '@app/routes/app-routes'; import { CurrentAccount } from './components/account-area'; import { HomeTabs } from './components/home-tabs'; @@ -48,7 +49,9 @@ export function Home() { <> } /> - } /> + }> + {settingsModalRoutes} + {backgroundLocation && } diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index b2bda7a3f31..292e8bd9a2f 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -70,6 +70,14 @@ export function AppRoutes() { return ; } +export const settingsModalRoutes = ( + + } /> + } /> + } /> + +); + function useAppRoutes() { const userHasNotConsentedToDiagnostics = useHasUserRespondedToAnalyticsConsent(); @@ -83,14 +91,6 @@ function useAppRoutes() { ) ); - const settingsModalRoutes = ( - - } /> - } /> - } /> - - ); - const legacyRequestRoutes = ( <> Date: Thu, 27 Jul 2023 14:11:38 +0100 Subject: [PATCH 4/8] fix: WIP with catchall route to handle opening in new tab, closes #4028 --- .../settings-dropdown/settings-dropdown.tsx | 3 --- src/app/features/theme-drawer/theme-drawer.tsx | 4 +++- src/app/pages/home/home.tsx | 9 ++++----- src/app/pages/receive-tokens/receive-modal.tsx | 3 ++- src/app/pages/select-network/select-network.tsx | 4 +++- src/app/routes/app-routes.tsx | 16 ++++++++-------- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/app/features/settings-dropdown/settings-dropdown.tsx b/src/app/features/settings-dropdown/settings-dropdown.tsx index 9e859e9cdb9..461810603c8 100644 --- a/src/app/features/settings-dropdown/settings-dropdown.tsx +++ b/src/app/features/settings-dropdown/settings-dropdown.tsx @@ -96,7 +96,6 @@ export function SettingsDropdown() { onClick={wrappedCloseCallback(() => { void analytics.track('click_change_theme_menu_item'); navigate(RouteUrls.ChangeTheme, { - relative: 'path', state: { backgroundLocation: location }, }); })} @@ -151,7 +150,6 @@ export function SettingsDropdown() { onClick={wrappedCloseCallback(() => { void analytics.track('click_change_network_menu_item'); navigate(RouteUrls.SelectNetwork, { - relative: 'path', state: { backgroundLocation: location }, }); })} @@ -185,7 +183,6 @@ export function SettingsDropdown() { color={color('feedback-error')} onClick={wrappedCloseCallback(() => navigate(RouteUrls.SignOutConfirm, { - relative: 'path', state: { backgroundLocation: location }, }) )} diff --git a/src/app/features/theme-drawer/theme-drawer.tsx b/src/app/features/theme-drawer/theme-drawer.tsx index 4a363ca3cec..6ef48e90442 100644 --- a/src/app/features/theme-drawer/theme-drawer.tsx +++ b/src/app/features/theme-drawer/theme-drawer.tsx @@ -1,13 +1,15 @@ import { useNavigate } from 'react-router-dom'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; import { ThemeList } from './theme-list'; export function ThemesDrawer() { const navigate = useNavigate(); + const backgroundLocation = useLocationState('backgroundLocation'); return ( - navigate('..')}> + navigate(backgroundLocation)}> ); diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index fa30da712f5..8c3be39d2ae 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -1,4 +1,4 @@ -import { Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; +import { Navigate, Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; import { RouteUrls } from '@shared/route-urls'; @@ -13,7 +13,6 @@ import { AssetsList } from '@app/features/asset-list/asset-list'; import { InAppMessages } from '@app/features/hiro-messages/in-app-messages'; import { SuggestedFirstSteps } from '@app/features/suggested-first-steps/suggested-first-steps'; import { HomeActions } from '@app/pages/home/components/home-actions'; -import { settingsModalRoutes } from '@app/routes/app-routes'; import { CurrentAccount } from './components/account-area'; import { HomeTabs } from './components/home-tabs'; @@ -49,9 +48,9 @@ export function Home() { <> } /> - }> - {settingsModalRoutes} - + } /> + {/* If we have an unmatched route go back home e.g. if a new tab is opened */} + } /> {backgroundLocation && } diff --git a/src/app/pages/receive-tokens/receive-modal.tsx b/src/app/pages/receive-tokens/receive-modal.tsx index ed053f2505c..e9861be6365 100644 --- a/src/app/pages/receive-tokens/receive-modal.tsx +++ b/src/app/pages/receive-tokens/receive-modal.tsx @@ -38,7 +38,8 @@ export function ReceiveModal() { navigate(backgroundLocation?.pathname)} + // if open in new tab - backgroundLocation?.pathname can be lost + onClose={() => navigate(backgroundLocation?.pathname || '..')} > Tokens diff --git a/src/app/pages/select-network/select-network.tsx b/src/app/pages/select-network/select-network.tsx index 17573742a28..e9055c8afdd 100644 --- a/src/app/pages/select-network/select-network.tsx +++ b/src/app/pages/select-network/select-network.tsx @@ -4,6 +4,7 @@ import { WalletDefaultNetworkConfigurationIds } from '@shared/constants'; import { RouteUrls } from '@shared/route-urls'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; import { NetworkListLayout } from '@app/pages/select-network/components/network-list.layout'; import { NetworkListItem } from '@app/pages/select-network/network-list-item'; @@ -20,6 +21,7 @@ export function SelectNetwork() { const analytics = useAnalytics(); const networksActions = useNetworksActions(); const currentNetwork = useCurrentNetworkState(); + const backgroundLocation = useLocationState('backgroundLocation'); function addNetwork() { void analytics.track('add_network'); @@ -38,7 +40,7 @@ export function SelectNetwork() { } function closeNetworkModal() { - navigate('..'); + navigate(backgroundLocation || '..'); } return ( diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index 292e8bd9a2f..b2bda7a3f31 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -70,14 +70,6 @@ export function AppRoutes() { return ; } -export const settingsModalRoutes = ( - - } /> - } /> - } /> - -); - function useAppRoutes() { const userHasNotConsentedToDiagnostics = useHasUserRespondedToAnalyticsConsent(); @@ -91,6 +83,14 @@ function useAppRoutes() { ) ); + const settingsModalRoutes = ( + + } /> + } /> + } /> + + ); + const legacyRequestRoutes = ( <> Date: Thu, 27 Jul 2023 16:17:42 +0100 Subject: [PATCH 5/8] fix: WIP allow modals to be opened in a new tab --- .../features/theme-drawer/theme-drawer.tsx | 2 +- src/app/pages/home/components/home-tabs.tsx | 17 ++++- src/app/pages/home/home.tsx | 7 +- .../receive-collectible-oridinal.tsx | 16 +++-- src/app/routes/app-routes.tsx | 69 +++++++++---------- 5 files changed, 64 insertions(+), 47 deletions(-) diff --git a/src/app/features/theme-drawer/theme-drawer.tsx b/src/app/features/theme-drawer/theme-drawer.tsx index 6ef48e90442..3843f6d4e17 100644 --- a/src/app/features/theme-drawer/theme-drawer.tsx +++ b/src/app/features/theme-drawer/theme-drawer.tsx @@ -9,7 +9,7 @@ export function ThemesDrawer() { const navigate = useNavigate(); const backgroundLocation = useLocationState('backgroundLocation'); return ( - navigate(backgroundLocation)}> + navigate(backgroundLocation || '..')}> ); diff --git a/src/app/pages/home/components/home-tabs.tsx b/src/app/pages/home/components/home-tabs.tsx index 003462906a0..f95af4aa80d 100644 --- a/src/app/pages/home/components/home-tabs.tsx +++ b/src/app/pages/home/components/home-tabs.tsx @@ -16,7 +16,7 @@ interface HomeTabsProps extends StackProps { // TODO #4013: Abstract this to generic RouteTab once choose-fee-tab updated export function HomeTabs({ children }: HomeTabsProps) { const navigate = useNavigate(); - const { pathname } = useLocation(); + const location = useLocation(); const backgroundLocation = useLocationState('backgroundLocation'); const tabs = useMemo( @@ -27,9 +27,20 @@ export function HomeTabs({ children }: HomeTabsProps) { [] ); - const path = backgroundLocation ? backgroundLocation.pathname : pathname; + // if(pathname === 'receive' && !backgroundLocation){ - const getActiveTab = useCallback(() => tabs.findIndex(tab => tab.slug === path), [tabs, path]); + // } + // const path = backgroundLocation ? backgroundLocation.pathname : location?.pathname; + + // console.info('home-tabs bg location', backgroundLocation); + // console.info('home-tabs location', location); + + // if open new tab and cannot find location then set tab to be first + const getActiveTab = useCallback(() => { + const path = backgroundLocation ? backgroundLocation.pathname : location?.pathname; + const activeTab = tabs.findIndex(tab => tab.slug === path); + return activeTab === -1 ? 0 : activeTab; + }, [tabs, backgroundLocation, location]); const setActiveTab = useCallback( (index: number) => navigate(tabs[index]?.slug), diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index 8c3be39d2ae..460aed97d67 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -1,4 +1,4 @@ -import { Navigate, Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; +import { Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; import { RouteUrls } from '@shared/route-urls'; @@ -13,6 +13,7 @@ import { AssetsList } from '@app/features/asset-list/asset-list'; import { InAppMessages } from '@app/features/hiro-messages/in-app-messages'; import { SuggestedFirstSteps } from '@app/features/suggested-first-steps/suggested-first-steps'; import { HomeActions } from '@app/pages/home/components/home-actions'; +import { homeModalRoutes } from '@app/routes/app-routes'; import { CurrentAccount } from './components/account-area'; import { HomeTabs } from './components/home-tabs'; @@ -37,7 +38,6 @@ export function Home() { useOnMount(() => { if (decodedAuthRequest) navigate(RouteUrls.ChooseAccount); }); - return ( } @@ -49,8 +49,7 @@ export function Home() { } /> } /> - {/* If we have an unmatched route go back home e.g. if a new tab is opened */} - } /> + {homeModalRoutes} {backgroundLocation && } diff --git a/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx b/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx index 1e5a08dec01..b73f3517d94 100644 --- a/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx +++ b/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx @@ -19,8 +19,16 @@ export function ReceiveCollectibleOrdinal() { const navigate = useNavigate(); const analytics = useAnalytics(); const { state } = useLocation(); - const { pathname } = useLocationState('backgroundLocation'); - const { onCopy } = useClipboard(state.btcAddressTaproot); + const backgroundLocation = useLocationState('backgroundLocation'); + + // if this is opened in a new tab it has no btcAddress so we cannot do anything + if (!state) { + // TODO implement this more gracefull to simply not load this component at all if no state.btcAdressTaproot + navigate('..'); + console.log('state.btcAddressTaproot', state); + } + + const { onCopy } = useClipboard(state?.btcAddressTaproot); function copyToClipboard() { void analytics.track('copy_address_to_add_new_inscription'); @@ -29,7 +37,7 @@ export function ReceiveCollectibleOrdinal() { } return ( - navigate(pathname)}> + navigate(backgroundLocation?.pathname || '..')}> @@ -84,7 +92,7 @@ export function ReceiveCollectibleOrdinal() { difficulty retrieving it - {truncateMiddle(state.btcAddressTaproot, 6)} + {truncateMiddle(state?.btcAddressTaproot, 6)} diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index b2bda7a3f31..f6101d23c0b 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -69,6 +69,35 @@ export function AppRoutes() { const routes = useAppRoutes(); return ; } +const settingsModalRoutes = ( + + } /> + } /> + } /> + +); + +const sendOrdinalRoutes = ( + }> + } /> + } + /> + } /> + } /> + } /> + +); + +export const homeModalRoutes = ( + + } /> + } /> + {sendOrdinalRoutes} + {settingsModalRoutes} + +); function useAppRoutes() { const userHasNotConsentedToDiagnostics = useHasUserRespondedToAnalyticsConsent(); @@ -83,14 +112,6 @@ function useAppRoutes() { ) ); - const settingsModalRoutes = ( - - } /> - } /> - } /> - - ); - const legacyRequestRoutes = ( <> } /> - }> - {settingsModalRoutes} - + } /> + {requestBitcoinKeysRoutes} {requestStacksKeysRoutes} } /> @@ -199,34 +219,13 @@ function useAppRoutes() { } /> } /> - - } /> } /> - } - /> + } /> } /> + {homeModalRoutes} + {sendOrdinalRoutes} - }> - } /> - } - /> - } - /> - } - /> - } /> - - - {settingsModalRoutes} {ledgerStacksTxSigningRoutes} Date: Fri, 28 Jul 2023 09:33:45 +0100 Subject: [PATCH 6/8] fix: reinstate overloads and update types --- src/app/common/hooks/use-location-state.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/app/common/hooks/use-location-state.ts b/src/app/common/hooks/use-location-state.ts index 32ea45c1aef..abc100b72f4 100644 --- a/src/app/common/hooks/use-location-state.ts +++ b/src/app/common/hooks/use-location-state.ts @@ -5,11 +5,18 @@ import get from 'lodash.get'; import { isUndefined } from '@shared/utils'; + +export function useLocationState(propName: string): string | undefined; +export function useLocationState(propName: string, defaultValue: string): string; +export function useLocationState(propName: 'accountIndex'): number; +export function useLocationState(propName: 'backgroundLocation'): Location; export function useLocationState(propName: string, defaultValue?: string) { const location = useLocation(); return get(location, `state.${propName}`, defaultValue); } +export function useLocationStateWithCache(propName: string): T | undefined; +export function useLocationStateWithCache(propName: string, defaultValue: T): T; export function useLocationStateWithCache(propName: string, defaultValue?: T) { const location = useLocation(); const [value, setValue] = useState(defaultValue); From 364a7cd498121a6028cc59c32ac76d05b6d7a45c Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Fri, 28 Jul 2023 14:34:20 +0100 Subject: [PATCH 7/8] fix: gracefully handle opening modals in a new tab by setting backgroundLocation as home --- .../hooks/use-background-location-redirect.ts | 34 +++++++++++++++++++ src/app/common/hooks/use-location-state.ts | 1 - .../features/theme-drawer/theme-drawer.tsx | 4 ++- src/app/pages/home/components/home-tabs.tsx | 13 +------ .../components/receive-tokens.layout.tsx | 6 ++-- src/app/pages/receive-tokens/receive-btc.tsx | 7 ++-- .../pages/receive-tokens/receive-modal.tsx | 5 +-- src/app/pages/receive-tokens/receive-stx.tsx | 7 ++-- ...al.tsx => receive-collectible-ordinal.tsx} | 16 ++++----- .../pages/select-network/select-network.tsx | 4 ++- .../sign-out-confirm/sign-out-confirm.tsx | 6 +++- src/app/routes/app-routes.tsx | 6 ++-- 12 files changed, 72 insertions(+), 37 deletions(-) create mode 100644 src/app/common/hooks/use-background-location-redirect.ts rename src/app/pages/receive/receive-collectible/{receive-collectible-oridinal.tsx => receive-collectible-ordinal.tsx} (91%) diff --git a/src/app/common/hooks/use-background-location-redirect.ts b/src/app/common/hooks/use-background-location-redirect.ts new file mode 100644 index 00000000000..c34e068fb2b --- /dev/null +++ b/src/app/common/hooks/use-background-location-redirect.ts @@ -0,0 +1,34 @@ +import { useEffect } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; + +import { RouteUrls } from '@shared/route-urls'; + +import { useLocationState } from '@app/common/hooks/use-location-state'; + +/* +when modals are opened in a new tab they lose the location.state.backgroundLocation + this hook sets the backgroundLocation to be RouteUrls.Home to improve UX +*/ +export function useBackgroundLocationRedirect() { + const { pathname, state } = useLocation(); + const navigate = useNavigate(); + const backgroundLocation = useLocationState('backgroundLocation'); + + useEffect(() => { + void (async () => { + switch (true) { + // FIXME ReceiveCollectibleOrdinal loses state?.btcAddressTaproot in a new tab + // this can be improved to try and fetch btcAddressTaproot + case pathname === RouteUrls.ReceiveCollectibleOrdinal && !state?.btcAddressTaproot: + return navigate(RouteUrls.Home); + + case backgroundLocation === undefined: + return navigate(pathname, { + state: { backgroundLocation: { pathname: RouteUrls.Home } }, + }); + default: + return false; + } + })(); + }, [backgroundLocation, navigate, pathname, state]); +} diff --git a/src/app/common/hooks/use-location-state.ts b/src/app/common/hooks/use-location-state.ts index abc100b72f4..6c790d1f65b 100644 --- a/src/app/common/hooks/use-location-state.ts +++ b/src/app/common/hooks/use-location-state.ts @@ -5,7 +5,6 @@ import get from 'lodash.get'; import { isUndefined } from '@shared/utils'; - export function useLocationState(propName: string): string | undefined; export function useLocationState(propName: string, defaultValue: string): string; export function useLocationState(propName: 'accountIndex'): number; diff --git a/src/app/features/theme-drawer/theme-drawer.tsx b/src/app/features/theme-drawer/theme-drawer.tsx index 3843f6d4e17..72369e6157e 100644 --- a/src/app/features/theme-drawer/theme-drawer.tsx +++ b/src/app/features/theme-drawer/theme-drawer.tsx @@ -1,15 +1,17 @@ import { useNavigate } from 'react-router-dom'; +import { useBackgroundLocationRedirect } from '@app/common/hooks/use-background-location-redirect'; import { useLocationState } from '@app/common/hooks/use-location-state'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; import { ThemeList } from './theme-list'; export function ThemesDrawer() { + useBackgroundLocationRedirect(); const navigate = useNavigate(); const backgroundLocation = useLocationState('backgroundLocation'); return ( - navigate(backgroundLocation || '..')}> + navigate(backgroundLocation)}> ); diff --git a/src/app/pages/home/components/home-tabs.tsx b/src/app/pages/home/components/home-tabs.tsx index f95af4aa80d..fa6cdeae13b 100644 --- a/src/app/pages/home/components/home-tabs.tsx +++ b/src/app/pages/home/components/home-tabs.tsx @@ -26,20 +26,9 @@ export function HomeTabs({ children }: HomeTabsProps) { ], [] ); - - // if(pathname === 'receive' && !backgroundLocation){ - - // } - // const path = backgroundLocation ? backgroundLocation.pathname : location?.pathname; - - // console.info('home-tabs bg location', backgroundLocation); - // console.info('home-tabs location', location); - - // if open new tab and cannot find location then set tab to be first const getActiveTab = useCallback(() => { const path = backgroundLocation ? backgroundLocation.pathname : location?.pathname; - const activeTab = tabs.findIndex(tab => tab.slug === path); - return activeTab === -1 ? 0 : activeTab; + return tabs.findIndex(tab => tab.slug === path); }, [tabs, backgroundLocation, location]); const setActiveTab = useCallback( diff --git a/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx b/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx index 8446f828605..b359fe72d50 100644 --- a/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx +++ b/src/app/pages/receive-tokens/components/receive-tokens.layout.tsx @@ -4,6 +4,7 @@ import { useNavigate } from 'react-router-dom'; import { Box, Button, Flex, Text, color } from '@stacks/ui'; import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; +import { useBackgroundLocationRedirect } from '@app/common/hooks/use-background-location-redirect'; import { useLocationState } from '@app/common/hooks/use-location-state'; import { AddressDisplayer } from '@app/components/address-displayer/address-displayer'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; @@ -20,12 +21,13 @@ interface ReceiveTokensLayoutProps { hasSubtitle?: boolean; } export function ReceiveTokensLayout(props: ReceiveTokensLayoutProps) { + useBackgroundLocationRedirect(); const { address, accountName, onCopyAddressToClipboard, title, warning, hasSubtitle } = props; const navigate = useNavigate(); - const { pathname } = useLocationState('backgroundLocation'); + const backgroundLocation = useLocationState('backgroundLocation'); return ( - navigate(pathname)}> + navigate(backgroundLocation?.pathname)}> {hasSubtitle && ( diff --git a/src/app/pages/receive-tokens/receive-btc.tsx b/src/app/pages/receive-tokens/receive-btc.tsx index a48d4739911..00cb7918cb4 100644 --- a/src/app/pages/receive-tokens/receive-btc.tsx +++ b/src/app/pages/receive-tokens/receive-btc.tsx @@ -1,3 +1,4 @@ +import { useCallback } from 'react'; import toast from 'react-hot-toast'; import { useLocation } from 'react-router-dom'; @@ -5,6 +6,7 @@ import { useClipboard } from '@stacks/ui'; import get from 'lodash.get'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useBackgroundLocationRedirect } from '@app/common/hooks/use-background-location-redirect'; import { useCurrentAccountIndex } from '@app/store/accounts/account'; import { useNativeSegwitAccountIndexAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; @@ -12,6 +14,7 @@ import { ReceiveBtcModalWarning } from './components/receive-btc-warning'; import { ReceiveTokensLayout } from './components/receive-tokens.layout'; export function ReceiveBtcModal() { + useBackgroundLocationRedirect(); const analytics = useAnalytics(); const { state } = useLocation(); @@ -23,11 +26,11 @@ export function ReceiveBtcModal() { const { onCopy } = useClipboard(btcAddress); - function copyToClipboard() { + const copyToClipboard = useCallback(() => { void analytics.track('copy_btc_address_to_clipboard'); toast.success('Copied to clipboard!'); onCopy(); - } + }, [analytics, onCopy]); return ( navigate(backgroundLocation?.pathname || '..')} + onClose={() => navigate(backgroundLocation?.pathname)} > Tokens diff --git a/src/app/pages/receive-tokens/receive-stx.tsx b/src/app/pages/receive-tokens/receive-stx.tsx index 15ba117f91f..3b1b3fd2dd1 100644 --- a/src/app/pages/receive-tokens/receive-stx.tsx +++ b/src/app/pages/receive-tokens/receive-stx.tsx @@ -1,24 +1,27 @@ +import { useCallback } from 'react'; import toast from 'react-hot-toast'; import { useClipboard } from '@stacks/ui'; import { useCurrentAccountDisplayName } from '@app/common/hooks/account/use-account-names'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useBackgroundLocationRedirect } from '@app/common/hooks/use-background-location-redirect'; import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; import { ReceiveTokensLayout } from './components/receive-tokens.layout'; export function ReceiveStxModal() { + useBackgroundLocationRedirect(); const currentAccount = useCurrentStacksAccount(); const analytics = useAnalytics(); const { onCopy } = useClipboard(currentAccount?.address ?? ''); const accountName = useCurrentAccountDisplayName(); - function copyToClipboard() { + const copyToClipboard = useCallback(() => { void analytics.track('copy_stx_address_to_clipboard'); toast.success('Copied to clipboard!'); onCopy(); - } + }, [analytics, onCopy]); if (!currentAccount) return null; diff --git a/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx b/src/app/pages/receive/receive-collectible/receive-collectible-ordinal.tsx similarity index 91% rename from src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx rename to src/app/pages/receive/receive-collectible/receive-collectible-ordinal.tsx index b73f3517d94..0693432fc27 100644 --- a/src/app/pages/receive/receive-collectible/receive-collectible-oridinal.tsx +++ b/src/app/pages/receive/receive-collectible/receive-collectible-ordinal.tsx @@ -1,3 +1,4 @@ +import { useCallback } from 'react'; import toast from 'react-hot-toast'; import { FiArrowUpRight } from 'react-icons/fi'; import { useLocation, useNavigate } from 'react-router-dom'; @@ -6,6 +7,7 @@ import { Box, Flex, Stack, color, useClipboard } from '@stacks/ui'; import { truncateMiddle } from '@stacks/ui-utils'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useBackgroundLocationRedirect } from '@app/common/hooks/use-background-location-redirect'; import { useLocationState } from '@app/common/hooks/use-location-state'; import { openInNewTab } from '@app/common/utils/open-in-new-tab'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; @@ -16,28 +18,22 @@ import { PrimaryButton } from '@app/components/primary-button'; import { Caption, Text, Title } from '@app/components/typography'; export function ReceiveCollectibleOrdinal() { + useBackgroundLocationRedirect(); const navigate = useNavigate(); const analytics = useAnalytics(); const { state } = useLocation(); const backgroundLocation = useLocationState('backgroundLocation'); - // if this is opened in a new tab it has no btcAddress so we cannot do anything - if (!state) { - // TODO implement this more gracefull to simply not load this component at all if no state.btcAdressTaproot - navigate('..'); - console.log('state.btcAddressTaproot', state); - } - const { onCopy } = useClipboard(state?.btcAddressTaproot); - function copyToClipboard() { + const copyToClipboard = useCallback(() => { void analytics.track('copy_address_to_add_new_inscription'); toast.success('Copied to clipboard!'); onCopy(); - } + }, [analytics, onCopy]); return ( - navigate(backgroundLocation?.pathname || '..')}> + navigate(backgroundLocation.pathname)}> diff --git a/src/app/pages/select-network/select-network.tsx b/src/app/pages/select-network/select-network.tsx index e9055c8afdd..20c5f5b4818 100644 --- a/src/app/pages/select-network/select-network.tsx +++ b/src/app/pages/select-network/select-network.tsx @@ -4,6 +4,7 @@ import { WalletDefaultNetworkConfigurationIds } from '@shared/constants'; import { RouteUrls } from '@shared/route-urls'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { useBackgroundLocationRedirect } from '@app/common/hooks/use-background-location-redirect'; import { useLocationState } from '@app/common/hooks/use-location-state'; import { BaseDrawer } from '@app/components/drawer/base-drawer'; import { NetworkListLayout } from '@app/pages/select-network/components/network-list.layout'; @@ -16,6 +17,7 @@ import { AddNetworkButton } from './components/add-network-button'; const defaultNetworkIds = Object.values(WalletDefaultNetworkConfigurationIds) as string[]; export function SelectNetwork() { + useBackgroundLocationRedirect(); const navigate = useNavigate(); const networks = useNetworks(); const analytics = useAnalytics(); @@ -40,7 +42,7 @@ export function SelectNetwork() { } function closeNetworkModal() { - navigate(backgroundLocation || '..'); + navigate(backgroundLocation); } return ( diff --git a/src/app/pages/sign-out-confirm/sign-out-confirm.tsx b/src/app/pages/sign-out-confirm/sign-out-confirm.tsx index eba398fe0a3..c4d84c85aa2 100644 --- a/src/app/pages/sign-out-confirm/sign-out-confirm.tsx +++ b/src/app/pages/sign-out-confirm/sign-out-confirm.tsx @@ -2,13 +2,17 @@ import { useNavigate } from 'react-router-dom'; import { RouteUrls } from '@shared/route-urls'; +import { useBackgroundLocationRedirect } from '@app/common/hooks/use-background-location-redirect'; import { useKeyActions } from '@app/common/hooks/use-key-actions'; +import { useLocationState } from '@app/common/hooks/use-location-state'; import { SignOutConfirmLayout } from './sign-out-confirm.layout'; export function SignOutConfirmDrawer() { + useBackgroundLocationRedirect(); const { signOut } = useKeyActions(); const navigate = useNavigate(); + const backgroundLocation = useLocationState('backgroundLocation'); return ( navigate('..')} + onUserSafelyReturnToHomepage={() => navigate(backgroundLocation)} /> ); } diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index f6101d23c0b..42774a1d62c 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -39,7 +39,7 @@ import { ReceiveBtcModal } from '@app/pages/receive-tokens/receive-btc'; import { ReceiveModal } from '@app/pages/receive-tokens/receive-modal'; import { ReceiveStxModal } from '@app/pages/receive-tokens/receive-stx'; import { ReceiveCollectibleModal } from '@app/pages/receive/receive-collectible/receive-collectible-modal'; -import { ReceiveCollectibleOrdinal } from '@app/pages/receive/receive-collectible/receive-collectible-oridinal'; +import { ReceiveCollectibleOrdinal } from '@app/pages/receive/receive-collectible/receive-collectible-ordinal'; import { RequestError } from '@app/pages/request-error/request-error'; import { RpcGetAddresses } from '@app/pages/rpc-get-addresses/rpc-get-addresses'; import { rpcSendTransferRoutes } from '@app/pages/rpc-send-transfer/rpc-send-transfer.routes'; @@ -94,6 +94,8 @@ export const homeModalRoutes = ( } /> } /> + } /> + } /> {sendOrdinalRoutes} {settingsModalRoutes} @@ -221,8 +223,6 @@ function useAppRoutes() { } /> } /> - } /> - } /> {homeModalRoutes} {sendOrdinalRoutes} From 2d5b02bf1335a4b2206db6e1ede9d11a043ffdb5 Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Tue, 1 Aug 2023 14:46:02 +0100 Subject: [PATCH 8/8] fix: restructure home routes as absolute paths will not work in nested routes which are needed for modal --- src/app/pages/home/components/home-tabs.tsx | 4 +-- src/app/pages/home/home.tsx | 5 +-- src/app/routes/app-routes.tsx | 36 ++++++++------------- src/shared/route-urls.ts | 8 +++-- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/app/pages/home/components/home-tabs.tsx b/src/app/pages/home/components/home-tabs.tsx index fa6cdeae13b..5285a47074f 100644 --- a/src/app/pages/home/components/home-tabs.tsx +++ b/src/app/pages/home/components/home-tabs.tsx @@ -21,8 +21,8 @@ export function HomeTabs({ children }: HomeTabsProps) { const tabs = useMemo( () => [ - { slug: RouteUrls.Home, label: 'balances' }, - { slug: RouteUrls.Activity, label: 'activity' }, + { slug: `${RouteUrls.Home}/${RouteUrls.Assets}`, label: 'balances' }, + { slug: `${RouteUrls.Home}/${RouteUrls.Activity}`, label: 'activity' }, ], [] ); diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index 460aed97d67..70249287d62 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -1,4 +1,4 @@ -import { Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; +import { Navigate, Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; import { RouteUrls } from '@shared/route-urls'; @@ -47,8 +47,9 @@ export function Home() { <> - } /> + } /> } /> + } /> {homeModalRoutes} {backgroundLocation && } diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index 42774a1d62c..9bd3fad2559 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -202,32 +202,29 @@ function useAppRoutes() { } /> } - > - } /> - } /> - - {requestBitcoinKeysRoutes} - {requestStacksKeysRoutes} - } /> - - }> - {ledgerStacksTxSigningRoutes} - - } /> - } /> - } /> + /> - {homeModalRoutes} - {sendOrdinalRoutes} + {requestBitcoinKeysRoutes} + {requestStacksKeysRoutes} + } /> + }> {ledgerStacksTxSigningRoutes} + } /> + } /> + } /> + + {homeModalRoutes} + {sendOrdinalRoutes} + + {ledgerStacksTxSigningRoutes} - } /> {settingsModalRoutes} - {sendCryptoAssetFormRoutes} - }> {settingsModalRoutes} - {legacyRequestRoutes} {rpcRequestRoutes} } /> @@ -336,7 +329,6 @@ function useAppRoutes() { } /> - {/* Catch-all route redirects to onboarding */} } /> diff --git a/src/shared/route-urls.ts b/src/shared/route-urls.ts index ea0425d0b94..7d90ddda5a5 100644 --- a/src/shared/route-urls.ts +++ b/src/shared/route-urls.ts @@ -24,9 +24,13 @@ export enum RouteUrls { LedgerBroadcastError = 'transaction-broadcast-error', LedgerAddMoreKeys = 'add-more-keys', + // Active wallet routes - home + Home = '/home', + // Tab nested relative paths + Activity = 'activity', + Assets = 'assets', + // Active wallet routes - Home = '/', - Activity = '/activity', AddNetwork = '/add-network', ChooseAccount = '/choose-account', Fund = '/fund',