Skip to content

Commit d206c68

Browse files
committed
Merge branch 'main' into AssetHubsReservedAmount
2 parents cab37c0 + a6d4f63 commit d206c68

31 files changed

+969
-124
lines changed

packages/extension-base/src/background/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export interface AccountJson extends KeyringPair$Meta {
5454
balances?: string;
5555
identities?: string;
5656
isQR?: boolean;
57+
profile?: string;
5758
stakingAccount?: string;
5859
}
5960

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { getSubstrateAddress, isValidAddress } from '../util/utils';
2121
import { ChainLogo, Identicon, Infotip, ShortAddress } from '.';
2222

2323
interface Props {
24-
accountInfo?: DeriveAccountInfo;
24+
accountInfo?: DeriveAccountInfo | null;
2525
address?: string | AccountId;
2626
api?: ApiPromise;
2727
chain?: Chain;

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
22
// SPDX-License-Identifier: Apache-2.0
3-
// @ts-nocheck
43

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

76
import { ArrowForwardIos as ArrowForwardIosIcon } from '@mui/icons-material';
87
import { Box, Grid, type SxProps, type Theme, Typography } from '@mui/material';
9-
import React, { MouseEventHandler } from 'react';
8+
import React, { type MouseEventHandler } from 'react';
109

1110
import { noop } from '../util/utils';
1211

@@ -17,14 +16,15 @@ interface Props {
1716
text: string;
1817
children?: React.ReactElement<Props>;
1918
onClick?: MouseEventHandler<HTMLDivElement>;
19+
showChevron?: boolean;
2020
showSubMenu?: boolean;
2121
py?: string;
2222
fontSize?: string;
2323
pl?: string;
2424
withHoverEffect?: boolean;
2525
}
2626

27-
export default function MenuItem({ children, disabled = false, fontSize, icon, iconComponent, onClick, pl = '0', py = '8px', showSubMenu = false, text, withHoverEffect }: Props): React.ReactElement<Props> {
27+
export default function MenuItem({ children, disabled = false, fontSize, icon, iconComponent, onClick, pl = '0', py = '8px',showChevron, showSubMenu = false, text, withHoverEffect }: Props): React.ReactElement<Props> {
2828
const hoverEffectStyles: SxProps<Theme> = {
2929
'&:hover': { bgcolor: disabled ? 'none' : 'divider' },
3030
borderRadius: '5px',
@@ -57,8 +57,8 @@ export default function MenuItem({ children, disabled = false, fontSize, icon, i
5757
</Typography>
5858
</Grid>
5959
</Grid>
60-
<Grid alignItems='center' container item sx={{ display: children ? 'inherit' : 'none' }} xs={1}>
61-
<ArrowForwardIosIcon sx={{ color: 'secondary.light', fontSize: 18, m: 'auto', stroke: '#BA2882', strokeWidth: '2px', transform: showSubMenu ? 'rotate(-90deg)' : 'rotate(90deg)', transitionDuration: '0.3s', transitionProperty: 'transform' }} />
60+
<Grid alignItems='center' container item sx={{ display: children || showChevron ? 'inherit' : 'none' }} xs={1}>
61+
<ArrowForwardIosIcon sx={{ color: 'secondary.light', fontSize: 18, m: 'auto', stroke: '#BA2882', strokeWidth: '2px', transform: showChevron ? 'none' : (showSubMenu ? 'rotate(-90deg)' : 'rotate(90deg)'), transitionDuration: '0.3s', transitionProperty: 'transform' }} />
6262
</Grid>
6363
</Grid>
6464
{
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import { Autocomplete, Grid, type SxProps, TextField, type Theme, Typography } from '@mui/material';
5+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
6+
7+
import Label from './Label';
8+
import { useProfiles } from '../hooks';
9+
10+
interface Props {
11+
disabled?: boolean;
12+
helperText?: string;
13+
label: string;
14+
placeHolder?: string;
15+
profileName: string | undefined;
16+
setProfileName: React.Dispatch<React.SetStateAction<string | undefined>>;
17+
style?: SxProps<Theme>;
18+
}
19+
20+
export default function ProfileInput({ disabled = false, placeHolder = '', setProfileName, profileName, helperText = '', label, style }: Props): React.ReactElement<Props> {
21+
const containerRef = useRef<HTMLDivElement>(null);
22+
23+
const { userDefinedProfiles } = useProfiles();
24+
25+
const [isPopperOpen, setTogglePopper] = useState<boolean>(false);
26+
const [focus, setFocus] = useState<boolean>(false);
27+
const [enteredProfile, setEnteredProfile] = useState<string | undefined>();
28+
const [dropdownWidth, setDropdownWidth] = useState<string>('0');
29+
30+
const autocompleteOptions = useMemo(() => userDefinedProfiles.map((profile, index) => ({ index, profile })), [userDefinedProfiles, userDefinedProfiles.length]);
31+
32+
useEffect(() => {
33+
profileName && setEnteredProfile(profileName);
34+
}, [profileName]);
35+
36+
useEffect(() => {
37+
if (containerRef) {
38+
setDropdownWidth(`${(containerRef.current?.offsetWidth || 0)}px`);
39+
}
40+
}, [containerRef?.current?.offsetWidth]);
41+
42+
const handleProfile = useCallback((value?: string): void => {
43+
setTogglePopper(false);
44+
45+
if (!value) {
46+
setProfileName(undefined);
47+
setEnteredProfile(undefined);
48+
49+
return;
50+
}
51+
52+
setEnteredProfile(value);
53+
setProfileName(value)
54+
}, [setProfileName]);
55+
56+
const openPopper = useCallback(() =>
57+
userDefinedProfiles.length > 0 && !enteredProfile && !isPopperOpen && setTogglePopper(true)
58+
, [userDefinedProfiles.length, enteredProfile, isPopperOpen]);
59+
60+
const closePopper = useCallback(() =>
61+
setTogglePopper(false),
62+
[]);
63+
64+
return (
65+
<Grid alignItems='flex-end' container justifyContent='space-between' ref={containerRef} sx={{ position: 'relative', ...style }}>
66+
<Label
67+
helperText={helperText}
68+
label={label}
69+
style={{ position: 'relative', width: '100%' }}
70+
>
71+
<Autocomplete
72+
componentsProps={{ paper: { sx: { '> ul': { m: 0, p: 0 }, border: '2px solid', borderColor: 'secondary.light', maxHeight: window.innerHeight / 2, ml: '-1px', my: '5px', p: 0, width: dropdownWidth } } }}
73+
disableClearable
74+
disabled={disabled || !autocompleteOptions}
75+
freeSolo
76+
getOptionLabel={(option) => option?.toString() as any}
77+
inputValue={enteredProfile ?? ''}
78+
onBlur={() => setFocus(false)}
79+
onClose={closePopper}
80+
onFocus={() => setFocus(true)}
81+
onOpen={openPopper}
82+
open={isPopperOpen && !enteredProfile}
83+
options={autocompleteOptions as any}
84+
renderInput={(params) => (
85+
<TextField
86+
{...params}
87+
InputProps={{
88+
...params.InputProps,
89+
}}
90+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => handleProfile(event.target.value)}
91+
placeholder={placeHolder}
92+
sx={{ '> div.MuiOutlinedInput-root': { '> fieldset': { border: 'none' }, '> input.MuiAutocomplete-input': { border: 'none', lineHeight: '31px', p: 0 }, border: 'none', height: '31px', p: 0, px: '5px' }, bgcolor: 'background.paper', border: `${focus ? '2px' : '1px'} solid`, borderColor: `${focus ? 'action.focus' : 'secondary.light'}`, borderRadius: '5px', height: '32px', lineHeight: '31px' }}
93+
/>
94+
)}
95+
// @ts-ignore
96+
renderOption={(_props, { index, profile }) => {
97+
return (
98+
<Grid alignItems='center' container item justifyContent='space-between' key={index} onClick={() => handleProfile(profile)} sx={{ '&:not(:last-child)': { borderBottom: '1px solid', borderBottomColor: 'secondary.light', mb: '5px' }, cursor: 'pointer', p: '5px' }}>
99+
<Typography fontSize='12px' fontWeight={400} lineHeight='25px' overflow='hidden' textOverflow='ellipsis' whiteSpace='nowrap'>
100+
{profile}
101+
</Typography>
102+
</Grid>);
103+
}}
104+
sx={{ border: 'none', height: '31px', p: 0 }}
105+
/>
106+
</Label>
107+
</Grid>
108+
);
109+
}

packages/extension-polkagate/src/components/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
22
// SPDX-License-Identifier: Apache-2.0
3-
// @ts-nocheck
4-
/* eslint-disable header/header */
53

64
export { default as AccountNamePasswordCreation } from './AccountNamePasswordCreation';
75
export { default as AccountHolderWithProxy } from './AccountHolderWithProxy';
@@ -95,5 +93,6 @@ export { default as FullScreenIcon } from './FullScreenIcon';
9593
export { default as OptionalCopyButton } from './OptionalCopyButton';
9694
export { default as Waiting } from './Waiting';
9795
export { default as VaadinIcon } from './VaadinIcon';
96+
export { default as ProfileInput } from './ProfileInput';
9897

9998
export * from './contexts';

packages/extension-polkagate/src/fullscreen/accountDetails/components/AccountIconsFs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { IDENTITY_CHAINS, PROXY_CHAINS, SOCIAL_RECOVERY_CHAINS } from '../../../
2020

2121
interface AddressDetailsProps {
2222
address: string | undefined;
23-
accountInfo: DeriveAccountInfo | undefined
23+
accountInfo: DeriveAccountInfo | undefined | null
2424
}
2525

2626
export default function AccountIconsFs({ accountInfo, address }: AddressDetailsProps): React.ReactElement {

packages/extension-polkagate/src/fullscreen/accountDetails/components/AccountInformationForDetails.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
22
// SPDX-License-Identifier: Apache-2.0
3-
// @ts-nocheck
43

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

@@ -11,7 +10,7 @@ import { BN } from '@polkadot/util';
1110

1211
import { DisplayLogo, FormatBalance2, FormatPrice, Identicon, Identity, Infotip, Infotip2, OptionalCopyButton, ShortAddress2, VaadinIcon } from '../../../components';
1312
import { useIdentity, useInfo, useTranslation } from '../../../hooks';
14-
import { FetchedBalance } from '../../../hooks/useAssetsBalances';
13+
import type { FetchedBalance } from '../../../hooks/useAssetsBalances';
1514
import { showAccount, tieAccount } from '../../../messaging';
1615
import { getValue } from '../../../popup/account/util';
1716
import { BALANCES_VALIDITY_PERIOD } from '../../../util/constants';
@@ -129,9 +128,21 @@ interface AddressDetailsProps {
129128
setAssetIdOnAssetHub: React.Dispatch<React.SetStateAction<number | undefined>>;
130129
}
131130

132-
export default function AccountInformationForDetails({ accountAssets, address, label, price, pricesInCurrency, selectedAsset, setAssetIdOnAssetHub, setSelectedAsset }: AddressDetailsProps): React.ReactElement {
131+
export const EyeIconFullScreen = ({ isHidden, onClick }: { isHidden: boolean | undefined, onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined }) => {
133132
const { t } = useTranslation();
134133
const theme = useTheme();
134+
135+
return (
136+
<Infotip text={isHidden ? t('This account is hidden from websites') : t('This account is visible to websites')}>
137+
<IconButton onClick={onClick} sx={{ height: '20px', ml: '7px', mt: '13px', p: 0, width: '28px' }}>
138+
<VaadinIcon icon={isHidden ? 'vaadin:eye-slash' : 'vaadin:eye'} style={{ color: `${theme.palette.secondary.light}`, height: '20px' }} />
139+
</IconButton>
140+
</Infotip>
141+
)
142+
}
143+
144+
export default function AccountInformationForDetails({ accountAssets, address, label, price, pricesInCurrency, selectedAsset, setAssetIdOnAssetHub, setSelectedAsset }: AddressDetailsProps): React.ReactElement {
145+
const theme = useTheme();
135146
const { account, api, chain, formatted, genesisHash, token } = useInfo(address);
136147

137148
const accountInfo = useIdentity(genesisHash, formatted);
@@ -160,7 +171,7 @@ export default function AccountInformationForDetails({ accountAssets, address, l
160171
if (!sortedAccountAssets) {
161172
return sortedAccountAssets; // null or undefined!
162173
} else {
163-
return sortedAccountAssets.filter((_asset) => !getValue('total', _asset)?.isZero());
174+
return sortedAccountAssets.filter((_asset) => !getValue('total', _asset as unknown as BalancesInfo)?.isZero());
164175
}
165176
}, [sortedAccountAssets]);
166177

@@ -217,11 +228,10 @@ export default function AccountInformationForDetails({ accountAssets, address, l
217228
// subIdOnly
218229
/>
219230
<Grid item width='40px'>
220-
<Infotip text={account?.isHidden && t('This account is hidden from websites')}>
221-
<IconButton onClick={toggleVisibility} sx={{ height: '20px', ml: '7px', mt: '13px', p: 0, width: '28px' }}>
222-
<VaadinIcon icon={account?.isHidden ? 'vaadin:eye-slash' : 'vaadin:eye'} style={{ color: `${theme.palette.secondary.light}`, height: '20px' }} />
223-
</IconButton>
224-
</Infotip>
231+
<EyeIconFullScreen
232+
isHidden={account?.isHidden}
233+
onClick={toggleVisibility}
234+
/>
225235
</Grid>
226236
</Grid>
227237
<Grid alignItems='center' container item>
@@ -234,7 +244,7 @@ export default function AccountInformationForDetails({ accountAssets, address, l
234244
</Grid>
235245
</Grid>
236246
<SelectedAssetBox
237-
balanceToShow={selectedAsset}
247+
balanceToShow={selectedAsset as unknown as BalancesInfo}
238248
genesisHash={genesisHash}
239249
isBalanceOutdated={isBalanceOutdated}
240250
isPriceOutdated={!!isPriceOutdated}

packages/extension-polkagate/src/fullscreen/accountDetails/components/TotalChart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export default function TotalChart({ accountAssets, pricesInCurrency }: Props):
113113
return () => {
114114
chartInstance.destroy();
115115
};
116-
}, [assets, theme.palette.divider]);
116+
}, [assets?.length, theme.palette.divider]);
117117

118118
return (
119119
<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' }}>

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ import ReservedDisplayBalance from './components/ReservedDisplayBalance';
3232
import LockedInReferenda from './unlock/Review';
3333
import { AccountInformationForDetails, AccountSetting, AssetSelect, CommonTasks, DisplayBalance, ExternalLinks, LockedBalanceDisplay, TotalChart } from './components';
3434

35-
export const popupNumbers = {
36-
LOCKED_IN_REFERENDA: 1,
37-
FORGET_ACCOUNT: 2,
38-
RENAME: 3,
39-
EXPORT_ACCOUNT: 4,
40-
DERIVE_ACCOUNT: 5,
41-
RECEIVE: 6,
42-
HISTORY: 7
35+
export enum popupNumbers {
36+
LOCKED_IN_REFERENDA,
37+
FORGET_ACCOUNT,
38+
RENAME,
39+
EXPORT_ACCOUNT,
40+
DERIVE_ACCOUNT,
41+
RECEIVE,
42+
HISTORY
4343
};
4444

4545
export interface UnlockInformationType {

0 commit comments

Comments
 (0)