Skip to content

Commit 8f0fc1d

Browse files
authored
feat: sort the already authorized accounts to the bottom of the list to easier auth the unauthorized accounts (#1662)
1 parent d5a6bfa commit 8f0fc1d

File tree

7 files changed

+137
-112
lines changed

7 files changed

+137
-112
lines changed

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

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

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

6+
import type { AccountJson } from '@polkadot/extension-base/background/types';
7+
68
import { Grid, type SxProps, type Theme, Typography, useTheme } from '@mui/material';
7-
import React, { useCallback, useContext, useMemo } from 'react';
9+
import React, { useCallback, useContext, useMemo, useRef } from 'react';
810

911
import { openOrFocusTab } from '../fullscreen/accountDetails/components/CommonTasks';
1012
import { useTranslation } from '../hooks';
@@ -22,23 +24,48 @@ interface Props {
2224
accountTypeFilter?: AccountTypeFilterType;
2325
selectedAccounts: string[];
2426
setSelectedAccounts: React.Dispatch<React.SetStateAction<string[]>>;
27+
manageConnectedAccounts?: boolean;
2528
}
2629

27-
export default function AccountsTable ({ accountTypeFilter, areAllCheck, label, maxHeight = '112px', selectedAccounts, setSelectedAccounts, style }: Props): React.ReactElement<Props> {
30+
const sortAccounts = (accountA: AccountJson, accountB: AccountJson, selectedList: string[]): number => {
31+
const isASelected = selectedList.includes(accountA.address);
32+
const isBSelected = selectedList.includes(accountB.address);
33+
34+
if (!isASelected && isBSelected) {
35+
return -1;
36+
} else if (isASelected && !isBSelected) {
37+
return 1;
38+
}
39+
40+
return 0;
41+
};
42+
43+
function AccountsTable ({ accountTypeFilter, areAllCheck, label, manageConnectedAccounts, maxHeight = '112px', selectedAccounts, setSelectedAccounts, style }: Props): React.ReactElement<Props> {
2844
const { t } = useTranslation();
2945
const theme = useTheme();
3046
const { accounts } = useContext(AccountContext);
3147

48+
// Sort only on the first render, store result in a ref
49+
const sortedAccountsRef = useRef<AccountJson[] | null>(null);
50+
3251
const accountsToShow = useMemo(() => {
33-
const filtered = accounts.filter(({ isExternal, isHardware, isHidden, isQR }) =>
52+
const filtered = [...accounts].filter(({ isExternal, isHardware, isHidden, isQR }) =>
3453
(accountTypeFilter?.includes('Watch-Only') && !isExternal) ||
3554
(accountTypeFilter?.includes('Hardware') && !isHardware) ||
3655
(accountTypeFilter?.includes('QR') && !isQR) ||
3756
!isHidden
3857
);
3958

40-
return filtered;
41-
}, [accountTypeFilter, accounts]);
59+
// Only sort accounts when:
60+
// 1. We're in manage authorized accounts mode (manageConnectedAccounts is true)
61+
// 2. The accounts haven't been sorted yet (sortedAccountsRef.current is null)
62+
// 3. There are some selected accounts (selectedAccounts.length !== 0)
63+
if (manageConnectedAccounts && !sortedAccountsRef.current && selectedAccounts.length !== 0) {
64+
sortedAccountsRef.current = [...filtered].sort((a, b) => sortAccounts(a, b, selectedAccounts));
65+
}
66+
67+
return filtered; // .sort((a, b) => sortAccounts(a, b, selectedAccounts))
68+
}, [accountTypeFilter, accounts, manageConnectedAccounts, selectedAccounts]);
4269

4370
const onCheck = useCallback((address: string) => {
4471
const isAlreadySelected = selectedAccounts.includes(address);
@@ -106,7 +133,7 @@ export default function AccountsTable ({ accountTypeFilter, areAllCheck, label,
106133
/>
107134
</Grid>
108135
}
109-
{accountsToShow.map(({ address }, index) => (
136+
{(sortedAccountsRef.current ?? accountsToShow).map(({ address }, index) => (
110137
<Grid container item key={index} sx={{ '> div:not(:last-child)': { borderRight: '1px solid', borderRightColor: 'secondary.light' }, height: '37px', textAlign: 'center' }} xs={12}>
111138
<Grid alignItems='center' container item justifyContent='left' pl='15px' xs={8}>
112139
<Identity address={address} identiconSize={25} showShortAddress showSocial={false} style={{ fontSize: '14px' }} subIdOnly />
@@ -130,3 +157,5 @@ export default function AccountsTable ({ accountTypeFilter, areAllCheck, label,
130157
</Grid>
131158
);
132159
}
160+
161+
export default React.memo(AccountsTable);

packages/extension-polkagate/src/partials/ConnectedDappIcon.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Avatar } from '@mui/material';
77
import React, { useCallback, useContext, useEffect, useState } from 'react';
88

99
import { ActionContext } from '../components';
10+
import { useAnimateOnce } from '../hooks';
1011
import { getAuthList } from '../messaging';
1112
import { extractBaseUrl } from '../util/utils';
1213

@@ -22,7 +23,8 @@ export default function ConnectedDappIcon (): React.ReactElement {
2223
const [isConnected, setIsConnected] = useState<boolean | undefined>(undefined);
2324
const [favIconUrl, setFavIconUrl] = useState<string | undefined>(undefined);
2425
const [dappId, setDappId] = useState<string | undefined>(undefined);
25-
const [flip, setFlip] = useState(false);
26+
27+
const flip = useAnimateOnce(Boolean(favIconUrl), { delay: 1000, duration: 1000 });
2628

2729
const isOnHomePage = window.location.hash === '#/';
2830

@@ -55,15 +57,6 @@ export default function ConnectedDappIcon (): React.ReactElement {
5557
}
5658
}, []);
5759

58-
useEffect(() => {
59-
if (!favIconUrl) {
60-
return;
61-
}
62-
63-
setFlip(true);
64-
setTimeout(() => setFlip(false), 1000);
65-
}, [favIconUrl]);
66-
6760
useEffect(() => {
6861
if (isOnHomePage && isConnected === undefined && !checking && favIconUrl === undefined) {
6962
checkTab().catch(console.error);
@@ -84,14 +77,15 @@ export default function ConnectedDappIcon (): React.ReactElement {
8477
src={favIconUrl}
8578
sx={{
8679
borderRadius: '50%',
87-
bottom: 5,
8880
cursor: 'pointer',
8981
height: '15px',
9082
position: 'absolute',
91-
right: 10,
83+
right: '44%',
84+
top: 6,
9285
transform: flip ? 'rotateY(180deg)' : 'rotateY(0deg)',
9386
transition: 'transform 1s',
94-
width: '15px'
87+
width: '15px',
88+
zIndex: 10
9589
}}
9690
variant='circular'
9791
/>

packages/extension-polkagate/src/popup/authManagement/ManageAuthorizedAccounts.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ export default function ManageAuthorizedAccounts ({ info, onBackClick }: Props):
5353
</Grid>
5454
<AccountsTable
5555
areAllCheck={areAllCheck}
56+
manageConnectedAccounts
5657
maxHeight={window.innerHeight - 300}
5758
selectedAccounts={selectedAccounts}
5859
setSelectedAccounts={setSelectedAccounts}
59-
style={{ margin: '35px auto 0', width: '92%' }}
60+
style={{ margin: '25px auto 0', width: '92%' }}
6061
/>
6162
<TwoButtons
6263
disabled={noChanges}

packages/extension-polkagate/src/popup/authManagement/ManageAuthorizedDapps.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ interface Props {
2121
backToAccountFS?: () => void | undefined;
2222
}
2323

24-
export default function ManageAuthorizedDapps({ backToAccountFS, setDappInfo }: Props): React.ReactElement {
24+
export default function ManageAuthorizedDapps ({ backToAccountFS, setDappInfo }: Props): React.ReactElement {
2525
const isExtensionMode = useIsExtensionPopup();
2626
const { t } = useTranslation();
2727
const theme = useTheme();

packages/extension-polkagate/src/popup/authManagement/index.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ interface FSModeType {
3737
open: boolean;
3838
}
3939

40-
const ExtensionMode = ({ dappInfo, onBackClick, setDappInfo }: ExtensionModeType) => {
40+
const ExtensionMode = React.memo(function ExtensionMode ({ dappInfo, onBackClick, setDappInfo }: ExtensionModeType) {
4141
const { t } = useTranslation();
4242

4343
return (
@@ -53,9 +53,9 @@ const ExtensionMode = ({ dappInfo, onBackClick, setDappInfo }: ExtensionModeType
5353
}
5454
</>
5555
);
56-
};
56+
});
5757

58-
const FSMode = ({ backToAccountFS, dappInfo, onBackClick, open, setDappInfo }: FSModeType) => {
58+
const FSMode = React.memo(function FSMode ({ backToAccountFS, dappInfo, onBackClick, open, setDappInfo }: FSModeType) {
5959
const { t } = useTranslation();
6060

6161
return (
@@ -73,9 +73,9 @@ const FSMode = ({ backToAccountFS, dappInfo, onBackClick, open, setDappInfo }: F
7373
</Grid>
7474
</DraggableModal>
7575
);
76-
};
76+
});
7777

78-
export default function AuthManagement ({ open, setDisplayPopup }: Props): React.ReactElement {
78+
function AuthManagement ({ open, setDisplayPopup }: Props): React.ReactElement {
7979
const onAction = useContext(ActionContext);
8080
const isExtensionMode = useIsExtensionPopup();
8181
const { id: dappId } = useParams<{ id: string | undefined }>();
@@ -104,11 +104,12 @@ export default function AuthManagement ({ open, setDisplayPopup }: Props): React
104104

105105
return (
106106
<>
107-
{
108-
isExtensionMode
109-
? <ExtensionMode dappInfo={dappInfo} onBackClick={onBackClick} setDappInfo={setDappInfo} />
110-
: <FSMode backToAccountFS={backToAccountFS} dappInfo={dappInfo} onBackClick={onBackClick} open={!!open} setDappInfo={setDappInfo} />
107+
{isExtensionMode
108+
? <ExtensionMode dappInfo={dappInfo} onBackClick={onBackClick} setDappInfo={setDappInfo} />
109+
: <FSMode backToAccountFS={backToAccountFS} dappInfo={dappInfo} onBackClick={onBackClick} open={!!open} setDappInfo={setDappInfo} />
111110
}
112111
</>
113112
);
114113
}
114+
115+
export default React.memo(AuthManagement);

packages/extension-polkagate/src/popup/authorize/Request.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export default function Request ({ authRequest, hasBanner }: Props): React.React
8686
</Grid>
8787
<AccountsTable
8888
areAllCheck={areAllCheck}
89+
manageConnectedAccounts={alreadySelectedAccounts.length > 0}
8990
maxHeight={hasBanner ? '150px' : '170px'}
9091
selectedAccounts={selectedAccounts}
9192
setSelectedAccounts={setSelectedAccounts}

0 commit comments

Comments
 (0)