diff --git a/package.json b/package.json index 1d5e01b14..f2c343d7f 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "memoize-one": "^6.0.0", "qrcode.react": "^3.0.2", "react-chartjs-2": "^5.2.0", + "react-countup": "^6.5.3", "react-json-to-table": "^0.1.7", "react-markdown": "^8.0.7", "react-tooltip": "^4.2.21", diff --git a/packages/extension-polkagate/src/components/FormatPrice.tsx b/packages/extension-polkagate/src/components/FormatPrice.tsx index 27040c4bd..5ca9e9482 100644 --- a/packages/extension-polkagate/src/components/FormatPrice.tsx +++ b/packages/extension-polkagate/src/components/FormatPrice.tsx @@ -5,6 +5,7 @@ import type { BN } from '@polkadot/util'; import { Grid, Skeleton, Typography } from '@mui/material'; import React, { useMemo } from 'react'; +import CountUp from 'react-countup'; import { useCurrency } from '../hooks'; import { ASSETS_AS_CURRENCY_LIST } from '../util/currencyList'; @@ -27,6 +28,7 @@ interface Props { textColor?: string; height?: number; width?: string; + withCountUp?: boolean; } export function nFormatter (num: number, decimalPoint: number) { @@ -54,7 +56,7 @@ export function nFormatter (num: number, decimalPoint: number) { const DECIMAL_POINTS_FOR_CRYPTO_AS_CURRENCY = 4; -function FormatPrice ({ amount, commify, decimalPoint = 2, decimals, fontSize, fontWeight, height, lineHeight = 1, mt = '0px', num, price, sign, skeletonHeight = 15, textAlign = 'left', textColor, width = '90px' }: Props): React.ReactElement { +function FormatPrice ({ amount, commify, decimalPoint = 2, decimals, fontSize, fontWeight, height, lineHeight = 1, mt = '0px', num, price, sign, skeletonHeight = 15, textAlign = 'left', textColor, width = '90px', withCountUp }: Props): React.ReactElement { const currency = useCurrency(); const total = useMemo(() => { @@ -91,7 +93,17 @@ function FormatPrice ({ amount, commify, decimalPoint = 2, decimals, fontSize, f lineHeight={lineHeight} sx={{ color: textColor }} > - {sign || currency?.sign || ''}{ commify ? fixFloatingPoint(total as number, _decimalPoint, true) : nFormatter(total as number, _decimalPoint)} + {withCountUp + ? + : <> + {sign || currency?.sign || ''}{ commify ? fixFloatingPoint(total as number, _decimalPoint, true) : nFormatter(total as number, _decimalPoint)} + + } : setShowMore(!showMore), [showMore]); + const portfolioChange = useMemo(() => { + if (!youHave?.change) { + return 0; + } + + const value = fixFloatingPoint(youHave.change, 2, false, true); + + return parseFloat(value); + }, [youHave?.change]); + + const changeSign = !youHave?.change + ? '' + : youHave.change > 0 ? '+ ' : '- '; + return ( @@ -214,9 +229,16 @@ function TotalBalancePieChart ({ hideNumbers, setGroupedAssets }: Props): React. fontWeight={700} num={youHave?.portfolio} textColor= { isPriceOutdated(youHave) ? 'primary.light' : 'text.primary'} + withCountUp /> - 0 ? 'success.main' : 'warning.main', fontSize: '18px', fontWeight: 500 }}> - {youHave.change > 0 ? '+ ' : '- '}{currency?.sign}{ fixFloatingPoint(youHave?.change, 2, true, true)} {`(${COIN_GECKO_PRICE_CHANGE_DURATION}h)`} + 0 ? 'success.main' : 'warning.main', fontSize: '18px', fontWeight: 500 }}> + } diff --git a/packages/extension-polkagate/src/hooks/useYouHave.ts b/packages/extension-polkagate/src/hooks/useYouHave.ts index 40d6d40d1..ac3ef4de2 100644 --- a/packages/extension-polkagate/src/hooks/useYouHave.ts +++ b/packages/extension-polkagate/src/hooks/useYouHave.ts @@ -6,8 +6,9 @@ import type { BN } from '@polkadot/util'; import { useCallback, useContext, useMemo } from 'react'; import { AccountsAssetsContext } from '../components'; +import { ASSETS_AS_CURRENCY_LIST } from '../util/currencyList'; import { amountToHuman } from '../util/utils'; -import { usePrices } from '.'; +import { useCurrency, usePrices } from '.'; export interface YouHaveType { change: number; @@ -23,6 +24,7 @@ export interface YouHaveType { export default function useYouHave (): YouHaveType | undefined | null { const pricesInCurrencies = usePrices(); const { accountsAssets } = useContext(AccountsAssetsContext); + const currency = useCurrency(); const calcPrice = useCallback( (assetPrice: number | undefined, balance: BN, decimal: number) => @@ -62,10 +64,12 @@ export default function useYouHave (): YouHaveType | undefined | null { }); }); - const change = totalPrice - totalBeforeChange; + const change = currency?.code + ? ASSETS_AS_CURRENCY_LIST.includes(currency.code.toUpperCase()) ? 0 : totalPrice - totalBeforeChange + : 0; return { change, date, portfolio: totalPrice } as unknown as YouHaveType; - }, [accountsAssets, calcChange, calcPrice, pricesInCurrencies]); + }, [accountsAssets, calcChange, calcPrice, currency, pricesInCurrencies]); return youHave; } diff --git a/packages/extension-polkagate/src/popup/home/YouHave.tsx b/packages/extension-polkagate/src/popup/home/YouHave.tsx index e59be9a7f..d5fa85a98 100644 --- a/packages/extension-polkagate/src/popup/home/YouHave.tsx +++ b/packages/extension-polkagate/src/popup/home/YouHave.tsx @@ -56,13 +56,14 @@ export default function YouHave ({ hideNumbers, setHideNumbers }: Props): React. /> : } diff --git a/packages/extension-polkagate/src/util/utils.ts b/packages/extension-polkagate/src/util/utils.ts index 2683e8699..a0d638bac 100644 --- a/packages/extension-polkagate/src/util/utils.ts +++ b/packages/extension-polkagate/src/util/utils.ts @@ -50,6 +50,12 @@ function countLeadingZerosInFraction (numStr: string) { return 0; } +export function countDecimalPlaces (n: number) { + const match = n.toString().match(/\.(\d+)/); + + return match ? match[1].length : 0; +} + export function fixFloatingPoint (_number: number | string, decimalDigit = FLOATING_POINT_DIGIT, commify?: boolean, dynamicDecimal?: boolean): string { const MAX_DECIMAL_POINTS = 6; diff --git a/yarn.lock b/yarn.lock index 471a7f2cd..6ff099f86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8297,6 +8297,13 @@ __metadata: languageName: node linkType: hard +"countup.js@npm:^2.8.0": + version: 2.8.0 + resolution: "countup.js@npm:2.8.0" + checksum: 10/6681de9de9acd0d65b91183af280a462f2fbbc19ac5a90d30ea94e388f12b0d1cc7fa2b63b6bb83adc9dc38f938cd2a41f727a0b2ae7edf0d82f4b2ccb51e98c + languageName: node + linkType: hard + "crc-32@npm:^1.2.2": version: 1.2.2 resolution: "crc-32@npm:1.2.2" @@ -16694,6 +16701,17 @@ __metadata: languageName: node linkType: hard +"react-countup@npm:^6.5.3": + version: 6.5.3 + resolution: "react-countup@npm:6.5.3" + dependencies: + countup.js: "npm:^2.8.0" + peerDependencies: + react: ">= 16.3.0" + checksum: 10/5699e475bdd82b0b100174acbe24a33c9025080bacbba9f28593308145eacfb3e0d30be5de5bb153121346b719375e317a9f2aea87776f38d508cbe769ac0d8b + languageName: node + linkType: hard + "react-dom@npm:^16.7.0": version: 16.14.0 resolution: "react-dom@npm:16.14.0" @@ -17620,6 +17638,7 @@ __metadata: pinst: "npm:^3.0.0" qrcode.react: "npm:^3.0.2" react-chartjs-2: "npm:^5.2.0" + react-countup: "npm:^6.5.3" react-json-to-table: "npm:^0.1.7" react-markdown: "npm:^8.0.7" react-tooltip: "npm:^4.2.21"