diff --git a/app/components/UI/ApproveTransactionReview/EditPermission/index.js b/app/components/UI/ApproveTransactionReview/EditPermission/index.tsx
similarity index 83%
rename from app/components/UI/ApproveTransactionReview/EditPermission/index.js
rename to app/components/UI/ApproveTransactionReview/EditPermission/index.tsx
index 72464018a73..c15c136e95a 100644
--- a/app/components/UI/ApproveTransactionReview/EditPermission/index.js
+++ b/app/components/UI/ApproveTransactionReview/EditPermission/index.tsx
@@ -1,18 +1,22 @@
-import React, { useCallback, useMemo, useState } from 'react';
-import PropTypes from 'prop-types';
-import { View, StyleSheet, TouchableOpacity, TextInput } from 'react-native';
+import React, { useCallback, useEffect, useState } from 'react';
+import {
+ View,
+ Text,
+ StyleSheet,
+ TouchableOpacity,
+ TextInput,
+} from 'react-native';
import { fontStyles } from '../../../../styles/common';
-import Text from '../../../Base/Text';
import StyledButton from '../../StyledButton';
import { strings } from '../../../../../locales/i18n';
+import { isNumber } from '../../../../util/number';
import ConnectHeader from '../../ConnectHeader';
import Device from '../../../../util/device';
import ErrorMessage from '../../../Views/SendFlow/ErrorMessage';
import { useAppThemeFromContext, mockTheme } from '../../../../util/theme';
import formatNumber from '../../../../util/formatNumber';
-import { INTEGER_OR_FLOAT_REGEX } from '../../../../util/number';
-const createStyles = (colors) =>
+const createStyles = (colors: any) =>
StyleSheet.create({
wrapper: {
paddingHorizontal: 24,
@@ -99,6 +103,20 @@ const createStyles = (colors) =>
},
});
+interface IEditPermissionProps {
+ host: string;
+ minimumSpendLimit: string;
+ spendLimitUnlimitedSelected: boolean;
+ tokenSymbol: string;
+ spendLimitCustomValue: string;
+ originalApproveAmount: string;
+ onSetApprovalAmount: () => void;
+ onSpendLimitCustomValueChange: (approvalCustomValue: string) => void;
+ onPressSpendLimitUnlimitedSelected: () => void;
+ onPressSpendLimitCustomSelected: () => void;
+ toggleEditPermission: () => void;
+}
+
function EditPermission({
host,
minimumSpendLimit,
@@ -111,21 +129,25 @@ function EditPermission({
onPressSpendLimitUnlimitedSelected,
onPressSpendLimitCustomSelected,
toggleEditPermission,
-}) {
+}: IEditPermissionProps) {
const [initialState] = useState({
spendLimitUnlimitedSelected,
spendLimitCustomValue,
});
+ const [disableBtn, setDisableBtn] = useState(false);
+ const [displayErrorMsg, setDisplayErrorMsg] = useState(false);
const { colors, themeAppearance } = useAppThemeFromContext() || mockTheme;
const styles = createStyles(colors);
- const displayErrorMessage = useMemo(
- () =>
- (!spendLimitUnlimitedSelected &&
- !INTEGER_OR_FLOAT_REGEX.test(spendLimitCustomValue)) ||
- Number(minimumSpendLimit) > spendLimitCustomValue,
- [spendLimitUnlimitedSelected, spendLimitCustomValue, minimumSpendLimit],
- );
+ useEffect(() => {
+ setDisplayErrorMsg(
+ Number(minimumSpendLimit) > Number(spendLimitCustomValue),
+ );
+ }, [minimumSpendLimit, spendLimitCustomValue, spendLimitUnlimitedSelected]);
+
+ useEffect(() => {
+ setDisableBtn(!isNumber(spendLimitCustomValue) || displayErrorMsg);
+ }, [spendLimitCustomValue, displayErrorMsg]);
const onSetApprovalAmount = useCallback(() => {
if (!spendLimitUnlimitedSelected && !spendLimitCustomValue) {
@@ -141,13 +163,12 @@ function EditPermission({
]);
const onBackPress = useCallback(() => {
- const { spendLimitUnlimitedSelected, spendLimitCustomValue } = initialState;
- if (spendLimitUnlimitedSelected) {
+ if (initialState.spendLimitUnlimitedSelected) {
onPressSpendLimitUnlimitedSelected();
} else {
onPressSpendLimitCustomSelected();
}
- onSpendLimitCustomValueChange(spendLimitCustomValue);
+ onSpendLimitCustomValueChange(initialState.spendLimitCustomValue);
toggleEditPermission();
}, [
initialState,
@@ -249,7 +270,7 @@ function EditPermission({
returnKeyType={'done'}
keyboardAppearance={themeAppearance}
/>
- {displayErrorMessage && (
+ {displayErrorMsg && (
@@ -275,18 +296,4 @@ function EditPermission({
);
}
-EditPermission.propTypes = {
- host: PropTypes.string.isRequired,
- minimumSpendLimit: PropTypes.string,
- spendLimitUnlimitedSelected: PropTypes.bool.isRequired,
- tokenSymbol: PropTypes.string.isRequired,
- spendLimitCustomValue: PropTypes.string.isRequired,
- originalApproveAmount: PropTypes.string.isRequired,
- onPressSpendLimitUnlimitedSelected: PropTypes.func.isRequired,
- onPressSpendLimitCustomSelected: PropTypes.func.isRequired,
- onSpendLimitCustomValueChange: PropTypes.func.isRequired,
- onSetApprovalAmount: PropTypes.func.isRequired,
- toggleEditPermission: PropTypes.func.isRequired,
-};
-
export default EditPermission;
diff --git a/app/components/UI/Swaps/components/ApprovalTransactionEditionModal.js b/app/components/UI/Swaps/components/ApprovalTransactionEditionModal.js
index a15c984ce90..0012a58a54e 100644
--- a/app/components/UI/Swaps/components/ApprovalTransactionEditionModal.js
+++ b/app/components/UI/Swaps/components/ApprovalTransactionEditionModal.js
@@ -37,6 +37,8 @@ function ApprovalTransactionEditionModal({
chainId,
}) {
/* Approval transaction if any */
+ const [customApprovalTransaction, setCustomApprovalTransaction] =
+ useState(approvalTransaction);
const [approvalTransactionAmount, setApprovalTransactionAmount] =
useState('');
const [approvalCustomValue, setApprovalCustomValue] =
@@ -49,10 +51,12 @@ function ApprovalTransactionEditionModal({
(approvalCustomValue) => setApprovalCustomValue(approvalCustomValue),
[],
);
+
const onPressSpendLimitUnlimitedSelected = useCallback(
() => setSpendLimitUnlimitedSelected(true),
[],
);
+
const onPressSpendLimitCustomSelected = useCallback(
() => setSpendLimitUnlimitedSelected(false),
[],
@@ -66,8 +70,9 @@ function ApprovalTransactionEditionModal({
: approvalCustomValue,
sourceToken.decimals,
swapsUtils.getSwapsContractAddress(chainId),
- approvalTransaction,
+ customApprovalTransaction,
);
+ setCustomApprovalTransaction(newApprovalTransaction);
setApprovalTransaction(newApprovalTransaction);
onCancelEditQuoteTransactions();
} catch (err) {
@@ -78,27 +83,32 @@ function ApprovalTransactionEditionModal({
spendLimitUnlimitedSelected,
approvalTransactionAmount,
approvalCustomValue,
- approvalTransaction,
+ customApprovalTransaction,
sourceToken,
chainId,
onCancelEditQuoteTransactions,
]);
useEffect(() => {
- setApprovalTransaction(originalApprovalTransaction);
- if (originalApprovalTransaction) {
+ const newApprovalTx = spendLimitUnlimitedSelected
+ ? originalApprovalTransaction
+ : customApprovalTransaction;
+ setApprovalTransaction(newApprovalTx);
+ if (newApprovalTx) {
const approvalTransactionAmount = decodeApproveData(
- originalApprovalTransaction.data,
+ newApprovalTx.data,
).encodedAmount;
const amountDec = hexToBN(approvalTransactionAmount).toString(10);
setApprovalTransactionAmount(
fromTokenMinimalUnitString(amountDec, sourceToken.decimals),
);
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [
originalApprovalTransaction,
- sourceToken.decimals,
setApprovalTransaction,
+ spendLimitUnlimitedSelected,
+ customApprovalTransaction,
]);
return (
@@ -120,7 +130,7 @@ function ApprovalTransactionEditionModal({
- {Boolean(approvalTransaction) && (
+ {Boolean(customApprovalTransaction) && (
{
@@ -489,3 +490,28 @@ describe('Number utils :: fastSplit', () => {
expect(fastSplit('test string', ' ')).toEqual('test');
});
});
+
+describe('Number utils :: isNumber', () => {
+ it('should be a valid number ', () => {
+ expect(isNumber('1650.7')).toBe(true);
+ expect(isNumber('1000')).toBe(true);
+ expect(isNumber('0.0001')).toBe(true);
+ expect(isNumber('0001')).toBe(true);
+ expect(isNumber('1')).toBe(true);
+ });
+
+ it('should not be a valid number ', () => {
+ expect(isNumber('..7')).toBe(false);
+ expect(isNumber('1..1')).toBe(false);
+ expect(isNumber('0..')).toBe(false);
+ expect(isNumber('a.0001')).toBe(false);
+ expect(isNumber('00a01')).toBe(false);
+ expect(isNumber('1,.')).toBe(false);
+ expect(isNumber('1,')).toBe(false);
+ expect(isNumber('.')).toBe(false);
+ expect(isNumber('a¡1')).toBe(false);
+ expect(isNumber('.01')).toBe(false);
+ expect(isNumber(undefined)).toBe(false);
+ expect(isNumber(null)).toBe(false);
+ });
+});