Skip to content

Commit

Permalink
refactor: use FormatPrice component (#1565)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick-1979 authored Sep 29, 2024
1 parent fa9d47d commit 6c3fbcd
Show file tree
Hide file tree
Showing 20 changed files with 314 additions and 219 deletions.
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 @@ -56,13 +56,13 @@ const BalanceRow = ({ api, asset, pricesInCurrencies }: BalanceRowProps) => {
token={asset.token}
/>
</Grid>
<Grid item sx={{ fontSize: '13px', fontWeight: 400, lineHeight: 1 }}>
<FormatPrice
amount={total}
decimals={asset.decimal}
price={pricesInCurrencies?.prices?.[asset.priceId]?.value ?? 0}
/>
</Grid>
<FormatPrice
amount={total}
decimals={asset.decimal}
fontSize='13px'
fontWeight={ 400}
price={pricesInCurrencies?.prices?.[asset.priceId]?.value ?? 0}
/>
</Grid>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ interface PriceJSXType {
}

const Price = ({ balanceToShow, isPriceOutdated, price }: PriceJSXType) => (
<Grid item sx={{ '> div span': { display: 'block' }, color: isPriceOutdated ? 'primary.light' : 'text.primary', fontWeight: 400 }}>
<FormatPrice
amount={getValue('total', balanceToShow)}
decimals={balanceToShow?.decimal}
price={price}
skeletonHeight={22}
width='80px'
/>
</Grid>
<FormatPrice
amount={getValue('total', balanceToShow)}
decimals={balanceToShow?.decimal}
fontSize='28px'
fontWeight= { 400 }
price={price}
skeletonHeight={22}
textColor={ isPriceOutdated ? 'primary.light' : 'text.primary'}
width='80px'
/>
);

interface BalanceJSXType {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

/* eslint-disable react/jsx-max-props-per-line */

Expand All @@ -12,14 +11,14 @@ import { useAssetHubAssets, useTokens } from '../../../hooks';

interface Props {
address: string | undefined;
onChange: (value: number) => void;
onChange: (value: number | string) => void;
label: string;
style: SxProps<Theme> | undefined;
assetId: number | undefined;
setAssetId: React.Dispatch<React.SetStateAction<number | undefined>>
}

function AssetSelect({ address, assetId, label, onChange, setAssetId, style }: Props) {
function AssetSelect ({ address, assetId, label, onChange, setAssetId, style }: Props) {
const tokens = useTokens(address);
const assets = useAssetHubAssets(address);
const options = useMemo(() => (tokens || []).concat(assets || []), [assets, tokens]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
/* eslint-disable react/jsx-max-props-per-line */

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

import { ArrowForwardIosRounded as ArrowForwardIosRoundedIcon } from '@mui/icons-material';
import { Divider, Grid, IconButton, Typography, useTheme } from '@mui/material';
import React from 'react';

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

import { FormatPrice, ShowBalance } from '../../../components';

interface Props {
Expand All @@ -24,7 +23,7 @@ interface Props {
openCollapse?: boolean;
}

export default function DisplayBalance({ amount, decimal, disabled, onClick, price, openCollapse, title, token }: Props): React.ReactElement {
export default function DisplayBalance ({ amount, decimal, disabled, onClick, openCollapse, price, title, token }: Props): React.ReactElement {
const theme = useTheme();

return (
Expand All @@ -43,14 +42,14 @@ export default function DisplayBalance({ amount, decimal, disabled, onClick, pri
/>
</Grid>
<Divider orientation='vertical' sx={{ backgroundColor: 'text.primary', height: '35px', mx: '10px', my: 'auto' }} />
<Grid item sx={{ '> div span': { display: 'block' }, fontSize: '22px', fontWeight: 400 }}>
<FormatPrice
amount={amount}
decimals={decimal}
price={price}
skeletonHeight={20}
/>
</Grid>
<FormatPrice
amount={amount}
decimals={decimal}
fontSize= '22px'
fontWeight= {400}
price={price}
skeletonHeight={20}
/>
{onClick &&
<Grid item m='auto' pl='8px'>
<IconButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ export default function LockedInReferendaFS ({ address, price, refreshNeeded, se
/>
</Grid>
<Divider orientation='vertical' sx={{ backgroundColor: 'text.primary', height: '35px', mx: '10px', my: 'auto' }} />
<Grid item sx={{ '> div span': { display: 'block' }, fontSize: '22px', fontWeight: 400 }}>
<FormatPrice
amount={totalLocked}
decimals={decimal}
price={price}
skeletonHeight={20}
/>
</Grid>
<FormatPrice
amount={totalLocked}
decimals={decimal}
fontSize= '22px'
fontWeight={ 400}
price={price}
skeletonHeight={20}
/>
</Grid>
<Typography fontSize='12px' fontWeight={500} textAlign='right'>
{api && unlockableAmount && !unlockableAmount.isZero()
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,21 +108,24 @@ 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 (
<Grid alignItems='center' container direction='column' item justifyContent='center' sx={{ bgcolor: 'background.paper', borderRadius: '5px', boxShadow: '2px 3px 4px 0px rgba(0, 0, 0, 0.1)', maxHeight: '185px', p: '15px', width: 'inherit' }}>
<Grid alignItems='center' container gap='15px' item justifyContent='center'>
<Grid alignItems='center' container gap='15px' item justifyContent='center' height='54px'>
<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 @@ -150,14 +150,14 @@ export default function AccountDetails (): React.ReactElement {
}
}, [genesisHash, accountAssets, assetId, paramAssetId, selectedAsset]);

const onChangeAsset = useCallback((id: number) => {
const onChangeAsset = useCallback((id: number | string) => {
if (id === -1) { // this is the id of native token
setAssetIdOnAssetHub(0);

return;
}

setAssetIdOnAssetHub(id); // this works for asset hubs atm
setAssetIdOnAssetHub(id as number); // this works for asset hubs atm
}, []);

const goToSend = useCallback(() => {
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
Loading

0 comments on commit 6c3fbcd

Please sign in to comment.