Skip to content

Commit

Permalink
[UI] Update account detail navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
lw committed May 28, 2024
1 parent 0a02ee6 commit 48cb1cb
Showing 1 changed file with 25 additions and 265 deletions.
Original file line number Diff line number Diff line change
@@ -1,48 +1,38 @@
// Copyright 2019-2022 @subwallet/extension-koni-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { AccountJson, CurrentAccountInfo } from '@subwallet/extension-base/background/types';
import { SimpleQrModal } from '@subwallet/extension-koni-ui/components/Modal';
import { BookaSdk } from '@subwallet/extension-koni-ui/connector/booka/sdk';
import { DISCONNECT_EXTENSION_MODAL, SELECT_ACCOUNT_MODAL, smallRankIconMap } from '@subwallet/extension-koni-ui/constants';
import { useDefaultNavigate, useGoBackSelectAccount, useNotification, useTranslation } from '@subwallet/extension-koni-ui/hooks';
import { saveCurrentAccountAddress } from '@subwallet/extension-koni-ui/messaging';
import { smallRankIconMap } from '@subwallet/extension-koni-ui/constants';
import { useNotification, useTranslation } from '@subwallet/extension-koni-ui/hooks';
import { RootState } from '@subwallet/extension-koni-ui/stores';
import { Theme } from '@subwallet/extension-koni-ui/themes';
import { ThemeProps } from '@subwallet/extension-koni-ui/types';
import { copyToClipboard, findAccountByAddress, funcSortByName, isAccountAll, searchAccountFunction } from '@subwallet/extension-koni-ui/utils';
import { Button, Icon, Image, ModalContext, SelectModal } from '@subwallet/react-ui';
import { copyToClipboard } from '@subwallet/extension-koni-ui/utils';
import { Button, Icon, Image } from '@subwallet/react-ui';
import CN from 'classnames';
import { Copy } from 'phosphor-react';
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { useLocation, useNavigate } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';

import { AccountBriefInfo, AccountCardItem, AccountItemWithName } from '../../../Account';
import { GeneralEmptyList } from '../../../EmptyList';
import { AccountBriefInfo } from '../../../Account';

type Props = ThemeProps

const renderEmpty = () => <GeneralEmptyList />;

const modalId = SELECT_ACCOUNT_MODAL;
const simpleQrModalId = 'simple-qr-modal-id';
type Props = ThemeProps;
const apiSDK = BookaSdk.instance;

