From 2394961d4e1334aa8db878d9a18c897e1463f81c Mon Sep 17 00:00:00 2001 From: Pedro Figueiredo Date: Mon, 21 Oct 2024 18:17:28 +0100 Subject: [PATCH] fix: Reduce usage of scientific notation --- .../info/hooks/use-token-values.test.ts | 62 ++++++++++++++++++- .../confirm/info/hooks/use-token-values.ts | 39 +++++++++++- .../info/shared/send-heading/send-heading.tsx | 38 ++++++++---- .../token-transfer.test.tsx.snap | 2 +- 4 files changed, 125 insertions(+), 16 deletions(-) diff --git a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts index 1ed5e9c249ff..e66c8f3046e8 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts @@ -5,7 +5,11 @@ import mockState from '../../../../../../../test/data/mock-state.json'; import { renderHookWithConfirmContextProvider } from '../../../../../../../test/lib/confirmations/render-helpers'; import useTokenExchangeRate from '../../../../../../components/app/currency-input/hooks/useTokenExchangeRate'; import { useAssetDetails } from '../../../../hooks/useAssetDetails'; -import { useTokenValues } from './use-token-values'; +import { + roundDisplayValue, + toNonScientificString, + useTokenValues, +} from './use-token-values'; import { useDecodedTransactionData } from './useDecodedTransactionData'; jest.mock('../../../../hooks/useAssetDetails', () => ({ @@ -73,7 +77,8 @@ describe('useTokenValues', () => { await waitForNextUpdate(); expect(result.current).toEqual({ - decodedTransferValue: 7, + decodedTransferValue: '7', + displayTransferValue: '7', fiatDisplayValue: '$6.37', pending: false, }); @@ -118,9 +123,60 @@ describe('useTokenValues', () => { await waitForNextUpdate(); expect(result.current).toEqual({ - decodedTransferValue: 7, + decodedTransferValue: '7', + displayTransferValue: '7', fiatDisplayValue: null, pending: false, }); }); }); + +describe('roundDisplayValue', () => { + const TEST_CASES = [ + { value: 0, rounded: '0' }, + { value: 0.0000009, rounded: '<0.000001' }, + { value: 0.0000456, rounded: '0.000046' }, + { value: 0.0004567, rounded: '0.000457' }, + { value: 0.003456, rounded: '0.00346' }, + { value: 0.023456, rounded: '0.0235' }, + { value: 0.125456, rounded: '0.125' }, + { value: 1.0034, rounded: '1.003' }, + { value: 1.034, rounded: '1.034' }, + { value: 1.3034, rounded: '1.303' }, + { value: 7, rounded: '7' }, + { value: 7.1, rounded: '7.1' }, + { value: 12.0345, rounded: '12.03' }, + { value: 121.456, rounded: '121.5' }, + { value: 1034.123, rounded: '1034' }, + { value: 47361034.006, rounded: '47361034' }, + { value: 12130982923409.555, rounded: '12130982923410' }, + ]; + + // @ts-expect-error This is missing from the Mocha type definitions + it.each(TEST_CASES)( + 'Round $value to "$rounded"', + ({ value, rounded }: { value: number; rounded: string }) => { + const actual = roundDisplayValue(value); + + expect(actual).toEqual(rounded); + }, + ); +}); + +describe('toNonScientificString', () => { + const TEST_CASES = [ + { scientific: 1.23e-5, expanded: '0.0000123' }, + { scientific: 1e-10, expanded: '0.0000000001' }, + { scientific: 1.23e-21, expanded: '1.23e-21' }, + ]; + + // @ts-expect-error This is missing from the Mocha type definitions + it.each(TEST_CASES)( + 'Expand $scientific to "$expanded"', + ({ scientific, expanded }: { scientific: number; expanded: string }) => { + const actual = toNonScientificString(scientific); + + expect(actual).toEqual(expanded); + }, + ); +}); diff --git a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts index 139a1e8116b9..6fb3c38629f4 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts @@ -56,9 +56,46 @@ export const useTokenValues = (transactionMeta: TransactionMeta) => { const fiatDisplayValue = fiatValue && fiatFormatter(fiatValue, { shorten: true }); + const displayTransferValue = roundDisplayValue(decodedTransferValue); + return { - decodedTransferValue, + decodedTransferValue: toNonScientificString(decodedTransferValue), + displayTransferValue, fiatDisplayValue, pending, }; }; + +export function roundDisplayValue(decodedTransferValue: number): string { + switch (true) { + case decodedTransferValue === 0: + return '0'; + case decodedTransferValue < 0.000001: + return '<0.000001'; + case decodedTransferValue < 0.001: + return parseFloat(decodedTransferValue.toFixed(6)).toString(); + case decodedTransferValue < 0.01: + return parseFloat(decodedTransferValue.toFixed(5)).toString(); + case decodedTransferValue < 0.1: + return parseFloat(decodedTransferValue.toFixed(4)).toString(); + case decodedTransferValue < 10: + return parseFloat(decodedTransferValue.toFixed(3)).toString(); + case decodedTransferValue < 100: + return parseFloat(decodedTransferValue.toFixed(2)).toString(); + case decodedTransferValue < 1000: + return parseFloat(decodedTransferValue.toFixed(1)).toString(); + case decodedTransferValue < 10000: + return parseFloat(decodedTransferValue.toFixed(0)).toString(); + default: + return parseFloat(decodedTransferValue.toFixed(0)).toString(); + } +} + +export function toNonScientificString(num: number): string { + if (num >= 10e-18) { + return num.toFixed(18).replace(/\.?0+$/u, ''); + } + + // keep in scientific notation + return num.toString(); +} diff --git a/ui/pages/confirmations/components/confirm/info/shared/send-heading/send-heading.tsx b/ui/pages/confirmations/components/confirm/info/shared/send-heading/send-heading.tsx index 2806c33936c0..0a98f28dd501 100644 --- a/ui/pages/confirmations/components/confirm/info/shared/send-heading/send-heading.tsx +++ b/ui/pages/confirmations/components/confirm/info/shared/send-heading/send-heading.tsx @@ -23,6 +23,7 @@ import { useConfirmContext } from '../../../../../context/confirm'; import { useTokenImage } from '../../hooks/use-token-image'; import { useTokenValues } from '../../hooks/use-token-values'; import { ConfirmLoader } from '../confirm-loader/confirm-loader'; +import Tooltip from '../../../../../../../components/ui/tooltip'; const SendHeading = () => { const t = useI18nContext(); @@ -32,8 +33,12 @@ const SendHeading = () => { getWatchedToken(transactionMeta)(state), ); const { tokenImage } = useTokenImage(transactionMeta, selectedToken); - const { decodedTransferValue, fiatDisplayValue, pending } = - useTokenValues(transactionMeta); + const { + decodedTransferValue, + displayTransferValue, + fiatDisplayValue, + pending, + } = useTokenValues(transactionMeta); const TokenImage = ( { /> ); - const TokenValue = ( - <> + const TokenValue = + displayTransferValue === decodedTransferValue.toString() ? ( {`${decodedTransferValue || ''} ${ + >{`${displayTransferValue} ${ selectedToken?.symbol || t('unknown') }`} - {fiatDisplayValue && ( - - {fiatDisplayValue} - - )} - + ) : ( + + {`${displayTransferValue} ${ + selectedToken?.symbol || t('unknown') + }`} + + ); + + const TokenFiatValue = fiatDisplayValue && ( + + {fiatDisplayValue} + ); if (pending) { @@ -82,6 +97,7 @@ const SendHeading = () => { > {TokenImage} {TokenValue} + {TokenFiatValue} ); }; diff --git a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap index e1d19241252b..f7a672912907 100644 --- a/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/token-transfer/__snapshots__/token-transfer.test.tsx.snap @@ -13,7 +13,7 @@ exports[`TokenTransferInfo renders correctly 1`] = `

- Unknown + 0 Unknown