Skip to content

Commit 013f454

Browse files
feat: new you have (Portfolio) for Extension mode (#1655)
Co-authored-by: Amir Ekbatanifard <[email protected]>
1 parent bfb3966 commit 013f454

37 files changed

+732
-410
lines changed

packages/extension-polkagate/src/components/AccountIcons.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ function AccountIcons ({ address, identiconTheme, isSubId, judgements, prefix }:
4646
}, [address]);
4747

4848
return (
49-
<Grid container direction='column' sx={{ ml: '8px', width: '17%' }}>
49+
<Grid container direction='column' sx={{ m: '7px 0px 0px 8px', width: '17%' }}>
5050
<Grid item m='auto' width='fit-content'>
5151
<Identicon
5252
iconTheme={identiconTheme}
5353
isSubId={isSubId}
5454
judgement={judgements}
5555
prefix={prefix}
56-
size={40}
56+
size={35}
5757
value={formatted || address}
5858
/>
5959
</Grid>

packages/extension-polkagate/src/components/FormatPrice.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ export function nFormatter (num: number, decimalPoint: number) {
5858
const DECIMAL_POINTS_FOR_CRYPTO_AS_CURRENCY = 4;
5959
const SMALL_DECIMALS_FONT_SIZE_REDUCTION = 20;
6060

61+
const DecimalPart = ({ value, withCountUp }: { value: string | number, withCountUp: boolean | undefined }) => (
62+
withCountUp
63+
? <CountUp
64+
duration={1}
65+
end={Number(getDecimal(value))}
66+
prefix={'.'}
67+
/>
68+
: <>{`.${getDecimal(value)}`}</>
69+
);
70+
6171
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, withSmallDecimal }: Props): React.ReactElement<Props> {
6272
const currency = useCurrency();
6373
const theme = useTheme();
@@ -135,16 +145,10 @@ function FormatPrice ({ amount, commify, decimalPoint = 2, decimals, fontSize, f
135145
lineHeight={lineHeight}
136146
sx={{ color: theme.palette.secondary.contrastText }}
137147
>
138-
{withCountUp
139-
? <CountUp
140-
duration={1}
141-
end={Number(getDecimal(total))}
142-
prefix={'.'}
143-
/>
144-
: <>
145-
{`.${getDecimal(total)}`}
146-
</>
147-
}
148+
<DecimalPart
149+
value={total}
150+
withCountUp={withCountUp}
151+
/>
148152
</Typography>
149153
}
150154
</Stack>

packages/extension-polkagate/src/components/MenuItem.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { noop } from '../util/utils';
1212
interface Props {
1313
disabled?: boolean;
1414
icon?: string;
15-
iconComponent?: JSX.Element;
15+
iconComponent?: React.JSX.Element;
1616
text: string;
1717
children?: React.ReactElement<Props>;
1818
onClick?: MouseEventHandler<HTMLDivElement>;
@@ -35,8 +35,8 @@ export default function MenuItem ({ children, disabled = false, fontSize, icon,
3535

3636
return (
3737
<>
38-
<Grid alignItems='center' color={disabled ? '#4B4B4B' : 'inherit'} container item justifyContent='space-between' my='4px' onClick={disabled ? noop : onClick} pl={pl} py={py} sx={{ cursor: disabled ? '' : 'pointer', ...(withHoverEffect ? hoverEffectStyles : {}) }} textAlign='left' xs={12}>
39-
<Grid alignItems='center' container item xs sx={{ flexWrap: 'nowrap' }}>
38+
<Grid alignItems='center' color={disabled ? '#4B4B4B' : 'inherit'} container item justifyContent='space-between' my='4px' onClick={disabled ? noop : onClick} pl={pl} py={py} sx={{ cursor: disabled ? 'default' : 'pointer', ...(withHoverEffect ? hoverEffectStyles : {}) }} textAlign='left' xs={12}>
39+
<Grid alignItems='center' container item sx={{ flexWrap: 'nowrap' }} xs>
4040
<Grid alignItems='center' container item xs={1}>
4141
{iconComponent ??
4242
<Box

packages/extension-polkagate/src/components/RemoteNodeSelector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export default function RemoteNodeSelector ({ address, genesisHash }: Props): Re
4040
<>
4141
{endpoint &&
4242
<Select
43-
_mt='10px'
43+
_mt='3px'
4444
defaultValue={undefined}
4545
label={t('Remote node')}
4646
onChange={onChangeEndpoint}

packages/extension-polkagate/src/fullscreen/accountDetails/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { AccountContext, ActionContext, Warning } from '../../components';
1818
import { useAccountAssets, useBalances, useCurrency, useFullscreen, useInfo, usePrices, useTokenPrice, useTranslation } from '../../hooks';
1919
import { getValue } from '../../popup/account/util';
2020
import HistoryModal from '../../popup/history/modal/HistoryModal';
21-
import { AccountLabel } from '../../popup/home/AccountLabel';
21+
import AccountLabel from '../../popup/home/AccountLabel';
2222
import ReceiveModal from '../../popup/receive/ReceiveModal';
2323
import { ASSET_HUBS, GOVERNANCE_CHAINS, STAKING_CHAINS } from '../../util/constants';
2424
import getParentNameSuri from '../../util/getParentNameSuri';

packages/extension-polkagate/src/fullscreen/homeFullScreen/partials/AccountItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import React, { useContext, useMemo, useState } from 'react';
1515
import { AccountContext } from '../../../components';
1616
import { useAccountAssets, useChain } from '../../../hooks';
1717
import QuickActionFullScreen from '../../../partials/QuickActionFullScreen';
18-
import { AccountLabel } from '../../../popup/home/AccountLabel';
18+
import AccountLabel from '../../../popup/home/AccountLabel';
1919
import getParentNameSuri from '../../../util/getParentNameSuri';
2020
import AccountInformationForHome from './AccountInformationForHome';
2121

packages/extension-polkagate/src/fullscreen/homeFullScreen/partials/Currency.tsx

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,22 @@ export interface CurrencyItemType {
1818
sign: string;
1919
}
2020

21-
export default function Currency (): React.ReactElement {
21+
interface Props {
22+
borderColor?: string;
23+
color?: string;
24+
dialogLeft?: number;
25+
fontSize?: string;
26+
height?: string;
27+
minWidth?: string;
28+
}
29+
30+
function Currency ({ borderColor, color, dialogLeft = 260, fontSize = '22px', height, minWidth }: Props): React.ReactElement {
2231
const theme = useTheme();
2332

2433
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
2534
const [currencyToShow, setCurrencyToShow] = useState<CurrencyItemType | undefined>();
2635

27-
const textColor = useMemo(() => theme.palette.mode === 'dark' ? theme.palette.text.primary : theme.palette.text.secondary, [theme.palette.mode, theme.palette.text.primary, theme.palette.text.secondary]);
36+
const textColor = useMemo(() => color || (theme.palette.mode === 'dark' ? theme.palette.text.primary : theme.palette.text.secondary), [color, theme]);
2837

2938
useLayoutEffect(() => {
3039
if (currencyToShow) {
@@ -46,9 +55,18 @@ export default function Currency (): React.ReactElement {
4655

4756
return (
4857
<>
49-
<Grid alignItems='center' component='button' container direction='column' item justifyContent='center' onClick={onCurrencyClick} sx={{ ...HEADER_COMPONENT_STYLE, zIndex: anchorEl && theme.zIndex.modal + 1 }}>
58+
<Grid
59+
alignItems='center' component='button' container direction='column' item justifyContent='center' onClick={onCurrencyClick}
60+
sx={{
61+
...HEADER_COMPONENT_STYLE,
62+
borderColor: borderColor || HEADER_COMPONENT_STYLE?.borderColor,
63+
height: height || HEADER_COMPONENT_STYLE?.height,
64+
minWidth: minWidth || HEADER_COMPONENT_STYLE?.minWidth,
65+
zIndex: anchorEl && theme.zIndex.modal + 1
66+
}}
67+
>
5068
<Infotip2 text={currencyToShow?.currency}>
51-
<Typography color={textColor} fontSize='22px' fontWeight={500}>
69+
<Typography color={textColor} fontSize={ fontSize } fontWeight={500}>
5270
{currencyToShow?.sign || '$'}
5371
</Typography>
5472
</Infotip2>
@@ -62,7 +80,7 @@ export default function Currency (): React.ReactElement {
6280
boxShadow: theme.palette.mode === 'dark'
6381
? '0px 4px 4px rgba(255, 255, 255, 0.25)'
6482
: '0px 0px 25px 0px rgba(0, 0, 0, 0.50)',
65-
left: anchorEl?.getBoundingClientRect().right - 260,
83+
left: anchorEl?.getBoundingClientRect().right - dialogLeft,
6684
position: 'absolute',
6785
top: anchorEl?.getBoundingClientRect().bottom - 30
6886
}
@@ -89,3 +107,5 @@ export default function Currency (): React.ReactElement {
89107
</>
90108
);
91109
}
110+
111+
export default React.memo(Currency);

packages/extension-polkagate/src/fullscreen/homeFullScreen/partials/FavoriteChains.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ export default function FavoriteChains (): React.ReactElement {
5050
<Badge
5151
badgeContent={badgeCount}
5252
color='success'
53+
sx={{
54+
'& .MuiBadge-badge': {
55+
color: 'white'
56+
},
57+
}}
5358
>
5459
<Grid
5560
alignItems='center'

packages/extension-polkagate/src/fullscreen/homeFullScreen/partials/ProfileMenu.tsx

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@ const InputBox = ({ addToNewProfile, editName, newName }: InputBoxProps) => {
6060
};
6161

6262
interface AddProfileProps {
63-
address: string | undefined
63+
address: string | undefined;
6464
showName: boolean | undefined;
6565
setShowName: React.Dispatch<React.SetStateAction<boolean | undefined>>;
66-
handleClose: () => void
66+
handleClose: () => void;
67+
closeParentMenu: () => void
68+
extensionMode: boolean;
6769
}
6870

69-
const AddMenu = ({ address, handleClose, setShowName, showName }: AddProfileProps) => {
71+
const AddMenu = ({ address, closeParentMenu, extensionMode, handleClose, setShowName, showName }: AddProfileProps) => {
7072
const theme = useTheme();
7173
const { t } = useTranslation();
7274
const { userDefinedProfiles } = useProfiles();
@@ -103,18 +105,20 @@ const AddMenu = ({ address, handleClose, setShowName, showName }: AddProfileProp
103105
updateMeta(String(address), metaData)
104106
.then(() => {
105107
handleClose();
108+
closeParentMenu();
106109
}).catch(console.error);
107-
}, [account, address, handleClose]);
110+
}, [account, address, closeParentMenu, handleClose]);
108111

109112
return (
110-
<Grid alignItems='flex-start' container display='block' item sx={{ borderRadius: '10px', minWidth: '300px', p: '10px' }}>
113+
<Grid alignItems='flex-start' container display='block' item sx={{ borderRadius: '10px', minWidth: '300px', p: extensionMode ? '5px' : '10px' }}>
111114
{showName
112115
? <InputBox
113116
addToNewProfile={addToNewProfile}
114117
editName={editName}
115118
newName={newName}
116119
/>
117120
: <MenuItem
121+
fontSize={extensionMode ? '16px' : undefined}
118122
iconComponent={
119123
<VaadinIcon icon='vaadin:plus' style={{ color: theme.palette.text.primary, height: '20px' }} />
120124
}
@@ -123,10 +127,11 @@ const AddMenu = ({ address, handleClose, setShowName, showName }: AddProfileProp
123127
withHoverEffect
124128
/>
125129
}
126-
<Divider sx={{ bgcolor: 'divider', height: '1px', my: '6px' }} />
130+
<Divider sx={{ bgcolor: 'divider', height: '1px', my: extensionMode ? '3px' : '6px' }} />
127131
{userDefinedProfiles.length > 0
128132
? userDefinedProfiles.map((profile) => (
129133
<MenuItem
134+
fontSize={extensionMode ? '16px' : undefined}
130135
iconComponent={
131136
<VaadinIcon icon='vaadin:folder-open-o' style={{ color: theme.palette.text.primary, height: '20px' }} />
132137
}
@@ -139,6 +144,7 @@ const AddMenu = ({ address, handleClose, setShowName, showName }: AddProfileProp
139144
))
140145
: <MenuItem
141146
disabled
147+
fontSize={extensionMode ? '16px' : undefined}
142148
iconComponent={
143149
<VaadinIcon icon='vaadin:minus' style={{ color: `${theme.palette.text.disabled}`, height: '20px' }} />
144150
}
@@ -153,18 +159,20 @@ const AddMenu = ({ address, handleClose, setShowName, showName }: AddProfileProp
153159
interface RemoveProfileProps {
154160
profileNames: string[] | undefined;
155161
onRemove: (profile: string) => void;
162+
extensionMode: boolean;
156163
}
157164

158-
const RemoveMenu = ({ onRemove, profileNames }: RemoveProfileProps) => {
165+
const RemoveMenu = ({ extensionMode, onRemove, profileNames }: RemoveProfileProps) => {
159166
const theme = useTheme();
160167
const { t } = useTranslation();
161168

162169
return (
163-
<Grid alignItems='flex-start' container display='block' item sx={{ borderRadius: '10px', minWidth: '300px', p: '10px' }}>
170+
<Grid alignItems='flex-start' container display='block' item sx={{ borderRadius: '10px', minWidth: '300px', p: extensionMode ? '5px' : '10px' }}>
164171
{profileNames?.map((profileName) => (
165172
// eslint-disable-next-line react/jsx-no-bind
166173
<Grid component='button' container item key={profileName} onClick={() => onRemove(profileName)} sx={{ '> div div:last-child p': { maxWidth: '220px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, bgcolor: 'transparent', border: 'none', color: theme.palette.text.primary, height: 'fit-content', p: 0, width: 'inherit' }}>
167174
<MenuItem
175+
fontSize={extensionMode ? '16px' : undefined}
168176
iconComponent={
169177
<VaadinIcon icon='vaadin:folder-remove' style={{ color: theme.palette.text.primary, height: '20px' }} />
170178
}
@@ -206,8 +214,7 @@ function ProfileMenu ({ address, closeParentMenu }: Props): React.ReactElement<P
206214
const handleClose = useCallback(() => {
207215
setAnchorEl(null);
208216
setShowName(false);
209-
closeParentMenu();
210-
}, [closeParentMenu]);
217+
}, []);
211218

212219
const onAddClick = useCallback((event: React.MouseEvent<HTMLButtonElement | HTMLDivElement>) => {
213220
setAnchorEl(event.currentTarget);
@@ -240,14 +247,18 @@ function ProfileMenu ({ address, closeParentMenu }: Props): React.ReactElement<P
240247

241248
if (isLastAccountWithTheProfile && currentProfile === profileToBeRemoved) {
242249
setStorage('profile', PROFILE_TAGS.ALL)
243-
.then(handleClose)
250+
.then(() => {
251+
handleClose();
252+
closeParentMenu();
253+
})
244254
.catch(console.error);
245255
} else {
246256
handleClose();
257+
closeParentMenu();
247258
}
248259
})
249260
.catch(console.error);
250-
}, [profileNames, accounts, address, currentProfile, handleClose]);
261+
}, [address, profileNames, accounts, currentProfile, handleClose, closeParentMenu]);
251262

252263
const open = Boolean(anchorEl);
253264
const id = open ? 'simple-popover 2' : undefined;
@@ -256,6 +267,7 @@ function ProfileMenu ({ address, closeParentMenu }: Props): React.ReactElement<P
256267
<>
257268
<Grid aria-describedby={id} component='button' container item onClick={onAddClick} sx={{ bgcolor: 'transparent', border: 'none', color: theme.palette.text.primary, height: 'fit-content', p: 0, width: 'inherit' }}>
258269
<MenuItem
270+
fontSize={isExtensionMode ? '16px' : undefined}
259271
iconComponent={
260272
<VaadinIcon icon='vaadin:folder-add' style={{ color: `${theme.palette.text.primary}`, height: '20px' }} />
261273
}
@@ -284,6 +296,7 @@ function ProfileMenu ({ address, closeParentMenu }: Props): React.ReactElement<P
284296
{isExtensionMode && profileNames && profileNames.length > 0 &&
285297
<Grid aria-describedby={id} component='button' container item onClick={onRemoveMenuClick} sx={{ bgcolor: 'transparent', border: 'none', color: theme.palette.text.primary, height: 'fit-content', p: 0, width: 'inherit' }}>
286298
<MenuItem
299+
fontSize='16px'
287300
iconComponent={
288301
<VaadinIcon icon='vaadin:folder-remove' style={{ color: theme.palette.text.primary, height: '20px' }} />
289302
}
@@ -293,7 +306,6 @@ function ProfileMenu ({ address, closeParentMenu }: Props): React.ReactElement<P
293306
/>
294307
</Grid>
295308
}
296-
{isExtensionMode && <Divider sx={{ bgcolor: 'divider', height: '1px', my: '6px', width: '100%' }} />}
297309
<Popover
298310
PaperProps={{
299311
sx: {
@@ -322,12 +334,15 @@ function ProfileMenu ({ address, closeParentMenu }: Props): React.ReactElement<P
322334
{status === STATUS.SHOW_ADD &&
323335
<AddMenu
324336
address={address}
337+
closeParentMenu={closeParentMenu}
338+
extensionMode={isExtensionMode}
325339
handleClose={handleClose}
326340
setShowName={setShowName}
327341
showName={showName}
328342
/>}
329343
{status === STATUS.SHOW_REMOVE &&
330344
<RemoveMenu
345+
extensionMode={isExtensionMode}
331346
onRemove={onRemove}
332347
profileNames={profileNames}
333348
/>

packages/extension-polkagate/src/fullscreen/homeFullScreen/partials/TotalBalancePieChart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ function TotalBalancePieChart ({ setGroupedAssets }: Props): React.ReactElement
231231
withCountUp
232232
withSmallDecimal
233233
/>
234-
<Typography sx={{ color: !youHave.change ? 'secondary.contrastText' : youHave.change > 0 ? 'success.main' : 'warning.main', fontSize: '16px', fontWeight: 500 }}>
234+
<Typography sx={{ color: !youHave.change ? 'secondary.contrastText' : youHave.change > 0 ? 'success.contrastText' : 'warning.main', fontSize: '16px', fontWeight: 500 }}>
235235
<CountUp
236236
decimals={countDecimalPlaces(portfolioChange) || PORTFOLIO_CHANGE_DECIMAL}
237237
duration={1}

packages/extension-polkagate/src/hooks/useYouHave.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { amountToHuman } from '../util/utils';
1010
import { usePrices } from '.';
1111

1212
export interface YouHaveType {
13+
available: number;
1314
change: number;
1415
date: number;
1516
portfolio: number;
@@ -45,8 +46,9 @@ export default function useYouHave (): YouHaveType | undefined | null {
4546
return undefined;
4647
}
4748

48-
let totalPrice = 0;
49-
let totalBeforeChange = 0;
49+
let portfolio = 0;
50+
let available = 0;
51+
let change = 0;
5052
const balances = accountsAssets.balances;
5153
const date = Math.min(accountsAssets.timeStamp, pricesInCurrencies.date);
5254

@@ -56,14 +58,16 @@ export default function useYouHave (): YouHaveType | undefined | null {
5658
const tokenValue = pricesInCurrencies.prices[asset.priceId]?.value ?? 0;
5759
const tokenPriceChange = pricesInCurrencies.prices[asset.priceId]?.change ?? 0;
5860
const currentAssetPrice = calcPrice(tokenValue, asset.totalBalance, asset.decimal);
61+
const currentAvailableAssetPrice = calcPrice(tokenValue, asset.availableBalance, asset.decimal);
5962

60-
totalPrice += currentAssetPrice;
61-
totalBeforeChange += calcChange(tokenValue, Number(asset.totalBalance) / (10 ** asset.decimal), tokenPriceChange);
63+
portfolio += currentAssetPrice;
64+
available += currentAvailableAssetPrice;
65+
change += calcChange(tokenValue, Number(asset.totalBalance) / (10 ** asset.decimal), tokenPriceChange);
6266
});
6367
});
6468
});
6569

66-
return { change: totalBeforeChange, date, portfolio: totalPrice } as unknown as YouHaveType;
70+
return { available, change, date, portfolio } as unknown as YouHaveType;
6771
}, [accountsAssets, pricesInCurrencies]);
6872

6973
return youHave;

0 commit comments

Comments
 (0)