1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Changes in gas loading animation in EIP-1559 V2 (#13016)

This commit is contained in:
Jyoti Puri 2021-12-10 06:20:38 +05:30 committed by GitHub
parent 163d472fdf
commit 889e49a4a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 121 additions and 37 deletions

View File

@ -820,15 +820,18 @@
"editGasLow": { "editGasLow": {
"message": "Low" "message": "Low"
}, },
"editGasMaxBaseFeeGWEIImbalance": {
"message": "Max base fee cannot be lower than priority fee"
},
"editGasMaxBaseFeeHigh": { "editGasMaxBaseFeeHigh": {
"message": "Max base fee is higher than necessary" "message": "Max base fee is higher than necessary"
}, },
"editGasMaxBaseFeeImbalance": {
"message": "Max base fee cannot be lower than priority fee"
},
"editGasMaxBaseFeeLow": { "editGasMaxBaseFeeLow": {
"message": "Max base fee is low for current network conditions" "message": "Max base fee is low for current network conditions"
}, },
"editGasMaxBaseFeeMultiplierImbalance": {
"message": "Multiplier is low relative to Priority fee"
},
"editGasMaxFeeHigh": { "editGasMaxFeeHigh": {
"message": "Max fee is higher than necessary" "message": "Max fee is higher than necessary"
}, },

View File

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import Box from '../../../ui/box'; import Box from '../../../ui/box';
import I18nValue from '../../../ui/i18n-value'; import I18nValue from '../../../ui/i18n-value';
import LoadingHeartBeat from '../../../ui/loading-heartbeat';
const AdvancedGasFeeInputSubtext = ({ latest, historical }) => { const AdvancedGasFeeInputSubtext = ({ latest, historical }) => {
return ( return (
@ -11,14 +12,20 @@ const AdvancedGasFeeInputSubtext = ({ latest, historical }) => {
<span className="advanced-gas-fee-input-subtext__label"> <span className="advanced-gas-fee-input-subtext__label">
<I18nValue messageKey="currentTitle" /> <I18nValue messageKey="currentTitle" />
</span> </span>
<span>{latest}</span> <span className="advanced-gas-fee-input-subtext__value">
<LoadingHeartBeat />
{latest}
</span>
<img src="./images/high-arrow.svg" alt="" /> <img src="./images/high-arrow.svg" alt="" />
</Box> </Box>
<Box> <Box>
<span className="advanced-gas-fee-input-subtext__label"> <span className="advanced-gas-fee-input-subtext__label">
<I18nValue messageKey="twelveHrTitle" /> <I18nValue messageKey="twelveHrTitle" />
</span> </span>
<span>{historical}</span> <span className="advanced-gas-fee-input-subtext__value">
<LoadingHeartBeat />
{historical}
</span>
</Box> </Box>
</Box> </Box>
); );

View File

@ -1,8 +1,48 @@
import React from 'react'; import React from 'react';
import { render, screen } from '@testing-library/react'; import { screen } from '@testing-library/react';
import { GAS_ESTIMATE_TYPES } from '../../../../../shared/constants/gas';
import mockEstimates from '../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
import configureStore from '../../../../store/store';
import AdvancedGasFeeInputSubtext from './advanced-gas-fee-input-subtext'; import AdvancedGasFeeInputSubtext from './advanced-gas-fee-input-subtext';
jest.mock('../../../../store/actions', () => ({
disconnectGasFeeEstimatePoller: jest.fn(),
getGasFeeEstimatesAndStartPolling: jest
.fn()
.mockImplementation(() => Promise.resolve()),
addPollingTokenToAppState: jest.fn(),
removePollingTokenFromAppState: jest.fn(),
}));
const render = () => {
const store = configureStore({
metamask: {
...mockState.metamask,
accounts: {
[mockState.metamask.selectedAddress]: {
address: mockState.metamask.selectedAddress,
balance: '0x1F4',
},
},
advancedGasFee: { priorityFee: 100 },
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GAS_ESTIMATE_TYPES.FEE_MARKET].gasFeeEstimates,
},
});
return renderWithProvider(
<AdvancedGasFeeInputSubtext
latest="Latest Value"
historical="Historical value"
/>,
store,
);
};
describe('AdvancedGasFeeInputSubtext', () => { describe('AdvancedGasFeeInputSubtext', () => {
it('should renders latest and historical values passed', () => { it('should renders latest and historical values passed', () => {
render( render(

View File

@ -10,6 +10,10 @@
margin-right: 4px; margin-right: 4px;
} }
&__value {
position: relative;
}
img { img {
height: 16px; height: 16px;
margin-right: 8px; margin-right: 8px;

View File

@ -41,9 +41,16 @@ const multiplyCurrencyValues = (baseFee, value, numberOfDecimals) =>
multiplierBase: 10, multiplierBase: 10,
}).toNumber(); }).toNumber();
const validateBaseFee = (value, gasFeeEstimates, maxPriorityFeePerGas) => { const validateBaseFee = (
editingInGwei,
value,
gasFeeEstimates,
maxPriorityFeePerGas,
) => {
if (bnGreaterThan(maxPriorityFeePerGas, value)) { if (bnGreaterThan(maxPriorityFeePerGas, value)) {
return 'editGasMaxBaseFeeImbalance'; return editingInGwei
? 'editGasMaxBaseFeeGWEIImbalance'
: 'editGasMaxBaseFeeMultiplierImbalance';
} }
if ( if (
gasFeeEstimates?.low && gasFeeEstimates?.low &&
@ -145,14 +152,20 @@ const BaseFeeInput = () => {
useEffect(() => { useEffect(() => {
setMaxFeePerGas(maxBaseFeeGWEI); setMaxFeePerGas(maxBaseFeeGWEI);
const error = validateBaseFee( const error = validateBaseFee(
editingInGwei,
maxBaseFeeGWEI, maxBaseFeeGWEI,
gasFeeEstimates, gasFeeEstimates,
maxPriorityFeePerGas, maxPriorityFeePerGas,
); );
setBaseFeeError(error); setBaseFeeError(error);
setErrorValue('maxFeePerGas', error === 'editGasMaxBaseFeeImbalance'); setErrorValue(
'maxFeePerGas',
error === 'editGasMaxBaseFeeGWEIImbalance' ||
error === 'editGasMaxBaseFeeMultiplierImbalance',
);
}, [ }, [
editingInGwei,
gasFeeEstimates, gasFeeEstimates,
maxBaseFeeGWEI, maxBaseFeeGWEI,
maxPriorityFeePerGas, maxPriorityFeePerGas,

View File

@ -91,7 +91,9 @@
margin-top: auto; margin-top: auto;
} }
&__currency-container { &__currency-container,
&__total-amount,
&__total-value {
position: relative; position: relative;
} }
} }

View File

@ -5,7 +5,6 @@ import { useI18nContext } from '../../../hooks/useI18nContext';
import { useTransactionModalContext } from '../../../contexts/transaction-modal'; import { useTransactionModalContext } from '../../../contexts/transaction-modal';
import ErrorMessage from '../../ui/error-message'; import ErrorMessage from '../../ui/error-message';
import I18nValue from '../../ui/i18n-value'; import I18nValue from '../../ui/i18n-value';
import LoadingHeartBeat from '../../ui/loading-heartbeat';
import Popover from '../../ui/popover'; import Popover from '../../ui/popover';
import Typography from '../../ui/typography/typography'; import Typography from '../../ui/typography/typography';
@ -29,7 +28,6 @@ const EditGasFeePopover = () => {
className="edit-gas-fee-popover" className="edit-gas-fee-popover"
> >
<> <>
{process.env.IN_TEST ? null : <LoadingHeartBeat />}
<div className="edit-gas-fee-popover__wrapper"> <div className="edit-gas-fee-popover__wrapper">
<div className="edit-gas-fee-popover__content"> <div className="edit-gas-fee-popover__content">
{balanceError && ( {balanceError && (

View File

@ -12,6 +12,7 @@ import {
decimalToHex, decimalToHex,
hexWEIToDecGWEI, hexWEIToDecGWEI,
} from '../../../../helpers/utils/conversions.util'; } from '../../../../helpers/utils/conversions.util';
import LoadingHeartBeat from '../../../ui/loading-heartbeat';
import { getAdvancedGasFeeValues } from '../../../../selectors'; import { getAdvancedGasFeeValues } from '../../../../selectors';
import { toHumanReadableTime } from '../../../../helpers/utils/util'; import { toHumanReadableTime } from '../../../../helpers/utils/util';
import { useGasFeeContext } from '../../../../contexts/gasFee'; import { useGasFeeContext } from '../../../../contexts/gasFee';
@ -138,11 +139,14 @@ const EditGasItem = ({ priorityLevel }) => {
className={`edit-gas-item__fee-estimate edit-gas-item__fee-estimate-${priorityLevel}`} className={`edit-gas-item__fee-estimate edit-gas-item__fee-estimate-${priorityLevel}`}
> >
{hexMaximumTransactionFee ? ( {hexMaximumTransactionFee ? (
<div className="edit-gas-item__maxfee">
<LoadingHeartBeat />
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay
key="editGasSubTextFeeAmount" key="editGasSubTextFeeAmount"
type={PRIMARY} type={PRIMARY}
value={hexMaximumTransactionFee} value={hexMaximumTransactionFee}
/> />
</div>
) : ( ) : (
'--' '--'
)} )}

View File

@ -39,6 +39,10 @@
} }
} }
&__maxfee {
position: relative;
}
&__time-estimate { &__time-estimate {
display: inline-block; display: inline-block;
text-align: left; text-align: left;

View File

@ -11,6 +11,8 @@ export default function LoadingHeartBeat() {
useShouldAnimateGasEstimations(); useShouldAnimateGasEstimations();
const active = useSelector(getGasLoadingAnimationIsShowing); const active = useSelector(getGasLoadingAnimationIsShowing);
if (process.env.IN_TEST) return null;
return ( return (
<div <div
className={classNames('loading-heartbeat', { className={classNames('loading-heartbeat', {

View File

@ -365,12 +365,15 @@ export default class ConfirmTransactionBase extends Component {
secondaryTotalTextOverride === undefined secondaryTotalTextOverride === undefined
) { ) {
return ( return (
<div className="confirm-page-container-content__total-value">
<LoadingHeartBeat />
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay
type={PRIMARY} type={PRIMARY}
key="total-detail-value" key="total-detail-value"
value={hexTransactionTotal} value={hexTransactionTotal}
hideLabel={!useNativeCurrencyAsPrimaryCurrency} hideLabel={!useNativeCurrencyAsPrimaryCurrency}
/> />
</div>
); );
} }
return useNativeCurrencyAsPrimaryCurrency return useNativeCurrencyAsPrimaryCurrency
@ -384,12 +387,15 @@ export default class ConfirmTransactionBase extends Component {
secondaryTotalTextOverride === undefined secondaryTotalTextOverride === undefined
) { ) {
return ( return (
<div className="confirm-page-container-content__total-value">
<LoadingHeartBeat />
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay
type={SECONDARY} type={SECONDARY}
key="total-detail-text" key="total-detail-text"
value={hexTransactionTotal} value={hexTransactionTotal}
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)} hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
/> />
</div>
); );
} }
return useNativeCurrencyAsPrimaryCurrency return useNativeCurrencyAsPrimaryCurrency
@ -612,12 +618,13 @@ export default class ConfirmTransactionBase extends Component {
detailTotal={renderTotalDetailTotal()} detailTotal={renderTotalDetailTotal()}
subTitle={t('transactionDetailGasTotalSubtitle')} subTitle={t('transactionDetailGasTotalSubtitle')}
subText={ subText={
<> <div className="confirm-page-container-content__total-amount">
<LoadingHeartBeat />
<strong key="editGasSubTextAmountLabel"> <strong key="editGasSubTextAmountLabel">
{t('editGasSubTextAmountLabel')} {t('editGasSubTextAmountLabel')}
</strong> </strong>
{renderTotalMaxAmount()} {renderTotalMaxAmount()}
</> </div>
} }
/> />
), ),

View File

@ -17,8 +17,6 @@ import TransactionDetailItem from '../../../components/app/transaction-detail-it
import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'; import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display';
import { useGasFeeContext } from '../../../contexts/gasFee'; import { useGasFeeContext } from '../../../contexts/gasFee';
const HeartBeat = () => (process.env.IN_TEST ? null : <LoadingHeartBeat />);
const GasDetailsItem = ({ const GasDetailsItem = ({
hexMaximumTransactionFee, hexMaximumTransactionFee,
hexMinimumTransactionFee, hexMinimumTransactionFee,
@ -73,7 +71,7 @@ const GasDetailsItem = ({
detailTitleColor={COLORS.BLACK} detailTitleColor={COLORS.BLACK}
detailText={ detailText={
<div className="gas-details-item__currency-container"> <div className="gas-details-item__currency-container">
<HeartBeat /> <LoadingHeartBeat />
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay
type={SECONDARY} type={SECONDARY}
value={hexMinimumTransactionFee} value={hexMinimumTransactionFee}
@ -83,7 +81,7 @@ const GasDetailsItem = ({
} }
detailTotal={ detailTotal={
<div className="gas-details-item__currency-container"> <div className="gas-details-item__currency-container">
<HeartBeat /> <LoadingHeartBeat />
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay
type={PRIMARY} type={PRIMARY}
value={hexMinimumTransactionFee} value={hexMinimumTransactionFee}
@ -100,6 +98,7 @@ const GasDetailsItem = ({
'gas-details-item__gas-fee-warning': estimateUsed === 'high', 'gas-details-item__gas-fee-warning': estimateUsed === 'high',
})} })}
> >
<LoadingHeartBeat />
<Box marginRight={1}> <Box marginRight={1}>
<strong> <strong>
{estimateUsed === 'high' && '⚠ '} {estimateUsed === 'high' && '⚠ '}
@ -110,7 +109,7 @@ const GasDetailsItem = ({
key="editGasSubTextFeeValue" key="editGasSubTextFeeValue"
className="gas-details-item__currency-container" className="gas-details-item__currency-container"
> >
<HeartBeat /> <LoadingHeartBeat />
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay
key="editGasSubTextFeeAmount" key="editGasSubTextFeeAmount"
type={PRIMARY} type={PRIMARY}

View File

@ -11,7 +11,8 @@
color: $secondary-1; color: $secondary-1;
} }
&__currency-container { &__currency-container,
&__gasfee-label {
position: relative; position: relative;
} }
} }