Skip to content

Commit

Permalink
fix: refactor modals to overlay on top of backgroundLocation consiste…
Browse files Browse the repository at this point in the history
…ntly, closes leather-io#4028
  • Loading branch information
pete-watters committed Oct 16, 2023
1 parent 176ac33 commit c006894
Show file tree
Hide file tree
Showing 30 changed files with 543 additions and 294 deletions.
34 changes: 34 additions & 0 deletions src/app/common/hooks/use-background-location-redirect.ts
Original file line number Diff line number Diff line change
@@ -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';

// PETE this is the last thing
// - test opening in new tabs
// - find what fails and where then apply Kyrans advice
// - I think it works everywhere but Home tabs

/*
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');

// console.log('backgroundLocation', backgroundLocation);
// debugger;
useEffect(() => {
void (async () => {
// if (backgroundLocation === undefined) {
// return navigate(pathname, {
// state: { backgroundLocation: { pathname: RouteUrls.Home }, ...state },
// });
// }
return false;
})();
}, [backgroundLocation, navigate, pathname, state]);
}
7 changes: 7 additions & 0 deletions src/app/common/hooks/use-location-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import get from 'lodash.get';

import { isUndefined } from '@shared/utils';

type LocationState = string | undefined | number | Location;

export function useLocationState<T extends LocationState>(propName: string): T;
export function useLocationState<T extends LocationState>(
propName: string,
defaultValue: string
): T;
export function useLocationState(propName: string): string | undefined;
export function useLocationState(propName: string, defaultValue: string): string;
export function useLocationState(propName: string, defaultValue?: string) {
Expand Down
36 changes: 20 additions & 16 deletions src/app/features/activity-list/activity-list.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useMemo } from 'react';
import { Outlet } from 'react-router-dom';

import uniqby from 'lodash.uniqby';

Expand Down Expand Up @@ -110,21 +111,24 @@ export function ActivityList() {
);

return (
<ActivityListTabWrapper>
{hasSubmittedTransactions && <SubmittedTransactionList txs={submittedTransactions} />}
{hasPendingTransactions && (
<PendingTransactionList
bitcoinTxs={isBitcoinEnabled ? bitcoinPendingTxs : []}
stacksTxs={stacksPendingTransactions}
/>
)}
{hasTransactions && (
<TransactionList
bitcoinTxs={isBitcoinEnabled ? transactionListBitcoinTxs : []}
stacksTxs={transactionListStacksTxs}
currentBitcoinAddress={nsBitcoinAddress}
/>
)}
</ActivityListTabWrapper>
<>
<ActivityListTabWrapper>
{hasSubmittedTransactions && <SubmittedTransactionList txs={submittedTransactions} />}
{hasPendingTransactions && (
<PendingTransactionList
bitcoinTxs={isBitcoinEnabled ? bitcoinPendingTxs : []}
stacksTxs={stacksPendingTransactions}
/>
)}
{hasTransactions && (
<TransactionList
bitcoinTxs={isBitcoinEnabled ? transactionListBitcoinTxs : []}
stacksTxs={transactionListStacksTxs}
currentBitcoinAddress={nsBitcoinAddress}
/>
)}
</ActivityListTabWrapper>
<Outlet />
</>
);
}
3 changes: 1 addition & 2 deletions src/app/features/asset-list/asset-list.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Outlet } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { Outlet, useNavigate } from 'react-router-dom';

import { HomePageSelectors } from '@tests/selectors/home.selectors';
import { Stack } from 'leather-styles/jsx';
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/collectibles/collectibles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function Collectibles() {
subHeader={whenWallet({
software: (
<TaprootBalanceDisplayer
onSelectRetrieveBalance={() => navigate(RouteUrls.RetriveTaprootFunds)}
onSelectRetrieveBalance={() => navigate(RouteUrls.RetrieveTaprootFunds)}
/>
),
ledger: null,
Expand Down
9 changes: 7 additions & 2 deletions src/app/features/collectibles/components/add-collectible.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useNavigate } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';

import { Box } from '@stacks/ui';
import { token } from 'leather-styles/tokens';
Expand Down Expand Up @@ -26,13 +26,18 @@ const backgroundProps = {
export function AddCollectible() {
const navigate = useNavigate();
const analytics = useAnalytics();
const location = useLocation();

return (
<CollectibleItemLayout
backgroundElementProps={backgroundProps}
onClickLayout={() => {
void analytics.track('select_add_new_collectible');
navigate(RouteUrls.ReceiveCollectible);
navigate(`${RouteUrls.Receive}/${RouteUrls.ReceiveCollectible}`, {
state: {
backgroundLocation: location,
},
});
}}
subtitle="Collectible"
title="Add new"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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';
Expand All @@ -18,10 +18,11 @@ interface InscriptionProps {
export function Inscription({ rawInscription }: InscriptionProps) {
const inscription = convertInscriptionToSupportedInscriptionType(rawInscription);
const navigate = useNavigate();
const location = useLocation();

function openSendInscriptionModal() {
navigate(RouteUrls.SendOrdinalInscription, {
state: { inscription },
state: { inscription, backgroundLocation: location },
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useLocationState } from '@app/common/hooks/use-location-state';
import { DeviceBusyLayout } from '@app/features/ledger/generic-steps';

export function DeviceBusy() {
const description = useLocationState('description');
const description = useLocationState<string>('description');
return (
<DeviceBusyLayout chain="stacks" activityDescription={description ?? 'Ledger device busy'} />
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { useLedgerNavigate } from '@app/features/ledger/hooks/use-ledger-navigat

export function OperationRejected() {
const ledgerNavigate = useLedgerNavigate();
const description = useLocationState('description', 'The operation on device was rejected');
const description = useLocationState<string>(
'description',
'The operation on device was rejected'
);
return (
<LedgerOperationRejectedLayout
description={description}
Expand Down
15 changes: 12 additions & 3 deletions src/app/features/settings-dropdown/settings-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,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: location },
});
})}
>
Change theme
Expand Down Expand Up @@ -128,7 +131,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: location },
});
})}
>
<Flex width="100%" alignItems="center" justifyContent="space-between">
Expand Down Expand Up @@ -159,7 +165,10 @@ export function SettingsDropdown() {
<MenuItem
color={color('feedback-error')}
onClick={wrappedCloseCallback(() =>
navigate(RouteUrls.SignOutConfirm, { relative: 'path' })
navigate(RouteUrls.SignOutConfirm, {
relative: 'path',
state: { backgroundLocation: location },
})
)}
data-testid={SettingsSelectors.SignOutListItem}
>
Expand Down
4 changes: 3 additions & 1 deletion src/app/features/theme-drawer/theme-drawer.tsx
Original file line number Diff line number Diff line change
@@ -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<Location>('backgroundLocation');
return (
<BaseDrawer title="Select Theme" isShowing onClose={() => navigate('..')}>
<BaseDrawer title="Select Theme" isShowing onClose={() => navigate(backgroundLocation ?? '..')}>
<ThemeList />
</BaseDrawer>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/fund/fund.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import { FundLayout } from './fund.layout';

export function FundPage() {
const navigate = useNavigate();

const currentAccount = useCurrentStacksAccount();
const { data: balances } = useCurrentStacksAccountAnchoredBalances();

useRouteHeader(<Header onClose={() => navigate(RouteUrls.Home)} title=" " />);

if (!currentAccount || !balances) return <FullPageLoadingSpinner />;

return (
<>
<FundLayout address={currentAccount.address} />
Expand Down
14 changes: 12 additions & 2 deletions src/app/pages/home/components/account-actions.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useNavigate } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';

import { HomePageSelectors } from '@tests/selectors/home.selectors';
import { Flex, FlexProps } from 'leather-styles/jsx';
Expand All @@ -16,7 +16,11 @@ import { SendButton } from './send-button';

export function AccountActions(props: FlexProps) {
const navigate = useNavigate();
const location = useLocation();
const isBitcoinEnabled = useConfigBitcoinEnabled();
const receivePath = isBitcoinEnabled
? RouteUrls.Receive
: `${RouteUrls.Receive}/${RouteUrls.ReceiveStx}`;

return (
<Flex justify="space-between" {...props}>
Expand All @@ -26,7 +30,13 @@ export function AccountActions(props: FlexProps) {
data-testid={HomePageSelectors.ReceiveCryptoAssetBtn}
icon={<ArrowDown />}
label="Receive"
onClick={() => navigate(isBitcoinEnabled ? RouteUrls.Receive : RouteUrls.ReceiveStx)}
onClick={() =>
navigate(receivePath, {
state: {
backgroundLocation: location,
},
})
}
/>
<ActionButton
data-testid={HomePageSelectors.FundAccountBtn}
Expand Down
15 changes: 8 additions & 7 deletions src/app/pages/home/components/home-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -15,20 +16,20 @@ 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<Location>('backgroundLocation');

const tabs = useMemo(
() => [
{ slug: RouteUrls.Home, label: 'assets' },
{ slug: RouteUrls.Activity, label: 'activity' },
{ slug: `${RouteUrls.Home}${RouteUrls.Activity}`, label: 'activity' },
],
[]
);

const getActiveTab = useCallback(
() => tabs.findIndex(tab => tab.slug === pathname),
[tabs, pathname]
);
const getActiveTab = useCallback(() => {
const path = backgroundLocation ? backgroundLocation.pathname : location?.pathname;
return tabs.findIndex(tab => tab.slug === path);
}, [tabs, backgroundLocation, location]);

const setActiveTab = useCallback(
(index: number) => navigate(tabs[index]?.slug),
Expand Down
24 changes: 20 additions & 4 deletions src/app/pages/home/home.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Outlet, useNavigate } from 'react-router-dom';
import { Navigate, Route, useNavigate } from 'react-router-dom';
import { Outlet, Routes, useLocation } 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 { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';

import { CurrentAccount } from './components/account-area';
import { HomeTabs } from './components/home-tabs';
Expand All @@ -17,8 +20,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<Location>('backgroundLocation');

useTrackFirstDeposit();

useRouteHeader(
Expand All @@ -35,7 +40,18 @@ export function Home() {
return (
<HomeLayout currentAccount={<CurrentAccount />}>
<HomeTabs>
<Outlet context={{ address: stacksAccount?.address }} />
<>
{/*
To overlay modal on nested routes backgroundLocation is used
to trick the router into thinking its on the same page
*/}
<Routes location={backgroundLocation || location}>
<Route index element={<AssetsList />} />
<Route path={RouteUrls.Activity} element={<ActivityList />} />
<Route path="*" element={<Navigate replace to={RouteUrls.Home} />} />
</Routes>
{backgroundLocation && <Outlet />}
</>
</HomeTabs>
</HomeLayout>
);
Expand Down
13 changes: 10 additions & 3 deletions src/app/pages/receive/components/receive-tokens.layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { useNavigate } from 'react-router-dom';
import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors';
import { Box, Flex, styled } from 'leather-styles/jsx';

import { RouteUrls } from '@shared/route-urls';

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 { LeatherButton } from '@app/components/button/button';
import { BaseDrawer } from '@app/components/drawer/base-drawer';
Expand All @@ -19,11 +19,18 @@ interface ReceiveTokensLayoutProps {
warning?: React.JSX.Element;
}
export function ReceiveTokensLayout(props: ReceiveTokensLayoutProps) {
useBackgroundLocationRedirect();

const { address, accountName, onCopyAddressToClipboard, title, warning } = props;
const navigate = useNavigate();
const backgroundLocation = useLocationState<Location>('backgroundLocation');

return (
<BaseDrawer title="Receive" isShowing onClose={() => navigate(RouteUrls.Home)}>
<BaseDrawer
title="Receive"
isShowing
onClose={() => navigate(backgroundLocation.pathname ?? '..')}
>
{warning && warning}
<Flex alignItems="center" flexDirection="column" pb={['space.05', 'space.08']} px="space.05">
<styled.h2 mt="space.05" textStyle="heading.03">
Expand Down
Loading

0 comments on commit c006894

Please sign in to comment.