Skip to content

Commit

Permalink
feat: add option to hide balance, closes leather-io#5096
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianocola committed Sep 2, 2024
1 parent 6b9566a commit f4f8415
Show file tree
Hide file tree
Showing 12 changed files with 218 additions and 63 deletions.
20 changes: 20 additions & 0 deletions src/app/common/hide-balance-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createContext, useContext } from 'react';

interface HideBalanceContextProps {
hideBalance?: boolean;
}
const hideBalanceProvider = createContext<HideBalanceContextProps | null>(null);

const { Provider } = hideBalanceProvider;

export function useHideBalanceContext() {
return !!useContext(hideBalanceProvider)?.hideBalance;
}

interface HideBalanceProviderProps {
children: React.ReactNode;
hideBalance?: boolean;
}
export function HideBalanceProvider({ children, hideBalance }: HideBalanceProviderProps) {
return <Provider value={{ hideBalance }}>{children}</Provider>;
}
13 changes: 13 additions & 0 deletions src/app/components/balance/hideable-balance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type HTMLStyledProps, styled } from 'leather-styles/jsx';

import { useHideBalanceContext } from '@app/common/hide-balance-provider';

interface HideableBalanceProps extends HTMLStyledProps<'span'> {
children: React.ReactNode;
forceHidden?: boolean;
}
export function HideableBalance({ forceHidden, children, ...rest }: HideableBalanceProps) {
const hideBalance = useHideBalanceContext();

return <styled.span {...rest}>{hideBalance || forceHidden ? '•••••' : children}</styled.span>;
}
15 changes: 10 additions & 5 deletions src/app/components/crypto-asset-item/crypto-asset-item.layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Flex, styled } from 'leather-styles/jsx';
import { Box, Flex } from 'leather-styles/jsx';

