Skip to content

Commit

Permalink
refactor: account selection page
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Apr 21, 2022
1 parent 59aa057 commit 4aa0e0b
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 84 deletions.
28 changes: 28 additions & 0 deletions src/app/components/account/account-title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { BoxProps } from '@stacks/ui';

import { SoftwareWalletAccountWithAddress } from '@app/store/accounts/account.models';
import { Title } from '../typography';

interface AccountTitlePlaceholderProps extends BoxProps {
account: SoftwareWalletAccountWithAddress;
}
export function AccountTitlePlaceholder({ account, ...rest }: AccountTitlePlaceholderProps) {
const name = `Account ${account?.index + 1}`;
return (
<Title fontSize={2} lineHeight="1rem" fontWeight="400" {...rest}>
{name}
</Title>
);
}

interface AccountTitleProps extends BoxProps {
account: SoftwareWalletAccountWithAddress;
name: string;
}
export function AccountTitle({ account, name, ...rest }: AccountTitleProps) {
return (
<Title fontSize={2} lineHeight="1rem" fontWeight="400" {...rest}>
{name}
</Title>
);
}
24 changes: 24 additions & 0 deletions src/app/features/account-picker/account-picker.layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Flex, Stack, Text } from '@stacks/ui';

import { AppIcon } from '@app/components/app-icon';
import { Title } from '@app/components/typography';

interface AccountPickerLayoutProps {
appName?: string;
children: React.ReactNode;
}
export function AccountPickerLayout(props: AccountPickerLayoutProps) {
const { appName, children } = props;
return (
<Flex flexDirection="column" px={['loose', 'unset']} width="100%">
<Stack spacing="loose" textAlign="center">
<AppIcon mt="extra-loose" mb="loose" size="72px" />
<Stack spacing="base">
<Title fontSize={4}>Choose an account</Title>
<Text textStyle="caption">to connect to {appName}</Text>
</Stack>
</Stack>
{children}
</Flex>
);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useCallback, Suspense, memo, useState, useMemo } from 'react';
import { Suspense, memo, useMemo } from 'react';
import { FiPlusCircle } from 'react-icons/fi';
import { Virtuoso } from 'react-virtuoso';
import { Box, BoxProps, color, FlexProps, Spinner, Stack } from '@stacks/ui';
import { truncateMiddle } from '@stacks/ui-utils';

