Skip to content

Commit

Permalink
fix: allow virtuoso to resize dynamically, ref #5242
Browse files Browse the repository at this point in the history
  • Loading branch information
pete-watters committed Apr 23, 2024
1 parent b0276ec commit 6f242c3
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 121 deletions.
23 changes: 23 additions & 0 deletions src/app/common/hooks/use-media-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useEffect, useState } from 'react';

import { BreakpointToken, token } from 'leather-styles/tokens';

function useMediaQuery(query: string) {
const [matches, setMatches] = useState(false);

useEffect(() => {
const media = window.matchMedia(query);
if (media.matches !== matches) {
setMatches(media.matches);
}
const listener = () => setMatches(media.matches);
window.addEventListener('resize', listener);
return () => window.removeEventListener('resize', listener);
}, [matches, query]);

return matches;
}

export function useViewportMinWidth(viewport: BreakpointToken) {
return useMediaQuery(`(min-width: ${token(`breakpoints.${viewport}`)})`);
}
12 changes: 7 additions & 5 deletions src/app/features/container/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ export function Container() {
const isLogoClickable = variant !== 'home' && !isRpcRoute(pathname);
return (
<>
<SwitchAccountDialog
isShowing={isShowingSwitchAccount}
onClose={() => setIsShowingSwitchAccount(false)}
/>
{isShowingSwitchAccount && (
<SwitchAccountDialog
isShowing={isShowingSwitchAccount}
onClose={() => setIsShowingSwitchAccount(false)}
/>
)}

<InAppMessages />
<ContainerLayout
Expand Down Expand Up @@ -171,7 +173,7 @@ export function Container() {
) : null
}
>
<Outlet />
<Outlet context={{ isShowingSwitchAccount, setIsShowingSwitchAccount }} />
</ContainerLayout>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ import { useWalletType } from '@app/common/use-wallet-type';
import { useCurrentAccountIndex } from '@app/store/accounts/account';
import { useFilteredBitcoinAccounts } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { useHasLedgerKeys } from '@app/store/ledger/ledger.selectors';
import { Button } from '@app/ui/components/button/button';
import { Dialog, DialogProps, getHeightOffset } from '@app/ui/components/containers/dialog/dialog';
import { Dialog, DialogProps } from '@app/ui/components/containers/dialog/dialog';
import { Footer } from '@app/ui/components/containers/footers/footer';
import { Header } from '@app/ui/components/containers/headers/header';
import { virtuosoHeight, virtuosoStyles } from '@app/ui/shared/virtuoso';
import { VirtuosoWrapper } from '@app/ui/components/virtuoso';

import { AccountListUnavailable } from './components/account-list-unavailable';
import { SwitchAccountListItem } from './components/switch-account-list-item';

export interface SwitchAccountOutletContext {
isShowingSwitchAccount: boolean;
setIsShowingSwitchAccount(isShowing: boolean): void;
}

export const SwitchAccountDialog = memo(({ isShowing, onClose }: DialogProps) => {
const currentAccountIndex = useCurrentAccountIndex();
const createAccount = useCreateAccount();
const { whenWallet } = useWalletType();
const isLedger = useHasLedgerKeys();

const stacksAccounts = useStacksAccounts();
const bitcoinAccounts = useFilteredBitcoinAccounts();
const btcAddressesNum = bitcoinAccounts.length / 2;
Expand All @@ -43,13 +45,13 @@ export const SwitchAccountDialog = memo(({ isShowing, onClose }: DialogProps) =>
if (!isShowing) return null;

const accountNum = stacksAddressesNum || btcAddressesNum;
const maxAccountsShown = accountNum > 10 ? 10 : accountNum;

return (
<Dialog
header={<Header variant="dialog" title="Select account" />}
isShowing={isShowing}
onClose={onClose}
wrapChildren={false}
footer={whenWallet({
software: (
<Footer>
Expand All @@ -61,24 +63,24 @@ export const SwitchAccountDialog = memo(({ isShowing, onClose }: DialogProps) =>
ledger: null,
})}
>
<Virtuoso
height={virtuosoHeight}
style={{
...virtuosoStyles,
height: `calc(${virtuosoHeight * maxAccountsShown}px + ${getHeightOffset(true, !isLedger)}px)`,
}}
initialTopMostItemIndex={whenWallet({ ledger: 0, software: currentAccountIndex })}
totalCount={stacksAddressesNum || btcAddressesNum}
itemContent={index => (
<Box key={index} my="space.05" px="space.05">
<SwitchAccountListItem
handleClose={onClose}
currentAccountIndex={currentAccountIndex}
index={index}
/>
</Box>
)}
/>
<VirtuosoWrapper hasFooter={whenWallet({ ledger: false, software: true })}>
<Virtuoso
style={{
height: '100%',
}}
initialTopMostItemIndex={whenWallet({ ledger: 0, software: currentAccountIndex })}
totalCount={accountNum}
itemContent={index => (
<Box key={index} my="space.05" px="space.05">
<SwitchAccountListItem
handleClose={onClose}
currentAccountIndex={currentAccountIndex}
index={index}
/>
</Box>
)}
/>
</VirtuosoWrapper>
</Dialog>
);
});
4 changes: 2 additions & 2 deletions src/app/features/message-signer/message-preview-box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export function MessagePreviewBox({ message, hash }: MessageBoxProps) {
py="space.05"
overflowX="auto"
>
{message.split(/\r?\n/).map(line => (
<styled.span key={line} textStyle="label.01">
{message.split(/\r?\n/).map((line, index) => (
<styled.span key={`${line}_${index}`} textStyle="label.01">
{line}
</styled.span>
))}
Expand Down
17 changes: 12 additions & 5 deletions src/app/pages/choose-account/choose-account.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { memo, useEffect } from 'react';
import { useEffect } from 'react';
import { Outlet } from 'react-router-dom';

import { Flex, Stack, styled } from 'leather-styles/jsx';
Expand All @@ -10,10 +10,13 @@ import { useAppDetails } from '@app/common/hooks/auth/use-app-details';
import { RequesterFlag } from '@app/components/requester-flag';
import { ChooseAccountsList } from '@app/pages/choose-account/components/accounts';
import { useOnOriginTabClose } from '@app/routes/hooks/use-on-tab-closed';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { LogomarkIcon } from '@app/ui/icons/logomark-icon';

export const ChooseAccount = memo(() => {
export function ChooseAccount() {
const { url } = useAppDetails();
const accounts = useStacksAccounts();
const hasConnectedStacksAccounts = accounts.length > 0;

const cancelAuthentication = useCancelAuthRequest();

Expand All @@ -34,12 +37,16 @@ export const ChooseAccount = memo(() => {
{url && <RequesterFlag requester={url.toString()} />}
<LogomarkIcon width="248px" height="58px" />
<Stack gap="space.04">
<styled.h1 textStyle="heading.05">Choose an account to connect</styled.h1>
<styled.h1 textStyle="heading.05">
{hasConnectedStacksAccounts
? 'Choose an account to connect'
: 'No connected accounts found'}
</styled.h1>
</Stack>
</Stack>
<ChooseAccountsList />
{hasConnectedStacksAccounts && <ChooseAccountsList />}
</Flex>
<Outlet />
</>
);
});
}
49 changes: 22 additions & 27 deletions src/app/pages/choose-account/components/accounts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import { useNativeSegwitAccountIndexAddressIndexZero } from '@app/store/accounts
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models';
import { AccountAvatar } from '@app/ui/components/account/account-avatar/account-avatar';
import { VirtuosoWrapper } from '@app/ui/components/virtuoso';
import { PlusIcon } from '@app/ui/icons/plus-icon';
import { virtuosoHeight, virtuosoStyles } from '@app/ui/shared/virtuoso';

interface AccountTitlePlaceholderProps {
account: StacksAccount;
Expand All @@ -43,7 +43,6 @@ const ChooseAccountItem = memo(
const btcAddress = useNativeSegwitAccountIndexAddressIndexZero(account.index);

const accountSlug = useMemo(() => slugify(`Account ${account?.index + 1}`), [account?.index]);

return (
<AccountListItemLayout
accountAddresses={<AcccountAddresses index={account.index} />}
Expand Down Expand Up @@ -71,7 +70,7 @@ const ChooseAccountItem = memo(
}
);

const AddAccountAction = memo(() => {
function AddAccountAction() {
const [component, bind] = usePressable(true);
const createAccount = useCreateAccount();

Expand All @@ -88,9 +87,9 @@ const AddAccountAction = memo(() => {
{component}
</Box>
);
});
}

export const ChooseAccountsList = memo(() => {
export function ChooseAccountsList() {
const finishSignIn = useFinishAuthRequest();
const { whenWallet } = useWalletType();
const accounts = useStacksAccounts();
Expand All @@ -110,31 +109,27 @@ export const ChooseAccountsList = memo(() => {
};

if (!accounts) return null;
const accountNum = accounts.length;

const maxAccountsShown = accountNum > 10 ? 10 : accountNum;

return (
<Box mt="space.05" mb="space.06" width="100%">
{whenWallet({ software: <AddAccountAction />, ledger: <></> })}
<Virtuoso
height={virtuosoHeight}
style={{
...virtuosoStyles,
height: `calc(${virtuosoHeight * maxAccountsShown}px + 50px)`,
background: token('colors.ink.background-primary'),
}}
data={accounts}
itemContent={(index, account) => (
<Box key={index} my="space.05" px="space.05">
<ChooseAccountItem
account={account}
isLoading={whenWallet({ software: selectedAccount === index, ledger: false })}
onSelectAccount={signIntoAccount}
/>
</Box>
)}
/>
<VirtuosoWrapper isPopup>
<Virtuoso
style={{
background: token('colors.ink.background-primary'),
}}
data={accounts}
itemContent={(index, account) => (
<Box key={index} my="space.05" px="space.05">
<ChooseAccountItem
account={account}
isLoading={whenWallet({ software: selectedAccount === index, ledger: false })}
onSelectAccount={signIntoAccount}
/>
</Box>
)}
/>
</VirtuosoWrapper>
</Box>
);
});
}
15 changes: 4 additions & 11 deletions src/app/pages/home/home.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState } from 'react';
import { Route, useNavigate } from 'react-router-dom';
import { Route, useNavigate, useOutletContext } from 'react-router-dom';

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

Expand All @@ -9,7 +8,7 @@ import { useTotalBalance } from '@app/common/hooks/balance/use-total-balance';
import { useOnMount } from '@app/common/hooks/use-on-mount';
import { ActivityList } from '@app/features/activity-list/activity-list';
import { AssetsList } from '@app/features/asset-list/asset-list';
import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog';
import { SwitchAccountOutletContext } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog';
import { FeedbackButton } from '@app/features/feedback-button/feedback-button';
import { homePageModalRoutes } from '@app/routes/app-routes';
import { ModalBackgroundWrapper } from '@app/routes/components/modal-background-wrapper';
Expand All @@ -22,9 +21,9 @@ import { AccountActions } from './components/account-actions';
import { HomeTabs } from './components/home-tabs';

export function Home() {
const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false);
const { decodedAuthRequest } = useOnboardingState();

const { isShowingSwitchAccount, setIsShowingSwitchAccount } =
useOutletContext<SwitchAccountOutletContext>();
const navigate = useNavigate();
const account = useCurrentStacksAccount();

Expand All @@ -49,12 +48,6 @@ export function Home() {
<AccountCard
name={name}
balance={totalUsdBalance}
switchAccount={
<SwitchAccountDialog
isShowing={isShowingSwitchAccount}
onClose={() => setIsShowingSwitchAccount(false)}
/>
}
toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)}
isLoadingBnsName={isLoadingBnsName}
isLoadingBalance={isInitialLoading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { Box } from 'leather-styles/jsx';

import { useFilteredBitcoinAccounts } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger';
import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { Dialog, getHeightOffset } from '@app/ui/components/containers/dialog/dialog';
import { Dialog } from '@app/ui/components/containers/dialog/dialog';
import { Header } from '@app/ui/components/containers/headers/header';
import { virtuosoHeight, virtuosoStyles } from '@app/ui/shared/virtuoso';
import { VirtuosoWrapper } from '@app/ui/components/virtuoso';

import { AccountListItem } from './account-list-item';

Expand All @@ -23,27 +23,31 @@ export function RecipientAccountsDialog() {

if (stacksAddressesNum === 0 && btcAddressesNum === 0) return null;
const accountNum = stacksAddressesNum || btcAddressesNum;
const maxAccountsShown = accountNum > 10 ? 10 : accountNum;

return (
<Dialog header={<Header variant="dialog" title="My accounts" />} isShowing onClose={onGoBack}>
<Virtuoso
height={virtuosoHeight}
style={{
...virtuosoStyles,
height: `calc(${virtuosoHeight * maxAccountsShown}px + ${getHeightOffset(true, true)}px)`,
}}
itemContent={index => (
<Box key={index} my="space.05" px="space.05">
<AccountListItem
stacksAccount={stacksAccounts[index]}
onClose={onGoBack}
index={index}
/>
</Box>
)}
totalCount={stacksAddressesNum || btcAddressesNum}
/>
<Dialog
header={<Header variant="dialog" title="My accounts" />}
isShowing
onClose={onGoBack}
wrapChildren={false}
>
<VirtuosoWrapper>
<Virtuoso
style={{
height: '100%',
}}
itemContent={index => (
<Box key={index} my="space.05" px="space.05">
<AccountListItem
stacksAccount={stacksAccounts[index]}
onClose={onGoBack}
index={index}
/>
</Box>
)}
totalCount={accountNum}
/>
</VirtuosoWrapper>
</Dialog>
);
}
Loading

0 comments on commit 6f242c3

Please sign in to comment.