import type { Money } from '@leather.io/models';
import {
Expand All @@ -11,6 +11,8 @@ import {
} from '@leather.io/ui';
import { spamFilter } from '@leather.io/utils';

import { useHideBalanceContext } from '@app/common/hide-balance-provider';
import { HideableBalance } from '@app/components/balance/hideable-balance';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';

import { parseCryptoAssetBalance } from './crypto-asset-item.layout.utils';
Expand Down Expand Up @@ -43,24 +45,25 @@ export function CryptoAssetItemLayout({
titleLeft,
titleRightBulletInfo,
}: CryptoAssetItemLayoutProps) {
const hideBalance = useHideBalanceContext();
const { availableBalanceString, dataTestId, formattedBalance } =
parseCryptoAssetBalance(availableBalance);

const titleRight = (
<SkeletonLoader width="126px" isLoading={isLoading}>
<BasicTooltip
asChild
label={formattedBalance.isAbbreviated ? availableBalanceString : undefined}
label={formattedBalance.isAbbreviated && !hideBalance ? availableBalanceString : undefined}
side="left"
>
<Flex alignItems="center" gap="space.02" textStyle="label.02">
<BulletSeparator>
<styled.span
<HideableBalance
data-state={isLoadingAdditionalData ? 'loading' : undefined}
className={shimmerStyles}
>
{formattedBalance.value} {balanceSuffix}
</styled.span>
</HideableBalance>
{titleRightBulletInfo}
</BulletSeparator>
</Flex>
Expand All @@ -76,7 +79,9 @@ export function CryptoAssetItemLayout({
data-state={isLoadingAdditionalData ? 'loading' : undefined}
className={shimmerStyles}
>
{availableBalance.amount.toNumber() > 0 ? fiatBalance : null}
<HideableBalance>
{availableBalance.amount.toNumber() > 0 ? fiatBalance : null}
</HideableBalance>
</Caption>
{captionRightBulletInfo}
</BulletSeparator>
Expand Down
10 changes: 8 additions & 2 deletions src/app/components/transaction-item/transaction-item.layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { ReactNode } from 'react';

import { HStack, styled } from 'leather-styles/jsx';
import { HStack } from 'leather-styles/jsx';

import { Caption, ItemLayout, Pressable } from '@leather.io/ui';

import { HideableBalance } from '@app/components/balance/hideable-balance';

interface TransactionItemLayoutProps {
openTxLink(): void;
rightElement?: ReactNode;
Expand Down Expand Up @@ -42,7 +44,11 @@ export function TransactionItemLayout({
</HStack>
}
titleRight={
rightElement ? rightElement : <styled.span textStyle="label.02">{txValue}</styled.span>
rightElement ? (
rightElement
) : (
<HideableBalance textStyle="label.02">{txValue}</HideableBalance>
)
}
/>
</Pressable>
Expand Down
75 changes: 42 additions & 33 deletions src/app/pages/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Box, Stack } from 'leather-styles/jsx';
import { RouteUrls } from '@shared/route-urls';
import { SwitchAccountOutletContext } from '@shared/switch-account';

import { HideBalanceProvider } from '@app/common/hide-balance-provider';
import { useAccountDisplayName } from '@app/common/hooks/account/use-account-names';
import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state';
import { useTotalBalance } from '@app/common/hooks/balance/use-total-balance';
Expand All @@ -18,6 +19,8 @@ import { ModalBackgroundWrapper } from '@app/routes/components/modal-background-
import { useCurrentAccountIndex } from '@app/store/accounts/account';
import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { useToggleHideBalance } from '@app/store/settings/settings.actions';
import { useHideBalance } from '@app/store/settings/settings.selectors';
import { AccountCard } from '@app/ui/components/account/account.card';

import { AccountActions } from './components/account-actions';
Expand All @@ -30,6 +33,8 @@ export function Home() {
const navigate = useNavigate();
const account = useCurrentStacksAccount();
const currentAccountIndex = useCurrentAccountIndex();
const hideBalance = useHideBalance();
const toggleHideBalance = useToggleHideBalance();

const { data: name = '', isFetching: isFetchingBnsName } = useAccountDisplayName({
address: account?.address || '',
Expand All @@ -47,39 +52,43 @@ export function Home() {
});

return (
<Stack
data-testid={HomePageSelectors.HomePageContainer}
px={{ base: 0, md: 'space.05' }}
py={{ base: 0, md: 'space.07' }}
gap={{ base: 0, md: 'space.06' }}
width="100%"
bg="ink.1"
borderRadius="lg"
animation="fadein"
animationDuration="500ms"
>
<Box px={{ base: 'space.05', md: 0 }} pb={{ base: 'space.05', md: 0 }}>
<AccountCard
name={name}
balance={totalUsdBalance}
toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)}
isFetchingBnsName={isFetchingBnsName}
isLoadingBalance={isLoading}
isLoadingAdditionalData={isLoadingAdditionalData}
>
<AccountActions />
</AccountCard>
</Box>
<FeedbackButton />
<HomeTabs>
<ModalBackgroundWrapper>
<Route index element={<Assets />} />
<Route path={RouteUrls.Activity} element={<ActivityList />}>
<HideBalanceProvider hideBalance={hideBalance}>
<Stack
data-testid={HomePageSelectors.HomePageContainer}
px={{ base: 0, md: 'space.05' }}
py={{ base: 0, md: 'space.07' }}
gap={{ base: 0, md: 'space.06' }}
width="100%"
bg="ink.1"
borderRadius="lg"
animation="fadein"
animationDuration="500ms"
>
<Box px={{ base: 'space.05', md: 0 }} pb={{ base: 'space.05', md: 0 }}>
<AccountCard
name={name}
balance={totalUsdBalance}
toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)}
toggleHideBlance={toggleHideBalance}
isFetchingBnsName={isFetchingBnsName}
isLoadingBalance={isLoading}
isLoadingAdditionalData={isLoadingAdditionalData}
hideBalance={hideBalance}
>
<AccountActions />
</AccountCard>
</Box>
<FeedbackButton />
<HomeTabs>
<ModalBackgroundWrapper>
<Route index element={<Assets />} />
<Route path={RouteUrls.Activity} element={<ActivityList />}>
{homePageModalRoutes}
</Route>
{homePageModalRoutes}
</Route>
{homePageModalRoutes}
</ModalBackgroundWrapper>
</HomeTabs>
</Stack>
</ModalBackgroundWrapper>
</HomeTabs>
</Stack>
</HideBalanceProvider>
);
}
5 changes: 5 additions & 0 deletions src/app/store/settings/settings.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ export function useDismissMessage() {
const dispatch = useDispatch();
return (messageId: string) => dispatch(settingsActions.messageDismissed(messageId));
}

export function useToggleHideBalance() {
const dispatch = useDispatch();
return () => dispatch(settingsActions.toggleHideBlance());
}
6 changes: 6 additions & 0 deletions src/app/store/settings/settings.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ const selectDismissedMessageIds = createSelector(
export function useDismissedMessageIds() {
return useSelector(selectDismissedMessageIds);
}

const selectHideBalance = createSelector(selectSettings, state => state.hideBalance ?? false);

export function useHideBalance() {
return useSelector(selectHideBalance);
}
4 changes: 4 additions & 0 deletions src/app/store/settings/settings.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UserSelectedTheme } from '@app/common/theme-provider';
interface InitialState {
userSelectedTheme: UserSelectedTheme;
dismissedMessages: string[];
hideBalance?: boolean;
}

const initialState: InitialState = {
Expand All @@ -26,5 +27,8 @@ export const settingsSlice = createSlice({
resetMessages(state) {
state.dismissedMessages = [];
},
toggleHideBlance(state) {
state.hideBalance = !state.hideBalance;
},
},
});
24 changes: 24 additions & 0 deletions src/app/ui/components/account/account.card.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function AccountCard() {
name="leather.btc"
balance="$1,000"
toggleSwitchAccount={() => null}
toggleHideBlance={() => null}
isLoadingBalance={false}
isFetchingBnsName={false}
>
Expand All @@ -44,6 +45,7 @@ export function AccountCardLoading() {
name="leather.btc"
balance="$1,000"
toggleSwitchAccount={() => null}
toggleHideBlance={() => null}
isLoadingBalance
isFetchingBnsName={false}
>
Expand All @@ -63,6 +65,7 @@ export function AccountCardBnsNameLoading() {
name="leather.btc"
balance="$1,000"
toggleSwitchAccount={() => null}
toggleHideBlance={() => null}
isLoadingBalance={false}
isFetchingBnsName
>
Expand All @@ -75,3 +78,24 @@ export function AccountCardBnsNameLoading() {
</Component>
);
}

export function AccountCardHiddenBalance() {
return (
<Component
name="leather.btc"
balance="$1,000"
toggleSwitchAccount={() => null}
toggleHideBlance={() => null}
isLoadingBalance={false}
isFetchingBnsName={false}
hideBalance
>
<Flex justify="space-between">
<IconButton icon={<ArrowUpIcon />} label="Send" />
<IconButton icon={<ArrowDownIcon />} label="Receive" />
<IconButton icon={<PlusIcon />} label="Buy" />
<IconButton icon={<ArrowsRepeatLeftRightIcon />} label="Swap" />
</Flex>
</Component>
);
}
Loading

0 comments on commit f4f8415

Please sign in to comment.