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

[WALL] [Fix] Rostislav / WALL-3096 / Fix amounts not fitting in ATM inputs on mobile #12377

Merged
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useCallback, useEffect } from 'react';
import React, { useCallback, useEffect, useMemo } from 'react';
import { useFormikContext } from 'formik';
import { useDebounce } from 'usehooks-ts';
import { ATMAmountInput, Timer } from '../../../../../../components';
import useInputDecimalFormatter from '../../../../../../hooks/useInputDecimalFormatter';
import { useTransfer } from '../../provider';
import type { TInitialTransferFormValues } from '../../types';
import './TransferFormAmountInput.scss';
Expand All @@ -10,13 +11,14 @@ type TProps = {
fieldName: 'fromAmount' | 'toAmount';
};

const MAX_DIGITS = 14;
const MAX_DIGITS = 12;
const USD_MAX_POSSIBLE_TRANSFER_AMOUNT = 100_000;
nijil-deriv marked this conversation as resolved.
Show resolved Hide resolved

const TransferFormAmountInput: React.FC<TProps> = ({ fieldName }) => {
const { setFieldValue, setValues, values } = useFormikContext<TInitialTransferFormValues>();
const { fromAccount, fromAmount, toAccount, toAmount } = values;

const { activeWalletExchangeRates, refetchAccountLimits, refetchExchangeRates } = useTransfer();
const { USDExchangeRates, activeWalletExchangeRates, refetchAccountLimits, refetchExchangeRates } = useTransfer();

const refetchExchangeRatesAndLimits = useCallback(() => {
refetchAccountLimits();
Expand All @@ -42,6 +44,15 @@ const TransferFormAmountInput: React.FC<TProps> = ({ fieldName }) => {
? fromAccount?.currencyConfig?.fractional_digits
: toAccount?.currencyConfig?.fractional_digits;

const convertedMaxPossibleAmount = useMemo(
() => USD_MAX_POSSIBLE_TRANSFER_AMOUNT * (USDExchangeRates?.rates?.[currency ?? 'USD'] ?? 1),
[USDExchangeRates?.rates, currency]
);
const { value: formattedConvertedMaxPossibleAmount } = useInputDecimalFormatter(convertedMaxPossibleAmount, {
fractionDigits,
});
const maxDigits = formattedConvertedMaxPossibleAmount.match(/\d/g)?.length ?? MAX_DIGITS;
nijil-deriv marked this conversation as resolved.
Show resolved Hide resolved

const amountConverterHandler = useCallback(
(value: number) => {
if (!toAccount?.currency || !activeWalletExchangeRates?.rates || !isAmountFieldActive) return;
Expand Down Expand Up @@ -119,7 +130,7 @@ const TransferFormAmountInput: React.FC<TProps> = ({ fieldName }) => {
disabled={isAmountInputDisabled}
fractionDigits={fractionDigits}
label={amountLabel}
maxDigits={MAX_DIGITS}
maxDigits={maxDigits}
onBlur={() => setFieldValue('activeAmountFieldName', undefined)}
onChange={onChangeHandler}
onFocus={() => setFieldValue('activeAmountFieldName', fieldName)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('useInputDecimalFormatter', () => {
result.current.onChange({ target: { value: '123' } });
});

expect(result.current.value).toBe('123');
expect(result.current.value).toBe('123.00');
});

it('should handle fractional digits and sign options correctly', () => {
Expand All @@ -34,10 +34,10 @@ describe('useInputDecimalFormatter', () => {
expect(result.current.value).toBe('');
});

it('should return empty string when an user clear the unput', () => {
it('should return empty string when the user clears the input', () => {
const { result } = renderHook(() => useInputDecimalFormatter(10));

expect(result.current.value).toBe('10');
expect(result.current.value).toBe('10.00');

act(() => {
result.current.onChange({ target: { value: '' } });
Expand All @@ -61,16 +61,16 @@ describe('useInputDecimalFormatter', () => {
it('should return value with sign after adding sign for integer number', () => {
const { result } = renderHook(() => useInputDecimalFormatter(1, { withSign: true }));

expect(result.current.value).toBe('1');
expect(result.current.value).toBe('1.00');

act(() => {
result.current.onChange({ target: { value: '-1' } });
result.current.onChange({ target: { value: '-1.00' } });
});

expect(result.current.value).toBe('-1');
expect(result.current.value).toBe('-1.00');
});

it('should return 0 if an user type 0', () => {
it('should return 0 if the user types 0', () => {
const { result } = renderHook(() => useInputDecimalFormatter());

expect(result.current.value).toBe('');
Expand All @@ -82,27 +82,27 @@ describe('useInputDecimalFormatter', () => {
expect(result.current.value).toBe('0');
});

it('should return previous value if an user type char', () => {
it('should return previous value if the user types non-digit characters', () => {
const { result } = renderHook(() => useInputDecimalFormatter(10));

expect(result.current.value).toBe('10');
expect(result.current.value).toBe('10.00');

act(() => {
result.current.onChange({ target: { value: 'test' } });
});

expect(result.current.value).toBe('10');
expect(result.current.value).toBe('10.00');
});

it('should return previous value if an user type integer part like this pattern 0*', () => {
it('should return previous value if the user types integer part matching this pattern: 0*', () => {
const { result } = renderHook(() => useInputDecimalFormatter(10));

expect(result.current.value).toBe('10');
expect(result.current.value).toBe('10.00');

act(() => {
result.current.onChange({ target: { value: '03' } });
});

expect(result.current.value).toBe('10');
expect(result.current.value).toBe('10.00');
});
});
2 changes: 1 addition & 1 deletion packages/wallets/src/hooks/useInputATMFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const useInputATMFormatter = (inputRef: React.RefObject<HTMLInputElement>, initi
setCaret(newCaretPosition);
setCaretNeedsRepositioning(true);

if (maxDigits && input.value.replace(separatorRegex, '').length > maxDigits) return;
if (maxDigits && input.value.replace(separatorRegex, '').replace(/^0+/, '').length > maxDigits) return;

const hasNoChangeInDigits =
input.value.length + 1 === prevFormattedValue.length &&
Expand Down
4 changes: 2 additions & 2 deletions packages/wallets/src/hooks/useInputDecimalFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ const useInputDecimalFormatter = (initial?: number, options?: TOptions) => {

// The field have a decimal point and decimal places are already as allowed fraction
// digits, So we remove the extra decimal digits from the right and return the new value.
if (hasRight && right.length > fractionDigits) {
const newRight = right.substring(0, fractionDigits);
if (fractionDigits) {
const newRight = right ? right.substring(0, fractionDigits) : '0'.repeat(fractionDigits);

return `${left}.${newRight}`;
}
Expand Down