Skip to content

Commit

Permalink
[LW 10157] Show collateral deposits fee outside tx summary (#1070)
Browse files Browse the repository at this point in the history
* feat: Show collateral deposits fee outside tx summary
  • Loading branch information
lucas-barros committed Apr 25, 2024
1 parent 5425031 commit 7cae9ba
Show file tree
Hide file tree
Showing 24 changed files with 338 additions and 317 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const DropdownMenu = ({ isPopup }: DropdownMenuProps): React.ReactElement
profile={
activeWalletAvatar
? {
fallback: walletName,
fallbackText: walletName,
imageSrc: activeWalletAvatar
}
: undefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const UserInfo = ({ onOpenWalletAccounts, avatarVisible = true }: UserInf
profile={
walletAvatar
? {
fallback: fullWalletName,
fallbackText: fullWalletName,
imageSrc: walletAvatar
}
: undefined
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import React from 'react';
import { truncate, addEllipsis } from '@lace/common';
import { Wallet } from '@lace/cardano';
import { Cardano, AssetInfoWithAmount } from '@cardano-sdk/core';

import styles from './DappAddressSections.module.scss';
import { useTranslate } from '@src/ui/hooks';

import { Text, TransactionAssets, DappTransactionSummary, Tooltip, SummaryExpander, Box, Flex } from '@lace/ui';
import { getAddressTagTranslations, renderAddressTag } from '@src/ui/utils';

interface GroupedAddressAssets {
nfts: Array<AssetInfoWithAmount>;
tokens: Array<AssetInfoWithAmount>;
coins: Array<bigint>;
}

export interface DappAddressSectionProps {
groupedAddresses: Map<Cardano.PaymentAddress, GroupedAddressAssets>;
title: string;
isEnabled: boolean;
coinSymbol: string;
addressType: 'from' | 'to';
ownAddresses: string[];
addressToNameMap?: Map<string, string>;
}

const tryDecodeAsUtf8 = (
value: WithImplicitCoercion<string> | { [Symbol.toPrimitive](hint: 'string'): string }
): string => {
const bytes = Uint8Array.from(Buffer.from(value, 'hex'));
const decoder = new TextDecoder('utf-8');
// Decode the Uint8Array to a UTF-8 string
return decoder.decode(bytes);
};

const getFallbackName = (asset: AssetInfoWithAmount) =>
tryDecodeAsUtf8(asset.assetInfo.name) ? tryDecodeAsUtf8(asset.assetInfo.name) : asset.assetInfo.assetId;

const isNFT = (asset: AssetInfoWithAmount) => asset.assetInfo.supply === BigInt(1);

const getAssetTokenName = (assetWithAmount: AssetInfoWithAmount) => {
if (isNFT(assetWithAmount)) {
return assetWithAmount.assetInfo.nftMetadata?.name ?? getFallbackName(assetWithAmount);
}
return assetWithAmount.assetInfo.tokenMetadata?.ticker ?? getFallbackName(assetWithAmount);
};

const charBeforeEllName = 9;
const charAfterEllName = 0;

type UseTranslate = ReturnType<typeof useTranslate>['t'];

const getTransactionAssetTranslations = (t: UseTranslate) => ({
assetId: t('core.dappTransaction.assetId'),
policyId: t('core.dappTransaction.policyId')
});

const displayGroupedNFTs = (nfts: AssetInfoWithAmount[], t: UseTranslate, testId?: string) =>
nfts.map((nft: AssetInfoWithAmount) => {
const imageSrc = nft.assetInfo.tokenMetadata?.icon ?? nft.assetInfo.nftMetadata?.image ?? undefined;
return (
<TransactionAssets
testId={testId}
key={nft.assetInfo.fingerprint}
imageSrc={imageSrc}
translations={getTransactionAssetTranslations(t)}
balance={Wallet.util.calculateAssetBalance(nft.amount, nft.assetInfo)}
assetId={nft.assetInfo.assetId}
policyId={nft.assetInfo.policyId}
tokenName={truncate(getAssetTokenName(nft), charBeforeEllName, charAfterEllName)}
showImageBackground={imageSrc === undefined}
/>
);
});

const displayGroupedTokens = (tokens: AssetInfoWithAmount[], t: UseTranslate, testId?: string) =>
tokens.map((token: AssetInfoWithAmount) => {
const imageSrc = token.assetInfo.tokenMetadata?.icon ?? token.assetInfo.nftMetadata?.image ?? undefined;

return (
<TransactionAssets
testId={testId}
key={token.assetInfo.fingerprint}
imageSrc={token.assetInfo.tokenMetadata?.icon ?? token.assetInfo.nftMetadata?.image ?? undefined}
translations={getTransactionAssetTranslations(t)}
balance={Wallet.util.calculateAssetBalance(token.amount, token.assetInfo)}
assetId={token.assetInfo.assetId}
policyId={token.assetInfo.policyId}
tokenName={truncate(getAssetTokenName(token), charBeforeEllName, charAfterEllName)}
showImageBackground={imageSrc === undefined}
/>
);
});

const charBeforeEllipsisName = 8;
const charAfterEllipsisName = 8;

const getStringFromLovelace = (value: bigint): string => Wallet.util.lovelacesToAdaString(value.toString());

const getTokenQuantity = (tokens: Array<AssetInfoWithAmount>, coins: Array<bigint>) => {
let quantity = tokens.length;

if (coins.length > 0) {
quantity += 1;
}

return quantity;
};
export const DappAddressSection = ({
groupedAddresses,
isEnabled,
coinSymbol,
title,
addressType,
ownAddresses,
addressToNameMap
}: DappAddressSectionProps): React.ReactElement => {
const { t } = useTranslate();

const itemsCountCopy = t('core.dappTransaction.items');

return (
<SummaryExpander title={title} disabled={!isEnabled} testId={`dapp-transaction-${addressType}-section-expander`}>
{[...groupedAddresses.entries()].map(([address, addressData]) => (
<Box mb="$20" key={address}>
<div key={address} className={styles.address} data-testid={`dapp-transaction-${addressType}-row`}>
<Text.Body.Normal data-testid="dapp-transaction-address-title" weight="$medium">
{t('core.dappTransaction.address')}
</Text.Body.Normal>

<Flex flexDirection="column" alignItems="flex-end" gap="$8">
<Text.Body.Small data-testid="dapp-transaction-address" weight="$medium">
<Tooltip label={address}>{addEllipsis(address, charBeforeEllipsisName, charAfterEllipsisName)}</Tooltip>
</Text.Body.Small>
{renderAddressTag(address, getAddressTagTranslations(t), ownAddresses, addressToNameMap)}
</Flex>
</div>
{(addressData.tokens.length > 0 || addressData.coins.length > 0) && (
<>
<div className={styles.tokenCount} data-testid={`dapp-transaction-${addressType}-row`}>
<Text.Body.Normal data-testid="dapp-transaction-tokens-title" weight="$medium">
{t('core.dappTransaction.tokens')}
</Text.Body.Normal>
<Text.Body.Normal
color={addressType === 'to' ? 'success' : 'primary'}
data-testid="dapp-transaction-tokens-value"
weight="$medium"
>
{addressType === 'to'
? `${getTokenQuantity(addressData.tokens, addressData.coins)} ${itemsCountCopy}`
: `-${getTokenQuantity(addressData.tokens, addressData.coins)} ${itemsCountCopy}`}
</Text.Body.Normal>
</div>
{addressData.coins.map((coin) => (
<DappTransactionSummary
testId={`dapp-transaction-${addressType}-row`}
key={`${address}${coin}`}
adaTooltip={t('core.dappTransaction.adaTooltip')}
cardanoSymbol={coinSymbol}
transactionAmount={getStringFromLovelace(coin)}
/>
))}
{displayGroupedTokens(addressData.tokens, t, `dapp-transaction-${addressType}-row`)}
</>
)}

{addressData.nfts.length > 0 && (
<>
<div className={styles.tokenCount} data-testid={`dapp-transaction-${addressType}-row`}>
<Text.Body.Normal data-testid="dapp-transaction-nfts-title" weight="$medium">
{t('core.dappTransaction.nfts')}
</Text.Body.Normal>
<Text.Body.Normal
data-testid="dapp-transaction-nfts-amount-value"
weight="$medium"
color={addressType === 'to' ? 'success' : 'primary'}
>
{addressType === 'to'
? `${addressData.nfts.length} ${itemsCountCopy}`
: `-${addressData.nfts.length} ${itemsCountCopy}`}
</Text.Body.Normal>
</div>
{displayGroupedNFTs(addressData.nfts, t, `dapp-transaction-${addressType}-row`)}
</>
)}
</Box>
))}
</SummaryExpander>
);
};
Original file line number Diff line number Diff line change
@@ -1,34 +1,14 @@
@import '../../styles/theme.scss';
@import '../../../../../common/src/ui/styles/abstracts/_typography.scss';

.label {
color: var(--text-color-primary, #ffffff) !important;
font-size: 16px;
font-weight: 600;
}

.value {
color: var(--text-color-primary, #ffffff) !important;
font-size: 14px;
font-weight: 500;
}

.address {
display: flex;
justify-content: space-between;
padding: size_unit(2.5) 0;
}

.summaryContent {
padding-bottom: size_unit(2.5);
}

.tokenCount {
display: flex;
justify-content: space-between;
align-items: end;
}

.positiveAmount {
color: var(--data-green, #2CB67D) !important;
}

0 comments on commit 7cae9ba

Please sign in to comment.