function Component ({ className }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { activeModal, inactiveModal } = useContext(ModalContext);
const navigate = useNavigate();
const location = useLocation();
const { goHome } = useDefaultNavigate();
const notify = useNotification();
const navigate = useNavigate();

const [gameAccount, setGameAccount] = useState(apiSDK.account);

const { accounts: _accounts, currentAccount } = useSelector((state: RootState) => state.accountState);
const { currentAccount } = useSelector((state: RootState) => state.accountState);

const [selectedQrAddress, setSelectedQrAddress] = useState<string | undefined>();
const onClickAccount = useCallback(() => {
navigate(`/accounts/detail/${currentAccount?.address || ''}`);
}, [currentAccount?.address, navigate]);

useEffect(() => {
const accountSub = apiSDK.subscribeAccount().subscribe((data) => {
Expand All @@ -54,147 +44,13 @@ function Component ({ className }: Props): React.ReactElement<Props> {
};
}, []);

const accounts = useMemo((): AccountJson[] => {
const result = [..._accounts].sort(funcSortByName);
const all = result.find((acc) => isAccountAll(acc.address));

if (all) {
const index = result.indexOf(all);

result.splice(index, 1);
result.unshift(all);
}

if (!!currentAccount?.address && (currentAccount?.address !== (all && all.address))) {
const currentAccountIndex = result.findIndex((item) => {
return item.address === currentAccount?.address;
});

if (currentAccountIndex > -1) {
const _currentAccount = result[currentAccountIndex];

result.splice(currentAccountIndex, 1);
result.splice(1, 0, _currentAccount);
}
}

return result;
}, [_accounts, currentAccount?.address]);

const noAllAccounts = useMemo(() => {
return accounts.filter(({ address }) => !isAccountAll(address));
}, [accounts]);

const showAllAccount = useMemo(() => {
return noAllAccounts.length > 1;
}, [noAllAccounts]);

const _onSelect = useCallback((address: string) => {
if (address) {
const accountByAddress = findAccountByAddress(accounts, address);

if (accountByAddress) {
const accountInfo = {
address: address
} as CurrentAccountInfo;

saveCurrentAccountAddress(accountInfo).then(() => {
const pathName = location.pathname;
const locationPaths = location.pathname.split('/');

if (locationPaths) {
if (locationPaths[1] === 'home') {
if (locationPaths.length >= 3) {
if (pathName.startsWith('/home/nfts')) {
navigate('/home/nfts/collections');
} else if (pathName.startsWith('/home/tokens/detail')) {
navigate('/home/tokens');
} else {
navigate(`/home/${locationPaths[2]}`);
}
}
} else {
goHome();
}
}
}).catch((e) => {
console.error('Failed to switch account', e);
});
} else {
console.error('Failed to switch account');
}
}
}, [accounts, location.pathname, navigate, goHome]);

const onClickDetailAccount = useCallback((address: string) => {
return () => {
inactiveModal(modalId);
setTimeout(() => {
navigate(`/accounts/detail/${address}`);
}, 100);
};
}, [navigate, inactiveModal]);

const openDisconnectExtensionModal = useCallback(() => {
activeModal(DISCONNECT_EXTENSION_MODAL);
}, [activeModal]);

const onClickItemQrButton = useCallback((address: string) => {
setSelectedQrAddress(address);
activeModal(simpleQrModalId);
}, [activeModal]);

const onCopyCurrent = useCallback(() => {
copyToClipboard(currentAccount?.address || '');
notify({
message: t('Copied to clipboard')
});
}, [currentAccount?.address, notify, t]);

const onQrModalBack = useGoBackSelectAccount(simpleQrModalId);

const renderItem = useCallback((item: AccountJson, _selected: boolean): React.ReactNode => {
const currentAccountIsAll = isAccountAll(item.address);

if (currentAccountIsAll) {
if (showAllAccount) {
return (
<AccountItemWithName
address={item.address}
className='all-account-selection'
isSelected={_selected}
/>
);
} else {
return null;
}
}

const isInjected = !!item.isInjected;

return (
<AccountCardItem
accountName={item.name || ''}
address={item.address}
className={className}
genesisHash={item.genesisHash}
isSelected={_selected}
onClickQrButton={onClickItemQrButton}
onPressMoreButton={isInjected ? openDisconnectExtensionModal : onClickDetailAccount(item.address)}
source={item.source}
/>
);
}, [className, onClickDetailAccount, openDisconnectExtensionModal, onClickItemQrButton, showAllAccount]);

const renderSelectedItem = useCallback((item: AccountJson): React.ReactNode => {
return (
<AccountBriefInfo
account={item}
className='selected-account'
/>
);
}, []);

return (
<div className={CN(className, 'global-account-info')}>
<Button
Expand All @@ -208,26 +64,16 @@ function Component ({ className }: Props): React.ReactElement<Props> {
type={'ghost'}
/>

<SelectModal
background={'default'}
className={className}
id={modalId}
ignoreScrollbarMethod='padding'
inputWidth={'100%'}
itemKey='address'
items={accounts}
onSelect={_onSelect}
renderItem={renderItem}
renderSelected={renderSelectedItem}
renderWhenEmpty={renderEmpty}
searchFunction={searchAccountFunction}
searchMinCharactersCount={2}
searchPlaceholder={t<string>('Account name')}
selected={currentAccount?.address || ''}
shape='round'
size='small'
title={t('Select account')}
/>
{
!!currentAccount && (
<div onClick={onClickAccount}>
<AccountBriefInfo
account={currentAccount}
className='selected-account'
/>
</div>
)
}

<Button
className={'__copy-button'}
Expand All @@ -242,12 +88,6 @@ function Component ({ className }: Props): React.ReactElement<Props> {
size={'xs'}
type={'ghost'}
/>

<SimpleQrModal
address={selectedQrAddress}
id={simpleQrModalId}
onBack={onQrModalBack}
/>
</div>
);
}
Expand Down Expand Up @@ -296,93 +136,13 @@ const SelectAccount = styled(Component)<Props>(({ theme }) => {
},

'.selected-account': {
gap: token.sizeXXS
gap: token.sizeXXS,
cursor: 'pointer'
},

'.__copy-button': {
color: token.colorTextDark4
}
},

'&.ant-sw-modal': {
'.ant-sw-modal-body': {
marginBottom: 0
},

'.ant-sw-list-search-input': {
paddingBottom: token.paddingXS
},

'.ant-sw-modal-footer': {
marginTop: 0
},

'.ant-account-card': {
padding: token.paddingSM
},

'.ant-web3-block .ant-web3-block-middle-item': {
textAlign: 'initial'
},

'.all-account-selection': {
cursor: 'pointer',
borderRadius: token.borderRadiusLG,
transition: `background ${token.motionDurationMid} ease-in-out`,

'.account-item-name': {
fontSize: token.fontSizeHeading5,
lineHeight: token.lineHeightHeading5
},

'&:hover': {
background: token.colorBgInput
}
},

'.ant-account-card-name': {
textOverflow: 'ellipsis',
overflow: 'hidden',
'white-space': 'nowrap',
maxWidth: 120
},

'.ant-input-container .ant-input': {
color: token.colorTextLight1
}
},

'.all-account-item': {
display: 'flex',
padding: `${token.paddingSM + 2}px ${token.paddingSM}px`,
cursor: 'pointer',
backgroundColor: token.colorBgSecondary,
borderRadius: token.borderRadiusLG,
alignItems: 'center',
justifyContent: 'space-between',
gap: token.sizeXS,

'&:hover': {
backgroundColor: token.colorBgInput
},

'.selected': {
color: token['cyan-6']
}
},

'.ant-select-modal-input-container': {
overflow: 'hidden'
},

'.connect-icon': {
color: token.colorTextBase,
width: 40,
height: 40,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
cursor: 'pointer'
}
});
});
Expand Down

0 comments on commit 48cb1cb

Please sign in to comment.