1
0
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:
Jyoti Puri 2021-12-06 21:32:23 +05:30 committed by GitHub
parent 2dd8689d8a
commit a6bb503e52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 259 additions and 120 deletions

View File

@ -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."
},

View File

@ -52,7 +52,7 @@ const PriorityFeeInput = () => {
<>
<FormField
onChange={updatePriorityFee}
titleText={t('priorityFee')}
titleText={t('priorityFeeProperCase')}
titleUnit="(GWEI)"
tooltipText={t('advancedPriorityFeeToolTip')}
value={priorityFee}

View File

@ -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';

View File

@ -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"

View File

@ -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}

View File

@ -0,0 +1 @@
export { default } from './network-statistics';

View File

@ -1,4 +1,4 @@
.network-status {
.network-statistics {
margin: 24px 0 12px;
&__info {
@ -38,4 +38,8 @@
}
}
}
&__tooltip-label {
font-weight: 700;
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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,
};

View File

@ -1 +0,0 @@
export { default } from './network-status';

View File

@ -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;

View File

@ -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;