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 10, 2024
1 parent 54fce3e commit 49e7d00
Show file tree
Hide file tree
Showing 36 changed files with 351 additions and 50 deletions.
5 changes: 4 additions & 1 deletion src/app/components/account-total-balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import { styled } from 'leather-styles/jsx';
import { SkeletonLoader, shimmerStyles } from '@leather.io/ui';

import { useTotalBalance } from '@app/common/hooks/balance/use-total-balance';
import { useIsPrivateMode } from '@app/store/settings/settings.selectors';
import { PrivateTextLayout } from '@app/ui/components/privacy/private-text.layout';

interface AccountTotalBalanceProps {
btcAddress: string;
stxAddress: string;
}

export const AccountTotalBalance = memo(({ btcAddress, stxAddress }: AccountTotalBalanceProps) => {
const isPrivate = useIsPrivateMode();
const { totalUsdBalance, isFetching, isLoading, isLoadingAdditionalData } = useTotalBalance({
btcAddress,
stxAddress,
Expand All @@ -26,7 +29,7 @@ export const AccountTotalBalance = memo(({ btcAddress, stxAddress }: AccountTota
textStyle="label.02"
data-state={isLoadingAdditionalData || isFetching ? 'loading' : undefined}
>
{totalUsdBalance}
<PrivateTextLayout isPrivate={isPrivate}>{totalUsdBalance}</PrivateTextLayout>
</styled.span>
</SkeletonLoader>
);
Expand Down
25 changes: 25 additions & 0 deletions src/app/components/balance/balance-private.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type HTMLStyledProps } from 'leather-styles/jsx';

import { useTogglePrivateMode } from '@app/store/settings/settings.actions';
import { useIsPrivateMode } from '@app/store/settings/settings.selectors';
import { PrivateTextLayout } from '@app/ui/components/privacy/private-text.layout';

interface BalancePrivateProps extends HTMLStyledProps<'span'> {
children: React.ReactNode;
canClickToShow?: boolean;
}

export function BalancePrivate({ children, canClickToShow, ...rest }: BalancePrivateProps) {
const isPrivateMode = useIsPrivateMode();
const togglePrivateMode = useTogglePrivateMode();

return (
<PrivateTextLayout
{...rest}
isPrivate={isPrivateMode}
onShowValue={canClickToShow ? togglePrivateMode : undefined}
>
{children}
</PrivateTextLayout>
);
}
9 changes: 8 additions & 1 deletion src/app/components/balance/btc-balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ import { formatMoney } from '@leather.io/utils';

import { BitcoinNativeSegwitAccountLoader } from '../loaders/bitcoin-account-loader';
import { BtcBalanceLoader } from '../loaders/btc-balance-loader';
import { BalancePrivate } from './balance-private';

export function BtcBalance() {
return (
<BitcoinNativeSegwitAccountLoader current>
{signer => (
<BtcBalanceLoader address={signer.address}>
{balance => <Caption>{formatMoney(balance.availableBalance)}</Caption>}
{balance => (
<Caption>
<BalancePrivate canClickToShow>
{formatMoney(balance.availableBalance)}
</BalancePrivate>
</Caption>
)}
</BtcBalanceLoader>
)}
</BitcoinNativeSegwitAccountLoader>
Expand Down
8 changes: 7 additions & 1 deletion src/app/components/balance/stx-balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { Caption } from '@leather.io/ui';

import { stacksValue } from '@app/common/stacks-utils';

import { BalancePrivate } from './balance-private';

interface StxBalanceProps {
address: string;
}
Expand All @@ -21,5 +23,9 @@ export function StxBalance(props: StxBalanceProps) {
[filteredBalanceQuery.data?.unlockedBalance.amount]
);

return <Caption>{stxBalance}</Caption>;
return (
<Caption>
<BalancePrivate canClickToShow>{stxBalance}</BalancePrivate>
</Caption>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { openInNewTab } from '@app/common/utils/open-in-new-tab';
import { IncreaseFeeButton } from '@app/components/stacks-transaction-item/increase-fee-button';
import { TransactionTitle } from '@app/components/transaction/transaction-title';
import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useIsPrivateMode } from '@app/store/settings/settings.selectors';

import { TransactionItemLayout } from '../transaction-item/transaction-item.layout';
import { BitcoinTransactionIcon } from './bitcoin-transaction-icon';
Expand All @@ -33,6 +34,7 @@ interface BitcoinTransactionItemProps {
export function BitcoinTransactionItem({ transaction }: BitcoinTransactionItemProps) {
const { pathname } = useLocation();
const navigate = useNavigate();
const isPrivate = useIsPrivateMode();

const { data: inscriptionData } = useInscriptionByOutput(transaction);

Expand Down Expand Up @@ -98,6 +100,7 @@ export function BitcoinTransactionItem({ transaction }: BitcoinTransactionItemPr
txStatus={<BitcoinTransactionStatus transaction={transaction} />}
txTitle={<TransactionTitle title={title} />}
txValue={value}
isPrivate={isPrivate}
/>
);
}
16 changes: 11 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,7 @@ import {
} from '@leather.io/ui';
import { spamFilter } from '@leather.io/utils';

import { PrivateTextLayout } from '@app/ui/components/privacy/private-text.layout';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';

import { parseCryptoAssetBalance } from './crypto-asset-item.layout.utils';
Expand All @@ -25,6 +26,7 @@ interface CryptoAssetItemLayoutProps {
icon: React.ReactNode;
isLoading?: boolean;
isLoadingAdditionalData?: boolean;
isPrivate?: boolean;
onSelectAsset?(symbol: string, contractId?: string): void;
titleLeft: string;
titleRightBulletInfo?: React.ReactNode;
Expand All @@ -39,6 +41,7 @@ export function CryptoAssetItemLayout({
icon,
isLoading = false,
isLoadingAdditionalData = false,
isPrivate = false,
onSelectAsset,
titleLeft,
titleRightBulletInfo,
Expand All @@ -50,17 +53,18 @@ export function CryptoAssetItemLayout({
<SkeletonLoader width="126px" isLoading={isLoading}>
<BasicTooltip
asChild
label={formattedBalance.isAbbreviated ? availableBalanceString : undefined}
label={formattedBalance.isAbbreviated && !isPrivate ? availableBalanceString : undefined}
side="left"
>
<Flex alignItems="center" gap="space.02" textStyle="label.02">
<BulletSeparator>
<styled.span
<PrivateTextLayout
isPrivate={isPrivate}
data-state={isLoadingAdditionalData ? 'loading' : undefined}
className={shimmerStyles}
>
{formattedBalance.value} {balanceSuffix}
</styled.span>
</PrivateTextLayout>
{titleRightBulletInfo}
</BulletSeparator>
</Flex>
Expand All @@ -76,7 +80,9 @@ export function CryptoAssetItemLayout({
data-state={isLoadingAdditionalData ? 'loading' : undefined}
className={shimmerStyles}
>
{availableBalance.amount.toNumber() > 0 ? fiatBalance : null}
<PrivateTextLayout isPrivate={isPrivate}>
{availableBalance.amount.toNumber() > 0 ? fiatBalance : null}
</PrivateTextLayout>
</Caption>
{captionRightBulletInfo}
</BulletSeparator>
Expand Down
17 changes: 17 additions & 0 deletions src/app/components/layout/card/card.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@ export function CardWithBalanceFooter() {
);
}

export function CardWithPrivateBalanceFooter() {
return (
<Component
footer={
<ButtonRow>
<Button fullWidth onClick={() => null}>
Continue
</Button>
<AvailableBalance balance="$10" isPrivate />
</ButtonRow>
}
>
<Box height="40vh">Card content</Box>
</Component>
);
}

export function CardWithBigHeader() {
return (
<Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { Box, Flex, HStack, styled } from 'leather-styles/jsx';

import { InfoCircleIcon } from '@leather.io/ui';

import { PrivateTextLayout } from '@app/ui/components/privacy/private-text.layout';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';

interface AvailableBalanceProps {
balance: string;
balanceTooltipLabel?: string;
isPrivate?: boolean;
}

export function AvailableBalance({
balance,
isPrivate,
balanceTooltipLabel = 'Amount that is immediately available for use after taking into account any pending transactions or holds placed on your account by the protocol.',
}: AvailableBalanceProps) {
return (
Expand All @@ -26,7 +29,7 @@ export function AvailableBalance({
</BasicTooltip>
</HStack>
<styled.span color="ink.text-subdued" mr="space.02" textStyle="caption.01">
{balance}
<PrivateTextLayout isPrivate={isPrivate}>{balance}</PrivateTextLayout>
</styled.span>
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { whenPageMode } from '@app/common/utils';
import { openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab';
import { TransactionTitle } from '@app/components/transaction/transaction-title';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { useIsPrivateMode } from '@app/store/settings/settings.selectors';

import { TransactionItemLayout } from '../transaction-item/transaction-item.layout';
import { IncreaseFeeButton } from './increase-fee-button';
Expand All @@ -41,6 +42,7 @@ export function StacksTransactionItem({
}: StacksTransactionItemProps) {
const { handleOpenStacksTxLink } = useStacksExplorerLink();
const currentAccount = useCurrentStacksAccount();
const isPrivate = useIsPrivateMode();

const { pathname } = useLocation();
const navigate = useNavigate();
Expand Down Expand Up @@ -96,6 +98,7 @@ export function StacksTransactionItem({
txStatus={txStatus}
txTitle={<TransactionTitle title={txTitle} />}
txValue={txValue}
isPrivate={isPrivate}
/>
);
}
14 changes: 9 additions & 5 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 { PrivateTextLayout } from '@app/ui/components/privacy/private-text.layout';

interface TransactionItemLayoutProps {
openTxLink(): void;
rightElement?: ReactNode;
Expand All @@ -13,13 +15,14 @@ interface TransactionItemLayoutProps {
txIcon?: ReactNode;
txStatus?: ReactNode;
children?: ReactNode;
isPrivate?: boolean;
}

function TxValue({ txValue }: { txValue: ReactNode }) {
function TxValue({ txValue, isPrivate }: { txValue: ReactNode; isPrivate?: boolean }) {
return (
<styled.span textStyle="label.02" px="space.02">
<PrivateTextLayout isPrivate={isPrivate} textStyle="label.02" px="space.02">
{txValue}
</styled.span>
</PrivateTextLayout>
);
}

Expand All @@ -31,6 +34,7 @@ export function TransactionItemLayout({
txStatus,
txTitle,
txValue,
isPrivate,
}: TransactionItemLayoutProps) {
return (
<Pressable onClick={openTxLink} my="space.02">
Expand All @@ -49,7 +53,7 @@ export function TransactionItemLayout({
{txStatus && txStatus}
</HStack>
}
titleRight={<TxValue txValue={txValue} />}
titleRight={<TxValue txValue={txValue} isPrivate={isPrivate} />}
captionRight={rightElement}
/>
</Pressable>
Expand Down
25 changes: 20 additions & 5 deletions src/app/features/asset-list/asset-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Stx20TokenAssetList } from '@app/features/asset-list/stacks/stx20-token
import { StxCryptoAssetItem } from '@app/features/asset-list/stacks/stx-crypo-asset-item/stx-crypto-asset-item';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { useHasLedgerKeys } from '@app/store/ledger/ledger.selectors';
import { useIsPrivateMode } from '@app/store/settings/settings.selectors';

import { ConnectLedgerAssetItemFallback } from './_components/connect-ledger-asset-item-fallback';
import { BtcCryptoAssetItem } from './bitcoin/btc-crypto-asset-item/btc-crypto-asset-item';
Expand All @@ -36,6 +37,7 @@ interface AssetListProps {
export function AssetList({ onSelectAsset, variant = 'read-only' }: AssetListProps) {
const currentAccount = useCurrentStacksAccount();
const isLedger = useHasLedgerKeys();
const isPrivate = useIsPrivateMode();

const isReadOnly = variant === 'read-only';

Expand All @@ -60,6 +62,7 @@ export function AssetList({ onSelectAsset, variant = 'read-only' }: AssetListPro
isLoading={isLoading}
onSelectAsset={onSelectAsset}
isLoadingAdditionalData={isLoadingAdditionalData}
isPrivate={isPrivate}
/>
)}
</BtcAssetItemBalanceLoader>
Expand All @@ -85,6 +88,7 @@ export function AssetList({ onSelectAsset, variant = 'read-only' }: AssetListPro
<StxCryptoAssetItem
balance={balance}
isLoading={isLoading}
isPrivate={isPrivate}
onSelectAsset={onSelectAsset}
/>
)}
Expand All @@ -96,14 +100,15 @@ export function AssetList({ onSelectAsset, variant = 'read-only' }: AssetListPro
{(isLoading, tokens) => (
<Sip10TokenAssetList
isLoading={isLoading}
isPrivate={isPrivate}
tokens={tokens}
onSelectAsset={onSelectAsset}
/>
)}
</Sip10TokensLoader>
{isReadOnly && (
<Stx20TokensLoader address={account.address}>
{tokens => <Stx20TokenAssetList tokens={tokens} />}
{tokens => <Stx20TokenAssetList tokens={tokens} isPrivate={isPrivate} />}
</Stx20TokensLoader>
)}
</>
Expand All @@ -117,16 +122,22 @@ export function AssetList({ onSelectAsset, variant = 'read-only' }: AssetListPro
<>
{isReadOnly && (
<Brc20TokensLoader>
{tokens => <Brc20TokenAssetList tokens={tokens} variant={variant} />}
{tokens => (
<Brc20TokenAssetList
tokens={tokens}
variant={variant}
isPrivate={isPrivate}
/>
)}
</Brc20TokensLoader>
)}
{isReadOnly && (
<>
<Src20TokensLoader address={nativeSegwitAccount.address}>
{tokens => <Src20TokenAssetList tokens={tokens} />}
{tokens => <Src20TokenAssetList tokens={tokens} isPrivate={isPrivate} />}
</Src20TokensLoader>
<RunesLoader addresses={[nativeSegwitAccount.address, taprootAccount.address]}>
{runes => <RunesAssetList runes={runes} />}
{runes => <RunesAssetList runes={runes} isPrivate={isPrivate} />}
</RunesLoader>
</>
)}
Expand All @@ -141,7 +152,11 @@ export function AssetList({ onSelectAsset, variant = 'read-only' }: AssetListPro
{account => (
<Sip10TokensLoader address={account.address} filter="unsupported">
{(isLoading, tokens) => (
<Sip10TokenAssetListUnsupported isLoading={isLoading} tokens={tokens} />
<Sip10TokenAssetListUnsupported
isLoading={isLoading}
isPrivate={isPrivate}
tokens={tokens}
/>
)}
</Sip10TokensLoader>
)}
Expand Down
Loading

0 comments on commit 49e7d00

Please sign in to comment.