Skip to content

Commit

Permalink
feat: sort the already authorized accounts to the bottom of the list …
Browse files Browse the repository at this point in the history
…to easier auth the unauthorized accounts (#1662)
  • Loading branch information
AMIRKHANEF authored Nov 17, 2024
1 parent d5a6bfa commit 8f0fc1d
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 112 deletions.
41 changes: 35 additions & 6 deletions packages/extension-polkagate/src/components/AccountsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

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

import type { AccountJson } from '@polkadot/extension-base/background/types';

import { Grid, type SxProps, type Theme, Typography, useTheme } from '@mui/material';
import React, { useCallback, useContext, useMemo } from 'react';
import React, { useCallback, useContext, useMemo, useRef } from 'react';

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

export default function AccountsTable ({ accountTypeFilter, areAllCheck, label, maxHeight = '112px', selectedAccounts, setSelectedAccounts, style }: Props): React.ReactElement<Props> {
const sortAccounts = (accountA: AccountJson, accountB: AccountJson, selectedList: string[]): number => {
const isASelected = selectedList.includes(accountA.address);
const isBSelected = selectedList.includes(accountB.address);

if (!isASelected && isBSelected) {
return -1;
} else if (isASelected && !isBSelected) {
return 1;
}

return 0;
};

function AccountsTable ({ accountTypeFilter, areAllCheck, label, manageConnectedAccounts, maxHeight = '112px', selectedAccounts, setSelectedAccounts, style }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const theme = useTheme();
const { accounts } = useContext(AccountContext);

// Sort only on the first render, store result in a ref
const sortedAccountsRef = useRef<AccountJson[] | null>(null);

const accountsToShow = useMemo(() => {
const filtered = accounts.filter(({ isExternal, isHardware, isHidden, isQR }) =>
const filtered = [...accounts].filter(({ isExternal, isHardware, isHidden, isQR }) =>
(accountTypeFilter?.includes('Watch-Only') && !isExternal) ||
(accountTypeFilter?.includes('Hardware') && !isHardware) ||
(accountTypeFilter?.includes('QR') && !isQR) ||
!isHidden
);

return filtered;
}, [accountTypeFilter, accounts]);
// Only sort accounts when:
// 1. We're in manage authorized accounts mode (manageConnectedAccounts is true)
// 2. The accounts haven't been sorted yet (sortedAccountsRef.current is null)
// 3. There are some selected accounts (selectedAccounts.length !== 0)
if (manageConnectedAccounts && !sortedAccountsRef.current && selectedAccounts.length !== 0) {
sortedAccountsRef.current = [...filtered].sort((a, b) => sortAccounts(a, b, selectedAccounts));
}

return filtered; // .sort((a, b) => sortAccounts(a, b, selectedAccounts))
}, [accountTypeFilter, accounts, manageConnectedAccounts, selectedAccounts]);

const onCheck = useCallback((address: string) => {
const isAlreadySelected = selectedAccounts.includes(address);
Expand Down Expand Up @@ -106,7 +133,7 @@ export default function AccountsTable ({ accountTypeFilter, areAllCheck, label,
/>
</Grid>
}
{accountsToShow.map(({ address }, index) => (
{(sortedAccountsRef.current ?? accountsToShow).map(({ address }, index) => (
<Grid container item key={index} sx={{ '> div:not(:last-child)': { borderRight: '1px solid', borderRightColor: 'secondary.light' }, height: '37px', textAlign: 'center' }} xs={12}>
<Grid alignItems='center' container item justifyContent='left' pl='15px' xs={8}>
<Identity address={address} identiconSize={25} showShortAddress showSocial={false} style={{ fontSize: '14px' }} subIdOnly />
Expand All @@ -130,3 +157,5 @@ export default function AccountsTable ({ accountTypeFilter, areAllCheck, label,
</Grid>
);
}

export default React.memo(AccountsTable);
20 changes: 7 additions & 13 deletions packages/extension-polkagate/src/partials/ConnectedDappIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Avatar } from '@mui/material';
import React, { useCallback, useContext, useEffect, useState } from 'react';

import { ActionContext } from '../components';
import { useAnimateOnce } from '../hooks';
import { getAuthList } from '../messaging';
import { extractBaseUrl } from '../util/utils';

Expand All @@ -22,7 +23,8 @@ export default function ConnectedDappIcon (): React.ReactElement {
const [isConnected, setIsConnected] = useState<boolean | undefined>(undefined);
const [favIconUrl, setFavIconUrl] = useState<string | undefined>(undefined);
const [dappId, setDappId] = useState<string | undefined>(undefined);
const [flip, setFlip] = useState(false);

const flip = useAnimateOnce(Boolean(favIconUrl), { delay: 1000, duration: 1000 });

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

Expand Down Expand Up @@ -55,15 +57,6 @@ export default function ConnectedDappIcon (): React.ReactElement {
}
}, []);

useEffect(() => {
if (!favIconUrl) {
return;
}

setFlip(true);
setTimeout(() => setFlip(false), 1000);
}, [favIconUrl]);

useEffect(() => {
if (isOnHomePage && isConnected === undefined && !checking && favIconUrl === undefined) {
checkTab().catch(console.error);
Expand All @@ -84,14 +77,15 @@ export default function ConnectedDappIcon (): React.ReactElement {
src={favIconUrl}
sx={{
borderRadius: '50%',
bottom: 5,
cursor: 'pointer',
height: '15px',
position: 'absolute',
right: 10,
right: '44%',
top: 6,
transform: flip ? 'rotateY(180deg)' : 'rotateY(0deg)',
transition: 'transform 1s',
width: '15px'
width: '15px',
zIndex: 10
}}
variant='circular'
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ export default function ManageAuthorizedAccounts ({ info, onBackClick }: Props):
</Grid>
<AccountsTable
areAllCheck={areAllCheck}
manageConnectedAccounts
maxHeight={window.innerHeight - 300}
selectedAccounts={selectedAccounts}
setSelectedAccounts={setSelectedAccounts}
style={{ margin: '35px auto 0', width: '92%' }}
style={{ margin: '25px auto 0', width: '92%' }}
/>
<TwoButtons
disabled={noChanges}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface Props {
backToAccountFS?: () => void | undefined;
}

export default function ManageAuthorizedDapps({ backToAccountFS, setDappInfo }: Props): React.ReactElement {
export default function ManageAuthorizedDapps ({ backToAccountFS, setDappInfo }: Props): React.ReactElement {
const isExtensionMode = useIsExtensionPopup();
const { t } = useTranslation();
const theme = useTheme();
Expand Down
19 changes: 10 additions & 9 deletions packages/extension-polkagate/src/popup/authManagement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface FSModeType {
open: boolean;
}

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

return (
Expand All @@ -53,9 +53,9 @@ const ExtensionMode = ({ dappInfo, onBackClick, setDappInfo }: ExtensionModeType
}
</>
);
};
});

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

return (
Expand All @@ -73,9 +73,9 @@ const FSMode = ({ backToAccountFS, dappInfo, onBackClick, open, setDappInfo }: F
</Grid>
</DraggableModal>
);
};
});

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

return (
<>
{
isExtensionMode
? <ExtensionMode dappInfo={dappInfo} onBackClick={onBackClick} setDappInfo={setDappInfo} />
: <FSMode backToAccountFS={backToAccountFS} dappInfo={dappInfo} onBackClick={onBackClick} open={!!open} setDappInfo={setDappInfo} />
{isExtensionMode
? <ExtensionMode dappInfo={dappInfo} onBackClick={onBackClick} setDappInfo={setDappInfo} />
: <FSMode backToAccountFS={backToAccountFS} dappInfo={dappInfo} onBackClick={onBackClick} open={!!open} setDappInfo={setDappInfo} />
}
</>
);
}

export default React.memo(AuthManagement);
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export default function Request ({ authRequest, hasBanner }: Props): React.React
</Grid>
<AccountsTable
areAllCheck={areAllCheck}
manageConnectedAccounts={alreadySelectedAccounts.length > 0}
maxHeight={hasBanner ? '150px' : '170px'}
selectedAccounts={selectedAccounts}
setSelectedAccounts={setSelectedAccounts}
Expand Down
Loading

0 comments on commit 8f0fc1d

Please sign in to comment.