Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/4028/leather wallet modal routing #4325

Merged
merged 17 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
38 changes: 22 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 @@ -99,32 +100,37 @@ export function ActivityList() {
return (
<ActivityListTabWrapper padContent>
<LoadingSpinner />
<Outlet />
</ActivityListTabWrapper>
);

if (!hasTxs)
return (
<ActivityListTabWrapper padContent>
<NoAccountActivity />
<Outlet />
</ActivityListTabWrapper>
);

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
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.Home}${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
19 changes: 16 additions & 3 deletions src/app/features/settings-dropdown/settings-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ export function SettingsDropdown() {

useOnClickOutside(ref, isShowing ? handleClose : null);

// RouteUrls.Activity is nested off / so we need to use a link relative to the route
const linkRelativeType =
location.pathname === `${RouteUrls.Home}${RouteUrls.Activity}` ? 'route' : 'path';

return (
<SlideFade initialOffset="-20px" timeout={150} in={isShowing}>
{styles => (
Expand All @@ -78,7 +82,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: linkRelativeType,
state: { backgroundLocation: location },
});
})}
>
Change theme
Expand Down Expand Up @@ -128,7 +135,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: linkRelativeType,
state: { backgroundLocation: location },
});
})}
>
<Flex width="100%" alignItems="center" justifyContent="space-between">
Expand Down Expand Up @@ -159,7 +169,10 @@ export function SettingsDropdown() {
<MenuItem
color={color('feedback-error')}
onClick={wrappedCloseCallback(() =>
navigate(RouteUrls.SignOutConfirm, { relative: 'path' })
navigate(RouteUrls.SignOutConfirm, {
relative: linkRelativeType,
state: { backgroundLocation: location },
})
)}
data-testid={SettingsSelectors.SignOutListItem}
>
Expand Down
6 changes: 5 additions & 1 deletion src/app/features/theme-drawer/theme-drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { useNavigate } from 'react-router-dom';

import { useLocationState } from '@app/common/hooks/use-location-state';
import { BaseDrawer } from '@app/components/drawer/base-drawer';
import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';

import { ThemeList } from './theme-list';

export function ThemesDrawer() {
useBackgroundLocationRedirect();
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
11 changes: 9 additions & 2 deletions src/app/pages/fund/components/fiat-providers-list.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 { Grid } from 'leather-styles/jsx';

Expand All @@ -25,6 +25,7 @@ export function FiatProvidersList(props: FiatProvidersProps) {
const activeProviders = useActiveFiatProviders();
const hasProviders = useHasFiatProviders();
const analytics = useAnalytics();
const location = useLocation();

const goToProviderExternalWebsite = (provider: string, providerUrl: string) => {
void analytics.track('select_buy_option', { provider });
Expand Down Expand Up @@ -52,7 +53,13 @@ export function FiatProvidersList(props: FiatProvidersProps) {
width="100%"
maxWidth={['100%', '80rem']}
>
<ReceiveStxItem onReceiveStx={() => navigate(RouteUrls.FundReceiveStx)} />
<ReceiveStxItem
onReceiveStx={() =>
navigate(`${RouteUrls.ReceiveStx}`, {
state: { backgroundLocation: location },
})
}
/>
{Object.entries(activeProviders).map(([providerKey, providerValue]) => {
const providerUrl = getProviderUrl({
address,
Expand Down
13 changes: 9 additions & 4 deletions src/app/pages/fund/fund.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
import { Outlet, useNavigate } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';

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

import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { Header } from '@app/components/header';
import { FullPageLoadingSpinner } from '@app/components/loading-spinner';
import { useCurrentStacksAccountAnchoredBalances } from '@app/query/stacks/balance/stx-balance.hooks';
import { ModalBackgroundWrapper } from '@app/routes/components/modal-background-wrapper';
import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';

import { FundLayout } from './fund.layout';

export function FundPage() {
interface FundPageProps {
children: React.ReactNode;
}
export function FundPage({ children }: FundPageProps) {
useBackgroundLocationRedirect(RouteUrls.Fund);
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} />
<Outlet />
<ModalBackgroundWrapper>{children}</ModalBackgroundWrapper>
</>
);
}
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.Home}${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
18 changes: 14 additions & 4 deletions src/app/pages/home/home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Outlet, useNavigate } from 'react-router-dom';
import { Route, useNavigate } from 'react-router-dom';

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

Expand All @@ -7,8 +7,11 @@ import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-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 { homePageModalRoutes } from '@app/routes/app-routes';
import { ModalBackgroundWrapper } from '@app/routes/components/modal-background-wrapper';

import { CurrentAccount } from './components/account-area';
import { HomeTabs } from './components/home-tabs';
Expand All @@ -17,8 +20,8 @@ import { HomeLayout } from './components/home.layout';
export function Home() {
const { decodedAuthRequest } = useOnboardingState();

const stacksAccount = useCurrentStacksAccount();
const navigate = useNavigate();

useTrackFirstDeposit();

useRouteHeader(
Expand All @@ -35,7 +38,14 @@ export function Home() {
return (
<HomeLayout currentAccount={<CurrentAccount />}>
<HomeTabs>
<Outlet context={{ address: stacksAccount?.address }} />
<ModalBackgroundWrapper>
<Route index element={<AssetsList />} />
<Route path={RouteUrls.Activity} element={<ActivityList />}>
{homePageModalRoutes}
</Route>

{homePageModalRoutes}
</ModalBackgroundWrapper>
</HomeTabs>
</HomeLayout>
);
Expand Down
Loading