Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(TokenEnterAmount): add new flow to EnterAmount.tsx #6245

Merged
merged 77 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
e5ab0a5
add new TokenEnterAmount component
sviderock Nov 18, 2024
2fbc1b2
fix exports
sviderock Nov 18, 2024
b12d50f
Merge branch 'main' into slava/add-new-enter-amount-component
sviderock Nov 18, 2024
8af7b8d
Add reusable useEnterAmount hook
sviderock Nov 18, 2024
44c0aab
remove unused code
sviderock Nov 18, 2024
1aa17d6
change flow on send
sviderock Nov 19, 2024
4ed89fc
fix tests
sviderock Nov 19, 2024
d0c7099
fix jumpstart
sviderock Nov 19, 2024
b7e5107
remove unnecessary changes
sviderock Nov 19, 2024
6ca6f92
Merge branch 'main' into slava/add-new-enter-amount-component
sviderock Nov 19, 2024
f2185bc
Merge branch 'slava/add-new-enter-amount-component' into slava/add-en…
sviderock Nov 19, 2024
8762401
Merge branch 'slava/add-enter-amount-hook' into slava/change-send-flow
sviderock Nov 19, 2024
98938bc
fix knip
sviderock Nov 19, 2024
5a3f776
uncomment some tests
sviderock Nov 19, 2024
9360626
fixes
sviderock Nov 19, 2024
b3f3c67
add tests
sviderock Nov 20, 2024
8ce68a4
clear up console logs
sviderock Nov 20, 2024
c2773fa
Merge branch 'slava/add-new-enter-amount-component' into slava/add-en…
sviderock Nov 20, 2024
37455cb
WIP: tests for the hook
sviderock Nov 20, 2024
8357b18
reformat groupNumber, finish number formatting tests
sviderock Nov 21, 2024
f5db952
add useEnterAmount initial tests
sviderock Nov 21, 2024
130b620
finish tests
sviderock Nov 21, 2024
10fb5bd
revert unnecessary change
sviderock Nov 21, 2024
112e5f9
Merge branch 'main' into slava/add-new-enter-amount-component
sviderock Nov 21, 2024
bce9c2b
Merge branch 'slava/add-new-enter-amount-component' into slava/add-en…
sviderock Nov 21, 2024
7048f8e
Merge branch 'slava/add-enter-amount-hook' into slava/change-send-flow
sviderock Nov 21, 2024
a08f3a9
format input values
sviderock Nov 22, 2024
22f4a44
fix tests
sviderock Nov 22, 2024
78218f6
fix zero values for readable amounts
sviderock Nov 22, 2024
cea53aa
add comments
sviderock Nov 22, 2024
060a81a
Merge branch 'slava/add-enter-amount-hook' into slava/change-send-flow
sviderock Nov 22, 2024
8d80b3d
add comment
sviderock Nov 22, 2024
f9b5e31
unskip test that checks logic when fiat prices unavailable
sviderock Nov 22, 2024
0d64a5b
fix as per the review
sviderock Nov 22, 2024
2031bbc
fix as per the review comments
sviderock Nov 25, 2024
d7b5f0a
Merge branch 'main' into slava/add-new-enter-amount-component
sviderock Nov 25, 2024
6d738e4
Merge branch 'slava/add-new-enter-amount-component' into slava/add-en…
sviderock Nov 25, 2024
4c9ed39
remove refs and their handlers outside of the component
sviderock Nov 25, 2024
e1dbbec
refactor tests related to amount formatting
sviderock Nov 25, 2024
e9fc844
rename readabale to display
sviderock Nov 25, 2024
ec1f0a8
change variables names
sviderock Nov 25, 2024
96bc9b3
Merge branch 'slava/add-enter-amount-hook' into slava/change-send-flow
sviderock Nov 25, 2024
2c6f88b
fix tests after changes to hook
sviderock Nov 26, 2024
1a0c2bc
Merge branch 'main' into slava/add-new-enter-amount-component
sviderock Nov 26, 2024
6921dc5
Merge branch 'slava/add-new-enter-amount-component' into slava/add-en…
sviderock Nov 26, 2024
bcb4c6f
Merge branch 'slava/add-enter-amount-hook' into slava/change-send-flow
sviderock Nov 26, 2024
5d85bbd
remove unused callback
sviderock Nov 26, 2024
da1652b
change derived to processedAmounts
sviderock Nov 26, 2024
f57fac6
rename readable to displayAmount
sviderock Nov 26, 2024
39c6766
remove unnecessary hooks and mocks
sviderock Nov 26, 2024
cdd8396
fix tests as per review
sviderock Nov 26, 2024
6bb7c89
fix tests
sviderock Nov 26, 2024
1f40e7c
fix test
sviderock Nov 26, 2024
5cec1fb
Merge branch 'slava/add-enter-amount-hook' into slava/change-send-flow
sviderock Nov 26, 2024
b9f21de
fix as per the comments, adjust to "max" button
sviderock Nov 26, 2024
3858035
Merge branch 'main' into slava/change-send-flow
sviderock Nov 26, 2024
4eb45ba
unskip "max" tests
sviderock Nov 26, 2024
639e612
replace props.children check with .toHaveTextContent() in tests
sviderock Nov 26, 2024
080de6d
fix lint
sviderock Nov 27, 2024
e0de08b
add spacing for title
sviderock Nov 27, 2024
8001e05
fix percentages
sviderock Nov 28, 2024
ae82212
rename handler for better clarity
sviderock Nov 28, 2024
7714b4d
clear percentage on token select
sviderock Nov 28, 2024
b91f09d
change as per the review
sviderock Nov 29, 2024
fbcd741
Merge branch 'main' into slava/change-send-flow
sviderock Nov 29, 2024
757a759
revert some changes
sviderock Nov 29, 2024
8aed766
remove unused ref
sviderock Nov 29, 2024
ac325bd
fix 2e2
sviderock Nov 29, 2024
c5bc604
fix assets e2e
sviderock Nov 29, 2024
c0b5ab2
try to fix assets again
sviderock Nov 29, 2024
81991b5
ignore currency symbols for unformat function, cover new functions wi…
sviderock Nov 29, 2024
7c746d6
revert changes with removing symbols
sviderock Nov 29, 2024
12b4e47
fix: fee amount formatting on android
kathaypacific Dec 2, 2024
6d6ae26
fix: avoid showing fees when no amount
kathaypacific Dec 2, 2024
e54e741
fix: more than max amount set when max amount selected
kathaypacific Dec 2, 2024
1aa565d
fix: ensure token symbol displayed in secondary amount
kathaypacific Dec 2, 2024
5e2dbee
chore: increase switch icon touch area
kathaypacific Dec 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions locales/base/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -2208,6 +2208,7 @@
"title": "Enter Amount",
"selectToken": "Select a Token",
"networkFee": "{{networkName}} Network Fee",
"networkFeeV1_97": "Network Fee",
"lowerAmount": "Enter a lower amount",
"maxAmountWarning": {
"title": "Sending the maximum amount",
Expand Down
3 changes: 2 additions & 1 deletion src/components/TokenDisplay.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as React from 'react'
import 'react-native'
import { Provider } from 'react-redux'
import TokenDisplay, { formatValueToDisplay } from 'src/components/TokenDisplay'
import { APPROX_SYMBOL } from 'src/components/TokenEnterAmount'
import { LocalCurrencyCode } from 'src/localCurrency/consts'
import { RootState } from 'src/redux/reducers'
import { NetworkId } from 'src/transactions/types'
Expand Down Expand Up @@ -253,7 +254,7 @@ describe('TokenDisplay', () => {
/>
</Provider>
)
expect(getElementText(getByTestId('test'))).toEqual(`~10.00 cUSD`)
expect(getElementText(getByTestId('test'))).toEqual(`${APPROX_SYMBOL} 10.00 cUSD`)
})
})
})
Expand Down
3 changes: 2 additions & 1 deletion src/components/TokenDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BigNumber from 'bignumber.js'
import * as React from 'react'
import { StyleProp, Text, TextStyle } from 'react-native'
import { APPROX_SYMBOL } from 'src/components/TokenEnterAmount'
import { LocalCurrencyCode, LocalCurrencySymbol } from 'src/localCurrency/consts'
import { getLocalCurrencySymbol, usdToLocalCurrencyRateSelector } from 'src/localCurrency/selectors'
import { useSelector } from 'src/redux/hooks'
Expand Down Expand Up @@ -81,7 +82,7 @@ function TokenDisplay({
errorFallback
) : (
<>
{showApprox && '~'}
{showApprox && `${APPROX_SYMBOL} `}
{sign}
{showLocalAmount && fiatSymbol}
{amountToShow.isNaN()
Expand Down
6 changes: 2 additions & 4 deletions src/components/TokenEnterAmount.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ describe('TokenEnterAmount', () => {
decimals: 6,
tokenId: mockUSDCTokenId,
priceUsd: new BigNumber(1.001),
balance: new BigNumber(1500.76),
} as TokenBalance,
})

Expand All @@ -173,12 +174,10 @@ describe('TokenEnterAmount', () => {
expect(result.current.amount).toBe('1234.678')
expect(result.current.processedAmounts).toStrictEqual({
token: {
amount: '1234.678',
bignum: new BigNumber('1234.678'),
displayAmount: '1,234.678 USDC',
},
local: {
amount: '1235.91',
bignum: new BigNumber('1235.912678'),
displayAmount: '$1,235.91',
},
Expand All @@ -193,6 +192,7 @@ describe('TokenEnterAmount', () => {
decimals: 6,
tokenId: mockUSDCTokenId,
priceUsd: new BigNumber(1.001),
balance: new BigNumber(1500.76),
} as TokenBalance,
})

Expand All @@ -203,12 +203,10 @@ describe('TokenEnterAmount', () => {
expect(result.current.amount).toBe('1234.67')
expect(result.current.processedAmounts).toStrictEqual({
local: {
amount: '1234.67',
bignum: new BigNumber('1234.67'),
displayAmount: '$1,234.67',
},
token: {
amount: '1233.436563',
bignum: new BigNumber('1233.436563'),
displayAmount: '1,233.436563 USDC',
},
Expand Down
135 changes: 85 additions & 50 deletions src/components/TokenEnterAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
export const APPROX_SYMBOL = '≈'

const BORDER_RADIUS = 12
export const FETCH_UPDATED_TRANSACTIONS_DEBOUNCE_TIME_MS = 250

/**
* This function formats numbers in a "1234.5678" format into the correct format according to the
Expand All @@ -48,6 +49,16 @@
.replaceAll('_', groupingSeparator)
}

export function unformatNumberForProcessing(value: string) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function unformatNumberForProcessing(value: string) {
export function formatNumberToStandard(value: string) {

or parseNumberToStandardFormat or applyUSNumberFormatting?

Copy link
Contributor Author

@sviderock sviderock Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kathaypacific hmm, I'm still unsure on this one. It is only used in a single place so far to actually un-format already formatted number that comes from the input and format it for the processing purposes. I think it makes a more clear distinction for the specific purpose of the function:

  • it unformats the number (which implies it was formatted in the first place)
  • it formats it specifically for processing

I've only made is a separate function to simplify description as otherwise I'd need to write a comment explaining what it does and why, which feels more concise in a form of a clear function name.

In case of formatNumberToStandard/parseNumberToStandardFormat - we need to define what we mean by "standard". And in case of applyUSNumberFormatting - we need to understand why we specifically use US number formatting (even though I'm not sure it's US specific as up to this point I thought this was a general format that everyone uses and was always using it myself 😄)

At least, that's my train of though. What do you think about it?

const { decimalSeparator, groupingSeparator } = getNumberFormatSettings()
return value.replaceAll(groupingSeparator, '').replaceAll(decimalSeparator, '.')

Check warning on line 54 in src/components/TokenEnterAmount.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/TokenEnterAmount.tsx#L53-L54

Added lines #L53 - L54 were not covered by tests
}

export function roundLocalNumber(value: BigNumber | null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function roundLocalNumber(value: BigNumber | null) {
export function roundFiatValue(value: BigNumber | null) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

side thought, no need to address now but i wonder if this will be handy to have as a general function that can be used in other places like the transaction feed....

Copy link
Contributor Author

@sviderock sviderock Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kathaypacific I think it definitely will be. Considering that it is currently only used in this file - there's no point in moving it to a general utility yet file but we should keep this in mind for when its gonna be useful.

if (!value) return ''
return value.isLessThan(0.01) ? value.toPrecision(1) : value.toFixed(2)
}

/**
* This function returns complete formatted value for a token (crypto) amount when it is being a
* converted value (in "ExchangeAmount" element).
Expand Down Expand Up @@ -83,7 +94,7 @@
return `<${localCurrencySymbol}0${decimalSeparator}000001`
}

const roundedAmount = bignum.isLessThan(0.01) ? bignum.toPrecision(1) : bignum.toFixed(2)
const roundedAmount = roundLocalNumber(bignum)
const formattedAmount = formatNumber(roundedAmount.toString())
return `${localCurrencySymbol}${formattedAmount}`
}
Expand All @@ -95,62 +106,53 @@
export function useEnterAmount(props: {
token: TokenBalance
inputRef: React.RefObject<RNTextInput>
onHandleAmountInputChange?(value: string): void
}) {
const { decimalSeparator, groupingSeparator } = getNumberFormatSettings()

/**
* This field is formatted for processing purpose. It is a lot easier to process a number formatted
* in a single format, rather than writing different logic for various combinations of decimal
* and grouping separators. The format is "1234.5678".
*/
const [amount, setAmount] = useState('')
const [amountType, setAmountType] = useState<AmountEnteredIn>('token')

// this should never be null, just adding a default to make TS happy
// This should never be null, just adding a default to make TS happy
const localCurrencySymbol = useSelector(getLocalCurrencySymbol) ?? LocalCurrencySymbol.USD
const usdToLocalRate = useSelector(usdToLocalCurrencyRateSelector)

/**
* This field is for processing purposes only. It is a lot easier to process a number formatted
* in a single format, rather than writing different logic for various combinations of decimal
* and grouping separators. The format is "1234.5678"
*/
const amountRaw = useMemo(() => {
return formatNumber(amount).replaceAll(groupingSeparator, '').replaceAll(decimalSeparator, '.')
}, [amount])

/**
* This field includes all the necessary processed derived state. It is recalculated once whenever
* the input amount changes. Please, add new processed/calculated values to this variable.
*
* This field consists of two values: token and local. Both values represent calculated values for the
* corresponding amount type. Whenever we change token amount - we need to recalculate both token and
* local amounts. Each object consists of:
* - "amount" - this is the actual value, formatted to the unified format without any groupings
* and with a point as a decimal separator, format example: "1234.5678" (as per "amountRaw" value above)
* - "bignum" - this is a BigNumber representation of the "amount" field. Necessary for easier
* - `bignum` - this is a BigNumber representation of the "amount" field. Necessary for easier
* condition checks and various processing things.
* - "displayAmount" - this is a read-only component-friendly value that contains all of the necessary
* - `displayAmount` - this is a read-only component-friendly value that contains all of the necessary
* formatting, including: grouping, decimals, token symbol/fiat sign, small amounts format. This
* value is only necessary to be passed to TokenEnterAmount component fields as:
* - token.displayAmount -> tokenAmount
* - local.displayAmount -> localAmount
* - `token.displayAmount` -> `tokenDisplayAmount`
* - `local.displayAmount` -> `localDisplayAmount`
*/
const processedAmounts = useMemo(() => {
if (amountType === 'token') {
const parsedTokenAmount = amountRaw === '' ? null : parseInputAmount(amountRaw)
const parsedTokenAmount = amount === '' ? null : parseInputAmount(amount)

const tokenToLocal = convertTokenToLocalAmount({
tokenAmount: parsedTokenAmount,
tokenInfo: props.token,
usdToLocalRate,
})

const convertedTokenToLocal =
tokenToLocal && tokenToLocal.gt(0) ? tokenToLocal.toFixed(2) : ''

return {
token: {
amount: amountRaw,
bignum: parsedTokenAmount,
displayAmount: getDisplayTokenAmount(parsedTokenAmount, props.token),
},
local: {
amount: convertedTokenToLocal,
bignum: tokenToLocal,
displayAmount: getDisplayLocalAmount(tokenToLocal, localCurrencySymbol),
},
Expand All @@ -160,7 +162,7 @@
/**
* At this point, we can be sure that we are processing local (fiat) input.
*/
const parsedLocalAmount = amountRaw === '' ? null : parseInputAmount(amountRaw)
const parsedLocalAmount = amount === '' ? null : parseInputAmount(amount)

const localToToken = convertLocalToTokenAmount({
localAmount: parsedLocalAmount,
Expand All @@ -177,66 +179,94 @@
: ''

const parsedTokenAmount = parseInputAmount(convertedLocalToToken, decimalSeparator)
const balanceInLocal = convertTokenToLocalAmount({
tokenAmount: props.token.balance,
tokenInfo: props.token,
usdToLocalRate,
})?.decimalPlaces(2)

const isMaxLocalAmount =
parsedLocalAmount && balanceInLocal && balanceInLocal.eq(parsedLocalAmount)
const tokenAmount = isMaxLocalAmount ? props.token.balance : parsedTokenAmount

return {
token: {
amount: convertedLocalToToken,
bignum: parsedTokenAmount,
displayAmount: getDisplayTokenAmount(parsedTokenAmount, props.token),
bignum: tokenAmount,
displayAmount: getDisplayTokenAmount(tokenAmount, props.token),
},
local: {
amount: parsedLocalAmount?.toFixed(2) ?? '',
bignum: parsedLocalAmount,
displayAmount: getDisplayLocalAmount(parsedLocalAmount, localCurrencySymbol),
},
}
}, [amountRaw, amountType, localCurrencySymbol])
}, [amount, amountType, localCurrencySymbol])

function handleToggleAmountType() {
setAmountType((prev) => (prev === 'local' ? 'token' : 'local'))
const newAmountType = amountType === 'local' ? 'token' : 'local'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an existing issue and i haven't been able to think of a better approach that doesn't introduce a bunch of issues, but setting state using the existing value of a state variable like this is unreliable because of the batched state updates 🙈 probably low risk for this use case, unless someone is toggling the amounts many times really quickly.

maybe this component would have been a good one for useReducer, since that'd facilitate keeping the state variables in sync. it might be something we want to try later

Copy link
Contributor Author

@sviderock sviderock Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kathaypacific considering that the state setting is indeed batched since React 18 and the whole scope of handleToggleAmountType will happen only once at the very end - it is exactly what I need. I need these two states to be updated at the same time (and only once) and batching ensures that.

And according to React docs:
React does not batch across multiple intentional events like clicks—each click is handled separately.

So even if user clicks multiple time - we will be sure that both states will always be in sync with one another as it will only execute everything in scope as a single update.

P.S. I do remember that they also whether had this stated at the react docs previously or it was just some Abramov's post but there was a statement that using state setter without callback is completely fine if the use-case is simple enough and it will benefit from batching (which I believe applies in this case).

setAmountType(newAmountType)
setAmount(
amountType === 'token' ? processedAmounts.local.amount || '' : processedAmounts.token.amount
newAmountType === 'local'
? processedAmounts.local.bignum?.toFixed(2) || ''
: processedAmounts.token.bignum?.decimalPlaces(6).toString() || ''
)
props.inputRef.current?.blur()
}

function handleAmountInputChange(val: string) {
let value = val.replaceAll(groupingSeparator, '')
let value = val.replaceAll(groupingSeparator, '').replaceAll(decimalSeparator, '.')
value = value.startsWith('.') ? `0${value}` : value

if (!value) {
setAmount('')
props.onHandleAmountInputChange?.('')
return
}

if (value.startsWith(decimalSeparator)) {
value = `0${value}`
}

// only allow numbers, one decimal separator and 2 decimals
const localAmountRegex = new RegExp(`^(\\d+([.])?\\d{0,2}|[.]\\d{0,2}|[.])$`)
// only allow numbers, one decimal separator and amount of decimals equal to token.decimals
const tokenAmountRegex = new RegExp(
`^(?:\\d+[${decimalSeparator}]?\\d{0,${props.token.decimals}}|[${decimalSeparator}]\\d{0,${props.token.decimals}}|[${decimalSeparator}])$`
)

// only allow numbers, one decimal separator and 2 decimals
const localAmountRegex = new RegExp(
`^(\\d+([${decimalSeparator}])?\\d{0,2}|[${decimalSeparator}]\\d{0,2}|[${decimalSeparator}])$`
`^(?:\\d+[.]?\\d{0,${props.token.decimals}}|[.]\\d{0,${props.token.decimals}}|[.])$`
)

if (
(amountType === 'token' && value.match(tokenAmountRegex)) ||
(amountType === 'local' && value.match(localAmountRegex))
) {
setAmount(value)
props.onHandleAmountInputChange?.(value)
return
}
}

function handlePercentage(percentage: number) {
if (percentage <= 0 || percentage > 1) return

const percentageAmount = props.token.balance.multipliedBy(percentage)
const newAmount =
amountType === 'token'
? percentageAmount.decimalPlaces(6).toString()
: roundLocalNumber(

Check warning on line 249 in src/components/TokenEnterAmount.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/TokenEnterAmount.tsx#L249

Added line #L249 was not covered by tests
convertTokenToLocalAmount({
tokenAmount: percentageAmount,
tokenInfo: props.token,
usdToLocalRate,
})
)

if (!newAmount) return

setAmount(newAmount)
}

return {
amount: amountRaw,
amount,
amountType,
processedAmounts,
setAmount,
handleToggleAmountType,
handleAmountInputChange,
handlePercentage,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
handlePercentage,
handleSelectPercentageAmount,

}
}

Expand Down Expand Up @@ -276,9 +306,14 @@
const [startPosition, setStartPosition] = useState<number | undefined>(0)
// this should never be null, just adding a default to make TS happy
const localCurrencySymbol = useSelector(getLocalCurrencySymbol) ?? LocalCurrencySymbol.USD
const { decimalSeparator } = getNumberFormatSettings()
const tokenPlaceholder = new BigNumber(0).toFormat(2)
const localPlaceholder = `${localCurrencySymbol}${new BigNumber(0).toFormat(2).replaceAll('.', decimalSeparator)}`

const placeholder = useMemo(() => {
const { decimalSeparator } = getNumberFormatSettings()
return {
token: new BigNumber(0).toFormat(2),
local: `${localCurrencySymbol}${new BigNumber(0).toFormat(2).replaceAll('.', decimalSeparator)}`,
}
}, [localCurrencySymbol])

const formattedInputValue = useMemo(() => {
const formattedNumber = formatNumber(inputValue)
Expand Down Expand Up @@ -358,7 +393,7 @@
}}
value={formattedInputValue}
placeholderTextColor={Colors.gray3}
placeholder={amountType === 'token' ? tokenPlaceholder : localPlaceholder}
placeholder={amountType === 'token' ? placeholder.token : placeholder.local}
keyboardType="decimal-pad"
// Work around for RN issue with Samsung keyboards
// https://github.com/facebook/react-native/issues/22005
Expand Down Expand Up @@ -406,12 +441,12 @@

<Text
numberOfLines={1}
style={[styles.secondaryAmountText, { maxWidth: '35%' }]}
style={[styles.secondaryAmountText, { flexShrink: 0, maxWidth: '45%' }]}
testID={`${testID}/ExchangeAmount`}
>
{amountType === 'token'
? `${APPROX_SYMBOL} ${localAmount ? localAmount : localPlaceholder}`
: `${APPROX_SYMBOL} ${tokenAmount ? tokenAmount : tokenPlaceholder}`}
? `${APPROX_SYMBOL} ${localAmount ? localAmount : placeholder.local}`
: `${APPROX_SYMBOL} ${tokenAmount ? tokenAmount : placeholder.token}`}
</Text>
</>
) : (
Expand Down
9 changes: 7 additions & 2 deletions src/components/TokenTotalLineItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import BigNumber from 'bignumber.js'
import * as React from 'react'
import 'react-native'
import { Provider } from 'react-redux'
import { APPROX_SYMBOL } from 'src/components/TokenEnterAmount'
import TokenTotalLineItem from 'src/components/TokenTotalLineItem'
import { LocalCurrencyCode } from 'src/localCurrency/consts'
import { LocalAmount, NetworkId } from 'src/transactions/types'
Expand Down Expand Up @@ -173,7 +174,9 @@ describe('TokenTotalLineItem', () => {
showLocalAmountForTotal: false,
newSendScreen: true,
})
expect(getElementText(getByTestId('TotalLineItem/Total'))).toEqual('~10.50 cUSD')
expect(getElementText(getByTestId('TotalLineItem/Total'))).toEqual(
`${APPROX_SYMBOL} 10.50 cUSD`
)
expect(getElementText(getByTestId('TotalLineItem/ExchangeRate'))).toEqual(
'tokenExchangeRateApprox, {"symbol":"cUSD"}R$1.50'
)
Expand All @@ -184,7 +187,9 @@ describe('TokenTotalLineItem', () => {
showLocalAmountForTotal: false,
newSendScreen: true,
})
expect(getElementText(getByTestId('TotalLineItem/Total'))).toEqual('~10.00 cUSD')
expect(getElementText(getByTestId('TotalLineItem/Total'))).toEqual(
`${APPROX_SYMBOL} 10.00 cUSD`
)
expect(getElementText(getByTestId('TotalLineItem/ExchangeRate'))).toEqual(
'tokenExchangeRateApprox, {"symbol":"cUSD"}R$1.50'
)
Expand Down
Loading
Loading