import { Caption, Text, Title } from '@app/components/typography';
import { Caption, Text } from '@app/components/typography';
import { useAccountDisplayName } from '@app/common/hooks/account/use-account-names';
import { useWallet } from '@app/common/hooks/use-wallet';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
Expand All @@ -20,34 +20,11 @@ import {
import { slugify } from '@app/common/utils';
import { useAccounts, useHasCreatedAccount } from '@app/store/accounts/account.hooks';
import { useAddressBalances } from '@app/query/balance/balance.hooks';
import { AccountTitle, AccountTitlePlaceholder } from '@app/components/account/account-title';

const loadingProps = { color: '#A1A7B3' };
const getLoadingProps = (loading: boolean) => (loading ? loadingProps : {});

interface AccountTitlePlaceholderProps extends BoxProps {
account: SoftwareWalletAccountWithAddress;
}
const AccountTitlePlaceholder = ({ account, ...rest }: AccountTitlePlaceholderProps) => {
const name = `Account ${account?.index + 1}`;
return (
<Title fontSize={2} lineHeight="1rem" fontWeight="400" {...rest}>
{name}
</Title>
);
};

interface AccountTitleProps extends BoxProps {
account: SoftwareWalletAccountWithAddress;
name: string;
}
const AccountTitle = ({ account, name, ...rest }: AccountTitleProps) => {
return (
<Title fontSize={2} lineHeight="1rem" fontWeight="400" {...rest}>
{name}
</Title>
);
};

interface AccountItemProps extends FlexProps {
selectedAddress?: string | null;
isLoading: boolean;
Expand Down Expand Up @@ -131,21 +108,14 @@ const AddAccountAction = memo(() => {
);
});

export const Accounts = memo(() => {
const { wallet, finishSignIn } = useWallet();
const accounts = useAccounts();
const { decodedAuthRequest } = useOnboardingState();
const [selectedAccount, setSelectedAccount] = useState<number | null>(null);

const signIntoAccount = useCallback(
async (index: number) => {
setSelectedAccount(index);
await finishSignIn(index);
},
[finishSignIn]
);
interface AccountPickerProps {
selectedAccountIndex: number | null;
onAccountSelected(index: number): void;
}
export function AccountPicker(props: AccountPickerProps) {
const { onAccountSelected, selectedAccountIndex } = props;

if (!wallet || !accounts || !decodedAuthRequest) return null;
const accounts = useAccounts();

return (
<>
Expand All @@ -158,12 +128,12 @@ export const Accounts = memo(() => {
itemContent={(index, account) => (
<AccountItem
account={account}
isLoading={selectedAccount === index}
onSelectAccount={signIntoAccount}
isLoading={selectedAccountIndex === index}
onSelectAccount={() => onAccountSelected(index)}
/>
)}
/>
</Box>
</>
);
});
}
45 changes: 45 additions & 0 deletions src/app/pages/account-authentication/account-authentication.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { memo, useCallback, useEffect, useState } from 'react';

import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { useWallet } from '@app/common/hooks/use-wallet';
import { useAppDetails } from '@app/common/hooks/auth/use-app-details';
import { Header } from '@app/components/header';
import { AccountPicker } from '@app/features/account-picker/accounts';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
import { useAccounts } from '@app/store/accounts/account.hooks';
import { AccountPickerLayout } from '@app/features/account-picker/account-picker.layout';

export const AuthenticateAccount = memo(() => {
const accounts = useAccounts();
const { name: appName } = useAppDetails();
const { decodedAuthRequest } = useOnboardingState();
const { cancelAuthentication, wallet, finishSignIn } = useWallet();
const [selectedAccountIndex, setSelectedAccountIndex] = useState<number | null>(null);

useRouteHeader(<Header hideActions />);

const signIntoAccount = async (index: number) => {
setSelectedAccountIndex(index);
await finishSignIn(index);
};

const handleUnmount = useCallback(async () => {
cancelAuthentication();
}, [cancelAuthentication]);

useEffect(() => {
window.addEventListener('beforeunload', handleUnmount);
return () => window.removeEventListener('beforeunload', handleUnmount);
}, [handleUnmount]);

if (!wallet || !accounts || !decodedAuthRequest) return null;

return (
<AccountPickerLayout appName={appName}>
<AccountPicker
onAccountSelected={index => signIntoAccount(index)}
selectedAccountIndex={selectedAccountIndex}
/>
</AccountPickerLayout>
);
});
39 changes: 39 additions & 0 deletions src/app/pages/choose-account-request/account-request.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useRouteHeader } from '@app/common/hooks/use-route-header';
import { useAppDetails } from '@app/common/hooks/auth/use-app-details';
import { Header } from '@app/components/header';
import { AccountPicker } from '@app/features/account-picker/accounts';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
import { useAccounts } from '@app/store/accounts/account.hooks';
import { AccountPickerLayout } from '@app/features/account-picker/account-picker.layout';

export function AccountRequest() {
const accounts = useAccounts();
const { name: appName } = useAppDetails();
const { decodedAuthRequest } = useOnboardingState();
// const [selectedAccountIndex, setSelectedAccountIndex] = useState<number | null>(null);

useRouteHeader(<Header hideActions />);

const returnAccountDetailsToApp = async (index: number) => {
// setSelectedAccountIndex(index);
// await finishSignIn(index);
};

// const handleUnmount = useCallback(async () => {
// cancelAuthentication();
// }, [cancelAuthentication]);

// useEffect(() => {
// window.addEventListener('beforeunload', handleUnmount);
// return () => window.removeEventListener('beforeunload', handleUnmount);
// }, [handleUnmount]);

return (
<AccountPickerLayout appName={appName}>
<AccountPicker
onAccountSelected={index => returnAccountDetailsToApp(index)}
selectedAccountIndex={0}
/>
</AccountPickerLayout>
);
}
39 changes: 0 additions & 39 deletions src/app/pages/choose-account/choose-account.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/app/routes/app-routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { Container } from '@app/components/container/container';
import { LoadingSpinner } from '@app/components/loading-spinner';
import { MagicRecoveryCode } from '@app/pages/onboarding/magic-recovery-code/magic-recovery-code';
import { ChooseAccount } from '@app/pages/choose-account/choose-account';
import { AuthenticateAccount } from '@app/pages/account-authentication/account-authentication';
import { TransactionRequest } from '@app/pages/transaction-request/transaction-request';
import { SignIn } from '@app/pages/onboarding/sign-in/sign-in';
import { ReceiveTokens } from '@app/pages/receive-tokens/receive-tokens';
Expand Down Expand Up @@ -112,7 +112,7 @@ export function AppRoutes(): JSX.Element | null {
element={
<AccountGate>
<Suspense fallback={<></>}>
<ChooseAccount />
<AuthenticateAccount />
</Suspense>
</AccountGate>
}
Expand Down
2 changes: 2 additions & 0 deletions src/background/legacy-external-message-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ async function openRequestInFullPage(path: string, urlParams: URLSearchParams) {
export function inferLegacyMessage(message: any): message is LegacyMessageFromContentScript {
// Now that we use a RPC communication style, we can infer
// legacy message types by presence of an id
// Types incorrectly state this is `undefined`
// @ts-ignore
return !Object.hasOwn(message, 'id');
}

Expand Down
6 changes: 6 additions & 0 deletions src/inpage/inpage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,9 @@ declare global {
randomUUID: () => string;
}
}

// declare global {
// interface Window {
// StacksProvider?: Provider;
// }
// }

0 comments on commit 4aa0e0b

Please sign in to comment.