mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Adding tooltips in edit gas fee network status section (#12916)
This commit is contained in:
parent
2dd8689d8a
commit
a6bb503e52
@ -320,6 +320,9 @@
|
||||
"balanceOutdated": {
|
||||
"message": "Balance may be outdated"
|
||||
},
|
||||
"baseFee": {
|
||||
"message": "Base fee"
|
||||
},
|
||||
"basic": {
|
||||
"message": "Basic"
|
||||
},
|
||||
@ -1276,6 +1279,9 @@
|
||||
"message": "Use $1 to cover surges in network traffic due to things like popular NFT drops.",
|
||||
"description": "$1 is key 'high' (text: 'Aggressive') separated here so that it can be passed in with bold fontweight"
|
||||
},
|
||||
"highLowercase": {
|
||||
"message": "high"
|
||||
},
|
||||
"history": {
|
||||
"message": "History"
|
||||
},
|
||||
@ -1535,6 +1541,9 @@
|
||||
"message": "Use $1 to wait for a cheaper price. Time estimates are much less accurate as prices are somewhat unpredicible.",
|
||||
"description": "$1 is key 'low' separated here so that it can be passed in with bold fontweight"
|
||||
},
|
||||
"lowLowercase": {
|
||||
"message": "low"
|
||||
},
|
||||
"lowPriorityMessage": {
|
||||
"message": "Future transactions will queue after this one. This price was last seen was some time ago."
|
||||
},
|
||||
@ -1728,6 +1737,17 @@
|
||||
"networkStatus": {
|
||||
"message": "Network status"
|
||||
},
|
||||
"networkStatusBaseFeeTooltip": {
|
||||
"message": "The base fee is set by the network and changes every 13-14 seconds. Our $1 and $2 options account for sudden increases.",
|
||||
"description": "$1 and $2 are bold text for Medium and Aggressive respectively."
|
||||
},
|
||||
"networkStatusPriorityFeeTooltip": {
|
||||
"message": "Range of priority fees (aka “miner tip”). This goes to miners and incentivizes them to prioritize your transaction."
|
||||
},
|
||||
"networkStatusStabilityFeeTooltip": {
|
||||
"message": "Gas fees are $1 relative to the past 72 hours.",
|
||||
"description": "$1 is networks stability value - stable, low, high"
|
||||
},
|
||||
"networkURL": {
|
||||
"message": "Network URL"
|
||||
},
|
||||
@ -2089,6 +2109,9 @@
|
||||
"message": "Select native to prioritize displaying values in the native currency of the chain (e.g. ETH). Select Fiat to prioritize displaying values in your selected fiat currency."
|
||||
},
|
||||
"priorityFee": {
|
||||
"message": "Priority fee"
|
||||
},
|
||||
"priorityFeeProperCase": {
|
||||
"message": "Priority Fee"
|
||||
},
|
||||
"privacyMsg": {
|
||||
@ -2552,6 +2575,9 @@
|
||||
"stable": {
|
||||
"message": "Stable"
|
||||
},
|
||||
"stableLowercase": {
|
||||
"message": "stable"
|
||||
},
|
||||
"stateLogError": {
|
||||
"message": "Error in retrieving state logs."
|
||||
},
|
||||
|
@ -52,7 +52,7 @@ const PriorityFeeInput = () => {
|
||||
<>
|
||||
<FormField
|
||||
onChange={updatePriorityFee}
|
||||
titleText={t('priorityFee')}
|
||||
titleText={t('priorityFeeProperCase')}
|
||||
titleUnit="(GWEI)"
|
||||
tooltipText={t('advancedPriorityFeeToolTip')}
|
||||
value={priorityFee}
|
||||
|
@ -15,8 +15,8 @@
|
||||
@import 'edit-gas-display-education/index';
|
||||
@import 'edit-gas-fee-popover/index';
|
||||
@import 'edit-gas-fee-popover/edit-gas-item/index';
|
||||
@import 'edit-gas-fee-popover/network-status/index';
|
||||
@import 'edit-gas-fee-popover/network-status/status-slider/index';
|
||||
@import 'edit-gas-fee-popover/network-statistics/index';
|
||||
@import 'edit-gas-fee-popover/network-statistics/status-slider/index';
|
||||
@import 'flask/snaps-authorship-pill/index';
|
||||
@import 'edit-gas-fee-popover/edit-gas-tooltip/index';
|
||||
@import 'gas-customization/gas-modal-page-container/index';
|
||||
|
@ -13,7 +13,7 @@ import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system';
|
||||
import { INSUFFICIENT_FUNDS_ERROR_KEY } from '../../../helpers/constants/error-keys';
|
||||
import { useGasFeeContext } from '../../../contexts/gasFee';
|
||||
import EditGasItem from './edit-gas-item';
|
||||
import NetworkStatus from './network-status';
|
||||
import NetworkStatistics from './network-statistics';
|
||||
|
||||
const EditGasFeePopover = () => {
|
||||
const { balanceError } = useGasFeeContext();
|
||||
@ -52,7 +52,7 @@ const EditGasFeePopover = () => {
|
||||
<div className="edit-gas-fee-popover__content__separator" />
|
||||
<EditGasItem priorityLevel={PRIORITY_LEVELS.DAPP_SUGGESTED} />
|
||||
<EditGasItem priorityLevel={PRIORITY_LEVELS.CUSTOM} />
|
||||
<NetworkStatus />
|
||||
<NetworkStatistics />
|
||||
<Typography
|
||||
className="edit-gas-fee-popover__know-more"
|
||||
align="center"
|
||||
|
@ -101,7 +101,7 @@ const EditGasToolTip = ({
|
||||
fontWeight={FONT_WEIGHT.BOLD}
|
||||
className="edit-gas-tooltip__container__label"
|
||||
>
|
||||
{t('priorityFee')}
|
||||
{t('priorityFeeProperCase')}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant={TYPOGRAPHY.H7}
|
||||
|
@ -0,0 +1 @@
|
||||
export { default } from './network-statistics';
|
@ -1,4 +1,4 @@
|
||||
.network-status {
|
||||
.network-statistics {
|
||||
margin: 24px 0 12px;
|
||||
|
||||
&__info {
|
||||
@ -38,4 +38,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__tooltip-label {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
COLORS,
|
||||
FONT_WEIGHT,
|
||||
TYPOGRAPHY,
|
||||
} from '../../../../helpers/constants/design-system';
|
||||
import { useGasFeeContext } from '../../../../contexts/gasFee';
|
||||
import I18nValue from '../../../ui/i18n-value';
|
||||
import Typography from '../../../ui/typography/typography';
|
||||
|
||||
import { BaseFeeTooltip, PriorityFeeTooltip } from './tooltips';
|
||||
import StatusSlider from './status-slider';
|
||||
|
||||
const NetworkStatistics = () => {
|
||||
const { gasFeeEstimates } = useGasFeeContext();
|
||||
|
||||
return (
|
||||
<div className="network-statistics">
|
||||
<Typography
|
||||
color={COLORS.UI4}
|
||||
fontWeight={FONT_WEIGHT.BOLD}
|
||||
margin={[3, 0]}
|
||||
variant={TYPOGRAPHY.H8}
|
||||
>
|
||||
<I18nValue messageKey="networkStatus" />
|
||||
</Typography>
|
||||
<div className="network-statistics__info">
|
||||
<div className="network-statistics__info__field">
|
||||
<span className="network-statistics__info__field-data">
|
||||
<BaseFeeTooltip>
|
||||
{gasFeeEstimates?.estimatedBaseFee &&
|
||||
`${gasFeeEstimates?.estimatedBaseFee} GWEI`}
|
||||
</BaseFeeTooltip>
|
||||
</span>
|
||||
<span className="network-statistics__info__field-label">
|
||||
<I18nValue messageKey="baseFee" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="network-statistics__info__separator" />
|
||||
<div className="network-statistics__info__field network-statistics__info__field--priority-fee">
|
||||
<span className="network-statistics__info__field-data">
|
||||
<PriorityFeeTooltip>0.5 - 22 GWEI</PriorityFeeTooltip>
|
||||
</span>
|
||||
<span className="network-statistics__info__field-label">
|
||||
<I18nValue messageKey="priorityFee" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="network-statistics__info__separator" />
|
||||
<div className="network-statistics__info__field">
|
||||
<StatusSlider />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NetworkStatistics;
|
@ -6,7 +6,7 @@ import { ETH } from '../../../../helpers/constants/common';
|
||||
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
|
||||
import configureStore from '../../../../store/store';
|
||||
|
||||
import NetworkStatus from './network-status';
|
||||
import NetworkStatistics from './network-statistics';
|
||||
|
||||
jest.mock('../../../../store/actions', () => ({
|
||||
disconnectGasFeeEstimatePoller: jest.fn(),
|
||||
@ -44,13 +44,13 @@ const renderComponent = (props) => {
|
||||
|
||||
return renderWithProvider(
|
||||
<GasFeeContextProvider>
|
||||
<NetworkStatus />
|
||||
<NetworkStatistics />
|
||||
</GasFeeContextProvider>,
|
||||
store,
|
||||
);
|
||||
};
|
||||
|
||||
describe('NetworkStatus', () => {
|
||||
describe('NetworkStatistics', () => {
|
||||
it('should renders labels', () => {
|
||||
renderComponent();
|
||||
expect(screen.queryByText('Base fee')).toBeInTheDocument();
|
@ -3,7 +3,7 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 55%;
|
||||
width: 56px;
|
||||
|
||||
&__line {
|
||||
background-image: linear-gradient(to right, #037dd6, #d73a49);
|
@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
|
||||
import I18nValue from '../../../../ui/i18n-value';
|
||||
import { NetworkStabilityTooltip } from '../tooltips';
|
||||
|
||||
const GRADIENT_COLORS = [
|
||||
'#037DD6',
|
||||
'#1876C8',
|
||||
'#2D70BA',
|
||||
'#4369AB',
|
||||
'#57629E',
|
||||
'#6A5D92',
|
||||
'#805683',
|
||||
'#9A4D71',
|
||||
'#B44561',
|
||||
'#C54055',
|
||||
];
|
||||
|
||||
const STATUS_INFO = {
|
||||
low: {
|
||||
statusLabel: 'notBusy',
|
||||
tooltipLabel: 'lowLowercase',
|
||||
color: GRADIENT_COLORS[0],
|
||||
},
|
||||
stable: {
|
||||
statusLabel: 'stable',
|
||||
tooltipLabel: 'stableLowercase',
|
||||
color: GRADIENT_COLORS[4],
|
||||
},
|
||||
high: {
|
||||
statusLabel: 'busy',
|
||||
tooltipLabel: 'highLowercase',
|
||||
color: GRADIENT_COLORS[9],
|
||||
},
|
||||
};
|
||||
|
||||
const getStatusInfo = (status) => {
|
||||
if (status <= 0.33) {
|
||||
return STATUS_INFO.low;
|
||||
} else if (status > 0.66) {
|
||||
return STATUS_INFO.high;
|
||||
}
|
||||
return STATUS_INFO.stable;
|
||||
};
|
||||
|
||||
const StatusSlider = () => {
|
||||
const statusValue = 0.5;
|
||||
const sliderValueNumeric = Math.round(statusValue * 10);
|
||||
|
||||
const statusInfo = getStatusInfo(statusValue);
|
||||
|
||||
return (
|
||||
<NetworkStabilityTooltip statusInfo={statusInfo}>
|
||||
<div className="status-slider">
|
||||
<div className="status-slider__arrow-border">
|
||||
<div
|
||||
className="status-slider__arrow"
|
||||
style={{
|
||||
borderTopColor: GRADIENT_COLORS[sliderValueNumeric],
|
||||
marginLeft: `${sliderValueNumeric * 10}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="status-slider__line" />
|
||||
<div
|
||||
className="status-slider__label"
|
||||
style={{ color: GRADIENT_COLORS[sliderValueNumeric] }}
|
||||
>
|
||||
<I18nValue messageKey={statusInfo.statusLabel} />
|
||||
</div>
|
||||
</div>
|
||||
</NetworkStabilityTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusSlider;
|
@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||
import Tooltip from '../../../ui/tooltip';
|
||||
|
||||
const NetworkStatusTooltip = ({ children, html, title }) => (
|
||||
<Tooltip position="top" html={html} title={title} theme="tippy-tooltip-info">
|
||||
{children}
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
NetworkStatusTooltip.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
html: PropTypes.node,
|
||||
title: PropTypes.string,
|
||||
};
|
||||
|
||||
export const BaseFeeTooltip = ({ children }) => {
|
||||
const t = useI18nContext();
|
||||
return (
|
||||
<NetworkStatusTooltip
|
||||
html={t('networkStatusBaseFeeTooltip', [
|
||||
<strong
|
||||
key="base_fee_medium_estimate"
|
||||
className="network-status__tooltip-label"
|
||||
>
|
||||
{t('medium')}
|
||||
</strong>,
|
||||
<strong
|
||||
key="base_fee_high_estimate"
|
||||
className="network-status__tooltip-label"
|
||||
>
|
||||
{t('high')}
|
||||
</strong>,
|
||||
])}
|
||||
>
|
||||
{children}
|
||||
</NetworkStatusTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
BaseFeeTooltip.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export const PriorityFeeTooltip = ({ children }) => {
|
||||
const t = useI18nContext();
|
||||
return (
|
||||
<NetworkStatusTooltip title={t('networkStatusPriorityFeeTooltip')}>
|
||||
{children}
|
||||
</NetworkStatusTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
PriorityFeeTooltip.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export const NetworkStabilityTooltip = ({ children, statusInfo }) => {
|
||||
const t = useI18nContext();
|
||||
|
||||
return (
|
||||
<NetworkStatusTooltip
|
||||
html={t('networkStatusStabilityFeeTooltip', [
|
||||
<strong
|
||||
key="network-status__tooltip"
|
||||
className="network-status__tooltip-label"
|
||||
style={{ color: statusInfo.color }}
|
||||
>
|
||||
{t(statusInfo.tooltipLabel)}
|
||||
</strong>,
|
||||
])}
|
||||
>
|
||||
{children}
|
||||
</NetworkStatusTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
NetworkStabilityTooltip.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
statusInfo: PropTypes.object,
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './network-status';
|
@ -1,55 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
COLORS,
|
||||
TYPOGRAPHY,
|
||||
} from '../../../../helpers/constants/design-system';
|
||||
import { useGasFeeContext } from '../../../../contexts/gasFee';
|
||||
import I18nValue from '../../../ui/i18n-value';
|
||||
import Typography from '../../../ui/typography/typography';
|
||||
|
||||
import StatusSlider from './status-slider';
|
||||
|
||||
const NetworkStatus = () => {
|
||||
const { gasFeeEstimates } = useGasFeeContext();
|
||||
|
||||
return (
|
||||
<div className="network-status">
|
||||
<Typography
|
||||
color={COLORS.UI4}
|
||||
fontWeight="bold"
|
||||
margin={[3, 0]}
|
||||
tag={TYPOGRAPHY.H6}
|
||||
variant={TYPOGRAPHY.H8}
|
||||
>
|
||||
<I18nValue messageKey="networkStatus" />
|
||||
</Typography>
|
||||
<div className="network-status__info">
|
||||
<div className="network-status__info__field">
|
||||
<span className="network-status__info__field-data">
|
||||
{gasFeeEstimates?.estimatedBaseFee &&
|
||||
`${gasFeeEstimates?.estimatedBaseFee} GWEI`}
|
||||
</span>
|
||||
<span className="network-status__info__field-label">Base fee</span>
|
||||
</div>
|
||||
<div className="network-status__info__separator" />
|
||||
<div className="network-status__info__field network-status__info__field--priority-fee">
|
||||
<span className="network-status__info__field-data">
|
||||
0.5 - 22 GWEI
|
||||
</span>
|
||||
<span className="network-status__info__field-label">
|
||||
Priority fee
|
||||
</span>
|
||||
</div>
|
||||
<div className="network-status__info__separator" />
|
||||
<div className="network-status__info__field">
|
||||
<StatusSlider />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
NetworkStatus.propTypes = {};
|
||||
|
||||
export default NetworkStatus;
|
@ -1,53 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import I18nValue from '../../../../ui/i18n-value';
|
||||
|
||||
const GRADIENT_COLORS = [
|
||||
'#037DD6',
|
||||
'#1876C8',
|
||||
'#2D70BA',
|
||||
'#4369AB',
|
||||
'#57629E',
|
||||
'#6A5D92',
|
||||
'#805683',
|
||||
'#9A4D71',
|
||||
'#B44561',
|
||||
'#C54055',
|
||||
];
|
||||
|
||||
const StatusSlider = () => {
|
||||
// todo: value below to be replaced with dynamic values from api once it is available
|
||||
// corresponding test cases also to be added
|
||||
const statusValue = 0.5;
|
||||
const sliderValueNumeric = Math.round(statusValue * 10);
|
||||
|
||||
let statusLabel = 'stable';
|
||||
if (statusValue <= 0.33) {
|
||||
statusLabel = 'notBusy';
|
||||
} else if (statusValue > 0.66) {
|
||||
statusLabel = 'busy';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="status-slider">
|
||||
<div className="status-slider__arrow-border">
|
||||
<div
|
||||
className="status-slider__arrow"
|
||||
style={{
|
||||
borderTopColor: GRADIENT_COLORS[sliderValueNumeric],
|
||||
marginLeft: `${sliderValueNumeric * 10}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="status-slider__line" />
|
||||
<div
|
||||
className="status-slider__label"
|
||||
style={{ color: GRADIENT_COLORS[sliderValueNumeric] }}
|
||||
>
|
||||
<I18nValue messageKey={statusLabel} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StatusSlider;
|
Loading…
Reference in New Issue
Block a user