diff --git a/packages/core/src/ui/components/DappAddressSections/DappAddressSection.tsx b/packages/core/src/ui/components/DappAddressSections/DappAddressSection.tsx new file mode 100644 index 0000000000..634093e0b2 --- /dev/null +++ b/packages/core/src/ui/components/DappAddressSections/DappAddressSection.tsx @@ -0,0 +1,171 @@ +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 cn from 'classnames'; + +import { Text, TransactionAssets, DappTransactionSummary, Tooltip, SummaryExpander, Box } from '@lace/ui'; + +interface GroupedAddressAssets { + nfts: Array; + tokens: Array; + coins: Array; +} + +export interface DappAddressSectionProps { + groupedAddresses: Map; + title: string; + isEnabled: boolean; + coinSymbol: string; + addressType: 'from' | 'to'; +} + +const tryDecodeAsUtf8 = ( + value: WithImplicitCoercion | { [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; + +const displayGroupedNFTs = (nfts: AssetInfoWithAmount[], testId?: string) => + nfts.map((nft: AssetInfoWithAmount) => { + const imageSrc = nft.assetInfo.tokenMetadata?.icon ?? nft.assetInfo.nftMetadata?.image ?? undefined; + return ( + + ); + }); + +const displayGroupedTokens = (tokens: AssetInfoWithAmount[], testId?: string) => + tokens.map((token: AssetInfoWithAmount) => { + const imageSrc = token.assetInfo.tokenMetadata?.icon ?? token.assetInfo.nftMetadata?.image ?? undefined; + + return ( + + ); + }); + +const charBeforeEllipsisName = 8; +const charAfterEllipsisName = 8; + +const getStringFromLovelace = (value: bigint): string => Wallet.util.lovelacesToAdaString(value.toString()); + +const getTokenQuantity = (tokens: Array, coins: Array) => { + let quantity = tokens.length; + + if (coins.length > 0) { + quantity += 1; + } + + return quantity; +}; +export const DappAddressSection = ({ + groupedAddresses, + isEnabled, + coinSymbol, + title, + addressType +}: DappAddressSectionProps): React.ReactElement => { + const { t } = useTranslate(); + + const itemsCountCopy = t('core.dappTransaction.items'); + + return ( + + {[...groupedAddresses.entries()].map(([address, addressData]) => ( + +
+ + {t('core.dappTransaction.address')} + + + + {addEllipsis(address, charBeforeEllipsisName, charAfterEllipsisName)} + + +
+ {(addressData.tokens.length > 0 || addressData.coins.length > 0) && ( + <> +
+ + {t('core.dappTransaction.tokens')} + + + {addressType === 'to' + ? `${getTokenQuantity(addressData.tokens, addressData.coins)} ${itemsCountCopy}` + : `-${getTokenQuantity(addressData.tokens, addressData.coins)} ${itemsCountCopy}`} + +
+ {addressData.coins.map((coin) => ( + + ))} + {displayGroupedTokens(addressData.tokens, `dapp-transaction-${addressType}-row`)} + + )} + + {addressData.nfts.length > 0 && ( + <> +
+ + {t('core.dappTransaction.nfts')} + + + {addressType === 'to' + ? `${addressData.nfts.length} ${itemsCountCopy}` + : `-${addressData.nfts.length} ${itemsCountCopy}`} + +
+ {displayGroupedNFTs(addressData.nfts, `dapp-transaction-${addressType}-row`)} + + )} +
+ ))} +
+ ); +}; diff --git a/packages/core/src/ui/components/DappAddressSections/DappAddressSections.module.scss b/packages/core/src/ui/components/DappAddressSections/DappAddressSections.module.scss index 0c8f5304b7..ae235d4c7b 100644 --- a/packages/core/src/ui/components/DappAddressSections/DappAddressSections.module.scss +++ b/packages/core/src/ui/components/DappAddressSections/DappAddressSections.module.scss @@ -1,20 +1,16 @@ @import '../../styles/theme.scss'; @import '../../../../../common/src/ui/styles/abstracts/_typography.scss'; +.root { + color: var(--light-mode-black, var(--dark-mode-light-grey)); +} + .address { display: flex; justify-content: space-between; padding: size_unit(2.5) 0; } -.summaryContent { - color: var(--light-mode-black, var(--dark-mode-light-grey)); -} - -.fromAddress { - padding-bottom: size_unit(2.5); -} - .tokenCount { display: flex; justify-content: space-between; diff --git a/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx b/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx index 3f9b371ec2..e5014343e1 100644 --- a/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx +++ b/packages/core/src/ui/components/DappAddressSections/DappAddressSections.tsx @@ -1,13 +1,11 @@ /* eslint-disable sonarjs/no-identical-functions */ 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, SummaryExpander, DappTransactionSummary, Tooltip } from '@lace/ui'; +import { DappAddressSection } from './DappAddressSection'; interface GroupedAddressAssets { nfts: Array; @@ -23,75 +21,6 @@ export interface DappAddressSectionProps { coinSymbol: string; } -const tryDecodeAsUtf8 = ( - value: WithImplicitCoercion | { [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; - -const displayGroupedNFTs = (nfts: AssetInfoWithAmount[], testId?: string) => - nfts.map((nft: AssetInfoWithAmount) => { - const imageSrc = nft.assetInfo.tokenMetadata?.icon ?? nft.assetInfo.nftMetadata?.image ?? undefined; - return ( - - ); - }); - -const displayGroupedTokens = (tokens: AssetInfoWithAmount[], testId?: string) => - tokens.map((token: AssetInfoWithAmount) => { - const imageSrc = token.assetInfo.tokenMetadata?.icon ?? token.assetInfo.nftMetadata?.image ?? undefined; - - return ( - - ); - }); - -const charBeforeEllipsisName = 8; -const charAfterEllipsisName = 8; - -const getStringFromLovelace = (value: bigint): string => Wallet.util.lovelacesToAdaString(value.toString()); - -const getTokenQuantity = (tokens: Array, coins: Array) => { - let quantity = tokens.length; - - if (coins.length > 0) { - quantity += 1; - } - - return quantity; -}; export const DappAddressSections = ({ groupedFromAddresses, groupedToAddresses, @@ -101,133 +30,23 @@ export const DappAddressSections = ({ }: DappAddressSectionProps): React.ReactElement => { const { t } = useTranslate(); - const itemsCountCopy = t('core.dappTransaction.items'); - return ( -
- + -
- {[...groupedFromAddresses.entries()].map(([address, addressData]) => ( - <> -
- - {t('core.dappTransaction.address')} - - - - {addEllipsis(address, charBeforeEllipsisName, charAfterEllipsisName)} - - -
- {(addressData.tokens.length > 0 || addressData.coins.length > 0) && ( - <> -
- - {t('core.dappTransaction.tokens')} - - - -{getTokenQuantity(addressData.tokens, addressData.coins)} {itemsCountCopy} - -
- {addressData.coins.map((coin) => ( - - ))} - {displayGroupedTokens(addressData.tokens, 'dapp-transaction-from-row')} - - )} - - {addressData.nfts.length > 0 && ( - <> -
- - {t('core.dappTransaction.nfts')} - - - -{addressData.nfts.length} {itemsCountCopy} - -
- {displayGroupedNFTs(addressData.nfts, 'dapp-transaction-from-row')} - - )} - - ))} -
-
+ isEnabled={isFromAddressesEnabled} + /> - -
- {[...groupedToAddresses.entries()].map(([address, addressData]) => ( - <> -
- - {t('core.dappTransaction.address')} - - - - {addEllipsis(address, charBeforeEllipsisName, charAfterEllipsisName)} - - -
- {(addressData.tokens.length > 0 || addressData.coins.length > 0) && ( - <> -
- - {t('core.dappTransaction.tokens')} - - - {getTokenQuantity(addressData.tokens, addressData.coins)} {itemsCountCopy} - -
- {addressData.coins.map((coin) => ( - - ))} - {displayGroupedTokens(addressData.tokens, 'dapp-transaction-to-row')} - - )} - - {addressData.nfts.length > 0 && ( - <> -
- - {t('core.dappTransaction.nfts')} - - - {addressData.nfts.length} {itemsCountCopy} - -
- {displayGroupedNFTs(addressData.nfts, 'dapp-transaction-to-row')} - - )} - - ))} -
-
+ isEnabled={isToAddressesEnabled} + />
); };