Skip to content

refactor: use FormatPrice component #1565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 29, 2024
50 changes: 37 additions & 13 deletions packages/extension-polkagate/src/components/FormatPrice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import type { BN } from '@polkadot/util';

import { Grid, Skeleton } from '@mui/material';
import { Grid, Skeleton, Typography } from '@mui/material';
import React, { useMemo } from 'react';

import { useCurrency } from '../hooks';
Expand All @@ -13,23 +13,29 @@ interface Props {
amount?: BN | null;
decimalPoint?: number;
decimals?: number;
fontSize?: string;
fontWeight?: number;
lineHeight?: number;
mt?: string;
num?: number | string;
price?: number | null,
sign?: string;
skeletonHeight?: number;
textAlign?: 'left' | 'right';
textColor?: string;
height?: number;
width?: string;
mt?: string;
skeletonHeight?: number;
}

export function nFormatter (num: number, decimalPoint: number) {
const lookup = [
{ value: 1, symbol: '' },
{ value: 1e3, symbol: 'k' },
{ value: 1e6, symbol: 'M' },
{ value: 1e9, symbol: 'G' },
{ value: 1e12, symbol: 'T' },
{ value: 1e15, symbol: 'P' },
{ value: 1e18, symbol: 'E' }
{ symbol: '', value: 1 },
{ symbol: 'k', value: 1e3 },
{ symbol: 'M', value: 1e6 },
{ symbol: 'G', value: 1e9 },
{ symbol: 'T', value: 1e12 },
{ symbol: 'P', value: 1e15 },
{ symbol: 'E', value: 1e18 }
];

const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
Expand All @@ -44,11 +50,13 @@ export function nFormatter (num: number, decimalPoint: number) {
return item ? (num / item.value).toFixed(decimalPoint).replace(rx, '$1') + item.symbol : '0';
}

function FormatPrice ({ amount, decimalPoint = 2, decimals, mt = '0px', num, price, skeletonHeight = 15, textAlign = 'left', width = '90px' }: Props): React.ReactElement<Props> {
const DECIMAL_POINTS_FOR_CRYPTO_AS_CURRENCY = 4;

function FormatPrice ({ amount, decimalPoint = 2, decimals, fontSize, fontWeight, height, lineHeight = 1, mt = '0px', num, price, sign, skeletonHeight = 15, textAlign = 'left', textColor, width = '90px' }: Props): React.ReactElement<Props> {
const currency = useCurrency();

const total = useMemo(() => {
if (num) {
if (num !== undefined) {
return num;
}

Expand All @@ -59,14 +67,30 @@ function FormatPrice ({ amount, decimalPoint = 2, decimals, mt = '0px', num, pri
return undefined;
}, [amount, decimals, num, price]);

const _decimalPoint = useMemo(() => {
if (currency?.code && ['ETH', 'BTC'].includes(currency.code)) {
return DECIMAL_POINTS_FOR_CRYPTO_AS_CURRENCY;
}

return decimalPoint;
}, [currency?.code, decimalPoint]);

return (
<Grid
item
mt={mt}
sx={{ height }}
textAlign={textAlign}
>
{total !== undefined
? `${currency?.sign || ''}${nFormatter(total as number, decimalPoint)}`
? <Typography
fontSize={fontSize}
fontWeight={fontWeight}
lineHeight={lineHeight}
sx={{ color: textColor }}
>
{sign || currency?.sign || ''}{nFormatter(total as number, _decimalPoint)}
</Typography>
: <Skeleton
animation='wave'
height={skeletonHeight}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { Chart, registerables } from 'chart.js';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';

import { AssetLogo } from '../../../components';
import { nFormatter } from '../../../components/FormatPrice';
import { useCurrency, useTranslation } from '../../../hooks';
import FormatPrice from '../../../components/FormatPrice';
import { useTranslation } from '../../../hooks';
import { DEFAULT_COLOR } from '../../../util/constants';
import getLogo2 from '../../../util/getLogo2';
import { amountToHuman } from '../../../util/utils';
Expand All @@ -31,10 +31,9 @@ interface AssetsToShow extends FetchedBalance {
color: string
}

export default function TotalChart({ accountAssets, pricesInCurrency }: Props): React.ReactElement {
export default function TotalChart ({ accountAssets, pricesInCurrency }: Props): React.ReactElement {
const { t } = useTranslation();
const theme = useTheme();
const currency = useCurrency();
const chartRef = useRef(null);

Chart.register(...registerables);
Expand All @@ -45,10 +44,10 @@ export default function TotalChart({ accountAssets, pricesInCurrency }: Props):
const formatNumber = useCallback((num: number): number => parseFloat(Math.trunc(num) === 0 ? num.toFixed(2) : num.toFixed(1)), []);

const { assets, totalWorth } = useMemo(() => {
if (accountAssets && accountAssets.length) {
if (accountAssets?.length) {
const _assets = accountAssets as unknown as AssetsToShow[];

let totalWorth = 0;
let total = 0;

/** to add asset's worth and color */
accountAssets.forEach((asset, index) => {
Expand All @@ -58,20 +57,20 @@ export default function TotalChart({ accountAssets, pricesInCurrency }: Props):
_assets[index].worth = assetWorth;
_assets[index].color = adjustColor(asset.token, assetColor, theme);

totalWorth += assetWorth;
total += assetWorth;
});

/** to add asset's percentage */
_assets.forEach((asset) => {
asset.percentage = formatNumber((asset.worth / totalWorth) * 100);
asset.percentage = formatNumber((asset.worth / total) * 100);

return asset;
});

_assets.sort((a, b) => b.worth - a.worth);
const nonZeroAssets = _assets.filter((asset) => asset.worth > 0);

return { assets: nonZeroAssets, totalWorth: nFormatter(totalWorth, 2) };
return { assets: nonZeroAssets, totalWorth: total };
}

return { assets: undefined, totalWorth: undefined };
Expand All @@ -81,7 +80,7 @@ export default function TotalChart({ accountAssets, pricesInCurrency }: Props):
const worths = assets?.map(({ worth }) => worth);
const colors = assets?.map(({ color }) => color);

//@ts-ignore
// @ts-ignore
const chartInstance = new Chart(chartRef.current, {
data: {
datasets: [{
Expand All @@ -100,7 +99,7 @@ export default function TotalChart({ accountAssets, pricesInCurrency }: Props):
label: function (context) {
const index = colors?.findIndex((val) => val === context.element.options['backgroundColor']);

return index && index != -1 ? assets?.[index]?.token as string :'UNIT';
return index && index !== -1 ? assets?.[index]?.token : 'UNIT';
}
}
}
Expand All @@ -109,10 +108,10 @@ export default function TotalChart({ accountAssets, pricesInCurrency }: Props):
type: 'doughnut'
});

// Clean up the chart instance on component unmount
return () => {
chartInstance.destroy();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [assets?.length, theme.palette.divider]);

return (
Expand All @@ -121,9 +120,12 @@ export default function TotalChart({ accountAssets, pricesInCurrency }: Props):
<Typography fontSize='18px' fontWeight={400}>
{t('Total')}
</Typography>
<Typography fontSize='36px' fontWeight={700}>
{`${currency?.sign ?? ''}${totalWorth ?? 0}`}
</Typography>
<FormatPrice
fontSize='36px'
fontWeight={700}
num={totalWorth}
skeletonHeight={22}
/>
</Grid>
{assets && assets.length > 0 &&
<Grid container item sx={{ borderTop: '1px solid', borderTopColor: 'divider', py: '5px' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { Circle } from 'better-react-spinkit';
import React, { useEffect, useState } from 'react';

import { Label } from '../../components';
import { nFormatter } from '../../components/FormatPrice';
import { useCurrency, useTranslation } from '../../hooks';
import FormatPrice from '../../components/FormatPrice';
import { useTranslation } from '../../hooks';
import { toTitleCase } from '../governance/utils/util';

interface Props {
Expand Down Expand Up @@ -44,7 +44,6 @@ const TOKEN_PRICE_KEY = 'tokenPrice';
export default function ShowChainInfo ({ metadata, price, style }: Props): React.ReactElement {
const { t } = useTranslation();
const theme = useTheme();
const currency = useCurrency();

const [selectedChainInfo, setSelectedChainInfo] = useState<SelectedChainInfo | undefined>();

Expand Down Expand Up @@ -88,7 +87,12 @@ export default function ShowChainInfo ({ metadata, price, style }: Props): React
Object.entries(selectedChainInfo).map(([key, value]) => (
<Typography fontSize='14px' fontWeight={300} height={`${LINE_HEIGHT}px`} key={key}>
{key === TOKEN_PRICE_KEY
? `${currency?.sign || ''}${nFormatter(value as number, 2)}`
? <FormatPrice
decimalPoint={4}
fontSize='14px'
fontWeight={300}
num={(value || 0) as number}
/>
: value ?? '--- ---'
}
</Typography>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { ApiPromise, WsProvider } from '@polkadot/api';

import { endpointUrlPng } from '../../assets/img';
import { ActionContext, InputWithLabel, Progress, TwoButtons, VaadinIcon, Warning } from '../../components';
import { nFormatter } from '../../components/FormatPrice';
import FormatPrice from '../../components/FormatPrice';
import { updateStorage } from '../../components/Loading';
import { useCurrency, useFullscreen, useTranslation } from '../../hooks';
import { updateMetadata } from '../../messaging';
Expand Down Expand Up @@ -291,7 +291,12 @@ export default function AddNewChain (): React.ReactElement {
{priceId && price !== undefined &&
<Typography fontSize='16px' fontWeight={400}>
{price
? `${currency?.sign || ''}${nFormatter(price, 4)}`
? <FormatPrice
decimalPoint={4}
fontSize='18px'
num={price}
width='80px'
/>
: 'Check the price id, and try again!'
}
</Typography>}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

// @ts-nocheck
/* eslint-disable react/jsx-max-props-per-line */

import type { Proposal, Referendum } from '../utils/types';
Expand All @@ -15,9 +14,8 @@ import rehypeRaw from 'rehype-raw';

import { BN } from '@polkadot/util';

import { Identity, ShowBalance, ShowValue } from '../../../components';
import { nFormatter } from '../../../components/FormatPrice';
import { useApi, useChain, useDecimal, useToken, useTokenPrice, useTranslation } from '../../../hooks';
import { FormatPrice, Identity, ShowBalance, ShowValue } from '../../../components';
import { useInfo, useTokenPrice, useTranslation } from '../../../hooks';
import useStyles from '../styles/styles';
import { LabelValue } from '../TrackStats';
import { STATUS_COLOR } from '../utils/consts';
Expand All @@ -35,10 +33,7 @@ const DEFAULT_CONTENT = 'This referendum does not have a description provided by
export default function ReferendumDescription ({ address, currentTreasuryApprovalList, referendum }: Props): React.ReactElement {
const { t } = useTranslation();
const theme = useTheme();
const api = useApi(address);
const chain = useChain(address);
const decimal = useDecimal(address);
const token = useToken(address);
const { api, chain, decimal, token } = useInfo(address);
const { price } = useTokenPrice(address);
const style = useStyles();

Expand Down Expand Up @@ -149,9 +144,13 @@ export default function ReferendumDescription ({ address, currentTreasuryApprova
valueStyle={{ fontSize: 16, fontWeight: 500, pl: '5px' }}
/>
</Grid>
<Divider flexItem orientation='vertical' sx={{ bgcolor: theme.palette.mode === 'light' ? 'inherit' : 'text.disabled', mx: '7px', my: '8px' }} />
<Divider flexItem orientation='vertical' sx={{ bgcolor: theme.palette.mode === 'light' ? 'inherit' : 'text.disabled', mx: '7px', my: '8px' }} />
<Grid item sx={{ color: theme.palette.mode === 'light' ? 'text.disabled' : undefined, opacity: theme.palette.mode === 'dark' ? 0.6 : 1 }}>
{`$${requestedInUSD ? nFormatter(requestedInUSD, 2) : '0'}`}
<FormatPrice
decimalPoint={2}
num={requestedInUSD || 0}
sign='$'
/>
</Grid>
</Grid>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import type { HexString } from '@polkadot/util/types';
import type { FetchedBalance } from '../../../hooks/useAssetsBalances';

import { ArrowForwardIos as ArrowForwardIosIcon, MoreVert as MoreVertIcon } from '@mui/icons-material';
import { Box, Button, Divider, Grid, Skeleton, Typography, useTheme } from '@mui/material';
import { Box, Button, Divider, Grid, Typography, useTheme } from '@mui/material';
import React, { useCallback, useContext, useMemo, useState } from 'react';

import { getValue } from '@polkadot/extension-polkagate/src/popup/account/util';

import { stars6Black, stars6White } from '../../../assets/icons';
import { ActionContext, Identicon, Identity, OptionalCopyButton, ShortAddress2 } from '../../../components';
import { nFormatter } from '../../../components/FormatPrice';
import FormatPrice from '../../../components/FormatPrice';
import { useCurrency, useIdentity, useInfo, usePrices, useTranslation } from '../../../hooks';
import { showAccount, tieAccount } from '../../../messaging';
import { amountToHuman } from '../../../util/utils';
Expand Down Expand Up @@ -65,7 +65,7 @@ const AccountButton = ({ icon, onClick, text }: AccountButtonType) => {
);
};

const AccountTotal = ({ currencySign, hideNumbers, totalBalance }: { currencySign: string | undefined, hideNumbers: boolean | undefined, totalBalance: number | undefined }) => {
const AccountTotal = ({ hideNumbers, totalBalance }: { hideNumbers: boolean | undefined, totalBalance: number | undefined }) => {
const theme = useTheme();
const { t } = useTranslation();

Expand All @@ -78,11 +78,13 @@ const AccountTotal = ({ currencySign, hideNumbers, totalBalance }: { currencySig
{
hideNumbers || hideNumbers === undefined
? <Box component='img' src={(theme.palette.mode === 'dark' ? stars6White : stars6Black) as string} sx={{ height: '36px', width: '154px' }} />
: totalBalance !== undefined
? <Typography fontSize='32px' fontWeight={700}>
{`${currencySign ?? ''}${nFormatter(totalBalance ?? 0, 2)}`}
</Typography>
: <Skeleton animation='wave' height={28} sx={{ my: '2.5px', transform: 'none' }} variant='text' width={180} />
: <FormatPrice
fontSize='32px'
fontWeight={700}
num={totalBalance}
skeletonHeight={28}
width='180px'
/>
}
</Grid>
</Grid>
Expand Down Expand Up @@ -192,7 +194,6 @@ function AccountInformationForHome ({ accountAssets, address, hideNumbers, isChi
</Grid>
</Grid>
<AccountTotal
currencySign={currency?.sign}
hideNumbers={hideNumbers}
totalBalance={totalBalance}
/>
Expand Down
Loading
Loading