mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 01:47:00 +01:00
Allow sending up to 15 decimals on the send screen (#12707)
This commit is contained in:
parent
8f2144fdb0
commit
8597cd1401
5
shared/constants/decimal.js
Normal file
5
shared/constants/decimal.js
Normal file
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* MAX_DECIMAL represensts the maximum number of decimal values allow for the input,
|
||||
* the limitation in javascript <input/> retstricts us to keep it as 15 and below.
|
||||
*/
|
||||
export const MAX_DECIMAL = 15;
|
@ -14,6 +14,7 @@ import {
|
||||
getNativeCurrency,
|
||||
} from '../../../ducks/metamask/metamask';
|
||||
import { getCurrentCurrency, getShouldShowFiat } from '../../../selectors';
|
||||
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
|
||||
|
||||
/**
|
||||
* Component that allows user to enter currency values as a number, and props receive a converted
|
||||
@ -25,12 +26,14 @@ import { getCurrentCurrency, getShouldShowFiat } from '../../../selectors';
|
||||
* @param options0.featureSecondary
|
||||
* @param options0.onChange
|
||||
* @param options0.onPreferenceToggle
|
||||
* @param options0.primaryNumberOfDecimals
|
||||
*/
|
||||
export default function CurrencyInput({
|
||||
hexValue,
|
||||
featureSecondary,
|
||||
onChange,
|
||||
onPreferenceToggle,
|
||||
primaryNumberOfDecimals = 8,
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
|
||||
@ -64,7 +67,10 @@ export default function CurrencyInput({
|
||||
: getValueFromWeiHex({
|
||||
value: hexValue,
|
||||
toCurrency: ETH,
|
||||
numberOfDecimals: 8,
|
||||
numberOfDecimals:
|
||||
primaryNumberOfDecimals <= MAX_DECIMAL
|
||||
? primaryNumberOfDecimals
|
||||
: MAX_DECIMAL,
|
||||
});
|
||||
|
||||
return Number(decimalValueString) || 0;
|
||||
@ -127,7 +133,10 @@ export default function CurrencyInput({
|
||||
if (shouldUseFiat()) {
|
||||
// Display ETH
|
||||
currency = preferredCurrency || ETH;
|
||||
numberOfDecimals = 8;
|
||||
numberOfDecimals =
|
||||
primaryNumberOfDecimals <= MAX_DECIMAL
|
||||
? primaryNumberOfDecimals
|
||||
: MAX_DECIMAL;
|
||||
} else {
|
||||
// Display Fiat
|
||||
currency = secondaryCurrency;
|
||||
@ -143,7 +152,6 @@ export default function CurrencyInput({
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<UnitInput
|
||||
{...{
|
||||
@ -173,4 +181,5 @@ CurrencyInput.propTypes = {
|
||||
featureSecondary: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
onPreferenceToggle: PropTypes.func,
|
||||
primaryNumberOfDecimals: PropTypes.number,
|
||||
};
|
||||
|
@ -6,6 +6,7 @@ import { Provider } from 'react-redux';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import UnitInput from '../../ui/unit-input';
|
||||
import CurrencyDisplay from '../../ui/currency-display';
|
||||
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
|
||||
import CurrencyInput from './currency-input';
|
||||
|
||||
describe('CurrencyInput Component', () => {
|
||||
@ -145,7 +146,11 @@ describe('CurrencyInput Component', () => {
|
||||
|
||||
const wrapper = mount(
|
||||
<Provider store={store}>
|
||||
<CurrencyInput hexValue="f602f2234d0ea" featureSecondary />
|
||||
<CurrencyInput
|
||||
hexValue="f602f2234d0ea"
|
||||
featureSecondary
|
||||
primaryNumberOfDecimals={MAX_DECIMAL}
|
||||
/>
|
||||
</Provider>,
|
||||
{
|
||||
context: { t: (str) => `${str}_t` },
|
||||
@ -157,7 +162,7 @@ describe('CurrencyInput Component', () => {
|
||||
expect(wrapper.find('.unit-input__suffix')).toHaveLength(1);
|
||||
expect(wrapper.find('.unit-input__suffix').text()).toStrictEqual('ETH');
|
||||
expect(wrapper.find('.unit-input__input').props().value).toStrictEqual(
|
||||
0.00432788,
|
||||
0.004327880204276,
|
||||
);
|
||||
expect(
|
||||
wrapper.find('.currency-input__conversion-component').text(),
|
||||
@ -193,7 +198,11 @@ describe('CurrencyInput Component', () => {
|
||||
const store = configureMockStore()(mockStore);
|
||||
const wrapper = mount(
|
||||
<Provider store={store}>
|
||||
<CurrencyInput onChange={handleChangeSpy} hexValue="f602f2234d0ea" />
|
||||
<CurrencyInput
|
||||
onChange={handleChangeSpy}
|
||||
hexValue="f602f2234d0ea"
|
||||
primaryNumberOfDecimals={MAX_DECIMAL}
|
||||
/>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
@ -202,7 +211,7 @@ describe('CurrencyInput Component', () => {
|
||||
expect(handleBlurSpy.callCount).toStrictEqual(0);
|
||||
|
||||
const input = wrapper.find('input');
|
||||
expect(input.props().value).toStrictEqual(0.00432788);
|
||||
expect(input.props().value).toStrictEqual(0.004327880204276);
|
||||
|
||||
input.simulate('change', { target: { value: 1 } });
|
||||
expect(handleChangeSpy.callCount).toStrictEqual(2);
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
|
||||
import { ETH } from '../../../helpers/constants/common';
|
||||
import { addHexPrefix } from '../../../../app/scripts/lib/util';
|
||||
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
|
||||
|
||||
/**
|
||||
* Component that allows user to enter token values as a number, and props receive a converted
|
||||
@ -34,6 +35,7 @@ export default class TokenInput extends PureComponent {
|
||||
symbol: PropTypes.string,
|
||||
}).isRequired,
|
||||
tokenExchangeRates: PropTypes.object,
|
||||
primaryNumberOfDecimals: PropTypes.number,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
@ -108,6 +110,7 @@ export default class TokenInput extends PureComponent {
|
||||
currentCurrency,
|
||||
hideConversion,
|
||||
token,
|
||||
primaryNumberOfDecimals = 8,
|
||||
} = this.props;
|
||||
const { decimalValue } = this.state;
|
||||
|
||||
@ -129,7 +132,10 @@ export default class TokenInput extends PureComponent {
|
||||
} else {
|
||||
// Display ETH
|
||||
currency = ETH;
|
||||
numberOfDecimals = 6;
|
||||
numberOfDecimals =
|
||||
primaryNumberOfDecimals <= MAX_DECIMAL
|
||||
? primaryNumberOfDecimals
|
||||
: MAX_DECIMAL;
|
||||
}
|
||||
|
||||
const decimalEthValue = decimalValue * tokenExchangeRate || 0;
|
||||
|
@ -1,6 +1,9 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
|
||||
|
||||
const DECIMAL_REGEX = /\.(\d*)/u;
|
||||
|
||||
function removeLeadingZeroes(str) {
|
||||
return str.replace(/^0*(?=\d)/u, '');
|
||||
@ -62,6 +65,11 @@ export default class UnitInput extends PureComponent {
|
||||
|
||||
handleChange = (event) => {
|
||||
const { value: userInput } = event.target;
|
||||
const match = DECIMAL_REGEX.exec(userInput);
|
||||
if (match?.[1]?.length > MAX_DECIMAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
let value = userInput;
|
||||
|
||||
if (userInput.length && userInput.length > 1) {
|
||||
|
@ -4,6 +4,7 @@ import SendRowWrapper from '../send-row-wrapper';
|
||||
import UserPreferencedCurrencyInput from '../../../../components/app/user-preferenced-currency-input';
|
||||
import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input';
|
||||
import { ASSET_TYPES } from '../../../../ducks/send';
|
||||
import { MAX_DECIMAL } from '../../../../../shared/constants/decimal';
|
||||
import AmountMaxButton from './amount-max-button';
|
||||
|
||||
export default class SendAmountRow extends Component {
|
||||
@ -31,12 +32,14 @@ export default class SendAmountRow extends Component {
|
||||
onChange={this.handleChange}
|
||||
token={asset.details}
|
||||
value={amount}
|
||||
primaryNumberOfDecimals={asset.decimals}
|
||||
/>
|
||||
) : (
|
||||
<UserPreferencedCurrencyInput
|
||||
error={inError}
|
||||
onChange={this.handleChange}
|
||||
hexValue={amount}
|
||||
primaryNumberOfDecimals={MAX_DECIMAL}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user