Skip to content

Commit

Permalink
[Issue-1826] Fix some UI bug
Browse files Browse the repository at this point in the history
  • Loading branch information
dominhquang committed Dec 30, 2024
1 parent 61832c2 commit 5355218
Show file tree
Hide file tree
Showing 22 changed files with 379 additions and 233 deletions.
5 changes: 3 additions & 2 deletions src/components/MetaInfo/parts/TransferItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import i18n from 'utils/i18n/i18n';
import { View } from 'react-native';
import Typography from '../../design-system-ui/typography';
import { toShort } from 'utils/index';
import { Avatar, Logo } from 'components/design-system-ui';
import { Logo } from 'components/design-system-ui';
import { AccountProxyAvatar } from 'components/design-system-ui/avatar/account-proxy-avatar';

export interface TransferInfoItem extends Omit<InfoItemBase, 'label'> {
senderAddress: string;
Expand Down Expand Up @@ -59,7 +60,7 @@ const TransferItem: React.FC<TransferInfoItem> = ({
const genAccountBlock = (address: string, name?: string) => {
return (
<View style={[_style.valueWrapper, { gap: theme.sizeXS, alignItems: 'flex-start' }]}>
<Avatar value={address} size={24} />
<AccountProxyAvatar value={address} size={24} />
<View style={{ flexShrink: 1 }}>
{!!name && (
<Typography.Text ellipsis style={valueStyle}>
Expand Down
3 changes: 3 additions & 0 deletions src/components/Modal/AccountNameModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface Props {
onCancel?: () => void;
modalVisible: boolean;
setModalVisible: (value: boolean) => void;
isUseForceHidden?: boolean;
}

export const AccountNameModal = ({
Expand All @@ -26,6 +27,7 @@ export const AccountNameModal = ({
onCancel,
modalVisible,
setModalVisible,
isUseForceHidden,
}: Props) => {
const theme = useSubWalletTheme().swThemes;
const modalRef = useRef<SWModalRefProps>(null);
Expand Down Expand Up @@ -140,6 +142,7 @@ export const AccountNameModal = ({
modalTitle={'Account name'}
setVisible={setModalVisible}
isUseModalV2
isUseForceHidden={isUseForceHidden}
titleTextAlign={'center'}
onChangeModalVisible={onCancel}
disabledOnPressBackDrop={true}
Expand Down
25 changes: 15 additions & 10 deletions src/components/Modal/RemindBackupModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import { useSelector } from 'react-redux';
import { RootState } from 'stores/index';
import { useNavigation } from '@react-navigation/native';
import { RootNavigationProps } from 'routes/index';
import { AccountSelector } from 'components/Modal/common/AccountSelectorNew';
import { ModalRef } from 'types/modalRef';
import { AccountJson } from '@subwallet/extension-base/background/types';
import { isShowRemindBackupModal, setIsShowRemindBackupModal } from 'screens/Home';
import { BACKUP_SEED_PHRASE_CODE_URL } from 'constants/index';
import { AccountProxySelector } from '../common/AccountSelectorNew';
import { AccountProxyItem } from 'screens/Account/AccountsScreen';
import { AccountProxyType } from '@subwallet/extension-base/types';

interface Props {
modalVisible: boolean;
Expand All @@ -23,21 +24,25 @@ interface Props {
export const RemindBackupModal = ({ modalVisible, setVisible }: Props) => {
const navigation = useNavigation<RootNavigationProps>();
const theme = useSubWalletTheme().swThemes;
const { isAllAccount, currentAccount, accounts } = useSelector((state: RootState) => state.accountState);
const { accountProxies, currentAccountProxy } = useSelector((state: RootState) => state.accountState);
const accountSelectorRef = useRef<ModalRef>();
const onSetCurrentRemindBackupTimeout = () => {
mmkvStore.set('lastTimeLogin', Date.now());
mmkvStore.set('remindBackupTimeout', Date.now());
};
const onSelectItem = (item: AccountJson) => {
navigation.navigate('AccountExport', { address: item?.address || '' });
const onSelectItem = (item: AccountProxyItem) => {
navigation.navigate('AccountExport', { address: item?.id || '' });
};

const onBackUpAccount = () => {
if (isAllAccount) {
accountSelectorRef.current?.onOpenModal();
if (currentAccountProxy) {
if ([AccountProxyType.SOLO, AccountProxyType.UNIFIED].includes(currentAccountProxy.accountType)) {
navigation.navigate('AccountExport', { address: currentAccountProxy?.id || '' });
} else {
accountSelectorRef.current?.onOpenModal();
}
} else {
navigation.navigate('AccountExport', { address: currentAccount?.address || '' });
accountSelectorRef.current?.onOpenModal();
}
};

Expand Down Expand Up @@ -107,8 +112,8 @@ export const RemindBackupModal = ({ modalVisible, setVisible }: Props) => {
</SwModal>
)}

<AccountSelector
items={accounts.filter(item => item.address !== 'ALL')}
<AccountProxySelector
items={accountProxies.filter(item => item.id !== 'ALL')}
selectedValueMap={{}}
onSelectItem={onSelectItem}
accountSelectorRef={accountSelectorRef}
Expand Down
146 changes: 136 additions & 10 deletions src/components/Modal/common/AccountSelectorNew.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
import React from 'react';
import { AccountJson } from '@subwallet/extension-base/background/types';
import React, { useCallback, useMemo } from 'react';
import i18n from 'utils/i18n/i18n';
import { FullSizeSelectModal } from 'components/common/SelectModal';
import { ListRenderItemInfo } from 'react-native';
import { Keyboard, ListRenderItemInfo, StyleSheet, View } from 'react-native';
import { Typography } from 'components/design-system-ui';
import { AccountGroupLabel, AccountGroupType, AccountProxyItem } from 'screens/Account/AccountsScreen';
import { ThemeTypes } from 'styles/themes';
import { FontSemiBold } from 'styles/sharedStyles';
import { useSubWalletTheme } from 'hooks/useSubWalletTheme';
import { isAccountAll } from '@subwallet/extension-base/utils';
import { AccountProxy, AccountProxyType } from '@subwallet/extension-base/types';
import { VoidFunction } from 'types/index';

interface Props {
items: AccountJson[];
items: AccountProxy[];
selectedValueMap: Record<string, boolean>;
onSelectItem?: (item: AccountJson) => void;
onSelectItem?: (item: AccountProxyItem) => void;
disabled?: boolean;
renderSelected?: () => JSX.Element;
accountSelectorRef?: React.Ref<any>;
closeModalAfterSelect?: boolean;
isShowContent?: boolean;
isShowInput?: boolean;
children?: React.ReactNode;
renderCustomItem?: ({ item }: ListRenderItemInfo<AccountJson>) => JSX.Element;
renderCustomItem?: ({ item }: ListRenderItemInfo<AccountProxyItem>) => JSX.Element;
onCloseModal?: VoidFunction;
}

export const AccountSelector = ({
export const AccountProxySelector = ({
items,
selectedValueMap,
onSelectItem,
Expand All @@ -30,14 +38,114 @@ export const AccountSelector = ({
isShowInput,
children,
renderCustomItem,
onCloseModal,
}: Props) => {
const theme = useSubWalletTheme().swThemes;
const stylesheet = createStyle(theme);

const listItems = useMemo<AccountProxyItem[]>(() => {
let accountAll: AccountProxyItem | undefined;
const result: AccountProxyItem[] = [];
const masterAccounts: AccountProxyItem[] = [];
const qrSignerAccounts: AccountProxyItem[] = [];
const watchOnlyAccounts: AccountProxyItem[] = [];
const ledgerAccounts: AccountProxyItem[] = [];
const injectedAccounts: AccountProxyItem[] = [];
const unknownAccounts: AccountProxyItem[] = [];

items.forEach(ap => {
if (isAccountAll(ap.id) || ap.accountType === AccountProxyType.ALL_ACCOUNT) {
accountAll = { ...ap, group: AccountGroupType.ALL_ACCOUNT };

return;
}

if (ap.accountType === AccountProxyType.SOLO || ap.accountType === AccountProxyType.UNIFIED) {
masterAccounts.push({ ...ap, group: AccountGroupType.MASTER_ACCOUNT });
} else if (ap.accountType === AccountProxyType.QR) {
qrSignerAccounts.push({ ...ap, group: AccountGroupType.QR });
} else if (ap.accountType === AccountProxyType.READ_ONLY) {
watchOnlyAccounts.push({ ...ap, group: AccountGroupType.READ_ONLY });
} else if (ap.accountType === AccountProxyType.LEDGER) {
ledgerAccounts.push({ ...ap, group: AccountGroupType.LEDGER });
} else if (ap.accountType === AccountProxyType.INJECTED) {
injectedAccounts.push({ ...ap, group: AccountGroupType.INJECTED });
} else if (ap.accountType === AccountProxyType.UNKNOWN) {
unknownAccounts.push({ ...ap, group: AccountGroupType.UNKNOWN });
}
});

if (masterAccounts.length) {
result.push(...masterAccounts);
}

if (qrSignerAccounts.length) {
result.push(...qrSignerAccounts);
}

if (watchOnlyAccounts.length) {
result.push(...watchOnlyAccounts);
}

if (ledgerAccounts.length) {
result.push(...ledgerAccounts);
}

if (injectedAccounts.length) {
result.push(...ledgerAccounts);
}

if (unknownAccounts.length) {
result.push(...unknownAccounts);
}

if (result.length > 1 && accountAll) {
result.unshift(accountAll);
}

return result;
}, [items]);

const groupBy = useCallback((item: AccountProxyItem) => {
return `${AccountGroupLabel[item.group]}`;
}, []);

const renderSectionHeader: (item: string, itemLength?: number) => React.ReactElement | null = useCallback(
(item: string) => {
if (
item.split('|')[0] === AccountGroupLabel[AccountGroupType.ALL_ACCOUNT] ||
item.split('|')[0] === AccountGroupLabel[AccountGroupType.MASTER_ACCOUNT]
) {
return <></>;
}

return (
<View key={item} style={stylesheet.sectionHeaderContainer}>
<Typography.Text size={'sm'} style={stylesheet.sectionHeaderTitle}>
{`${item.split('|')[0]} `}
</Typography.Text>
</View>
);
},
[stylesheet.sectionHeaderContainer, stylesheet.sectionHeaderTitle],
);

const grouping = useMemo(() => {
return { groupBy, sortSection: undefined, renderSectionHeader };
}, [groupBy, renderSectionHeader]);

const _onSelectItem = (item: AccountProxyItem) => {
Keyboard.dismiss();
onSelectItem && onSelectItem(item);
};

return (
<FullSizeSelectModal
items={items}
items={listItems}
selectedValueMap={selectedValueMap}
onSelectItem={onSelectItem}
onSelectItem={_onSelectItem}
selectModalType={'single'}
selectModalItemType={'account'}
selectModalItemType={'account-proxy'}
disabled={disabled}
renderSelected={renderSelected}
placeholder={i18n.placeholder.accountName}
Expand All @@ -46,8 +154,26 @@ export const AccountSelector = ({
closeModalAfterSelect={closeModalAfterSelect}
isShowContent={isShowContent}
renderCustomItem={renderCustomItem}
estimatedItemSize={60}
onCloseModal={onCloseModal}
grouping={grouping}
isShowInput={isShowInput}>
{children}
</FullSizeSelectModal>
);
};

function createStyle(theme: ThemeTypes) {
return StyleSheet.create({
sectionHeaderContainer: {
paddingBottom: theme.sizeXS,
backgroundColor: theme.colorBgDefault,
paddingHorizontal: theme.padding,
},
sectionHeaderTitle: {
...FontSemiBold,
color: theme.colorTextLight1,
textTransform: 'uppercase',
},
});
}
26 changes: 25 additions & 1 deletion src/components/common/SelectModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { SortFunctionInterface } from 'types/ui-types';
import { SectionItem } from 'components/LazySectionList';
import { ListRenderItemInfo } from '@shopify/flash-list';
import { AccountAddressItemExtraType } from 'components/Modal/common/AccountSelector';
import { AccountProxyItem } from 'screens/Account/AccountsScreen';
import { AccountProxySelectItem } from 'components/common/SelectModal/parts/AccountProxySelectItem';

interface Props<T> {
items: T[];
Expand All @@ -37,7 +39,7 @@ interface Props<T> {
isShowListWrapper?: boolean;
renderSelectModalBtn?: (onOpenModal: React.Dispatch<React.SetStateAction<boolean>>) => JSX.Element;
renderSelected?: () => JSX.Element;
selectModalItemType?: 'account' | 'token' | 'chain' | 'account-chain-address';
selectModalItemType?: 'account' | 'token' | 'chain' | 'account-chain-address' | 'account-proxy';
selectModalType?: 'single' | 'multi';
selectedValueMap: Record<string, boolean>;
onSelectItem?: (item: T) => void;
Expand Down Expand Up @@ -153,6 +155,9 @@ function _SelectModal<T>(selectModalProps: Props<T>, ref: ForwardedRef<any>) {
} else if (selectModalItemType === 'account') {
const accountItems = items as AccountAddressItemExtraType[];
existed = accountItems.find(item => item.address === defaultValue);
} else if (selectModalItemType === 'account-proxy') {
const accountItems = items as AccountProxyItem[];
existed = accountItems.find(item => item.id === defaultValue);
} else {
const chainItems = items as ChainInfo[];
existed = chainItems.find(item => item.slug === defaultValue);
Expand Down Expand Up @@ -204,6 +209,13 @@ function _SelectModal<T>(selectModalProps: Props<T>, ref: ForwardedRef<any>) {
(acc.accountName && acc.accountName.toLowerCase().includes(lowerCaseSearchString)) ||
acc.address.toLowerCase().includes(lowerCaseSearchString),
) as T[];
} else if (selectModalItemType === 'account-proxy') {
return (_items as AccountProxyItem[]).filter(acc => {
const isValidSearchByAddress = acc.accounts.some(ac => {
return ac.address.toLowerCase().includes(searchString.toLowerCase());
});
return (acc.name && acc.name.toLowerCase().includes(lowerCaseSearchString)) || isValidSearchByAddress;
}) as T[];
} else if (selectModalItemType === 'token') {
return (_items as TokenItemType[]).filter(
({ symbol, originChain }) =>
Expand Down Expand Up @@ -232,6 +244,18 @@ function _SelectModal<T>(selectModalProps: Props<T>, ref: ForwardedRef<any>) {
/>
</>
);
} else if (selectModalItemType === 'account-proxy') {
return (
<>
<AccountProxySelectItem
item={item}
selectedValueMap={selectedValueMap}
onSelectItem={_onSelectItem}
showAccountSignModeIcon={showAccountSignModeIcon}
onCloseModal={() => closeModalAfterSelect && modalBaseV2Ref?.current?.close()}
/>
</>
);
} else if (selectModalItemType === 'token') {
return (
<_TokenSelectItem
Expand Down
36 changes: 36 additions & 0 deletions src/components/common/SelectModal/parts/AccountProxySelectItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import AccountItemWithName from 'components/common/Account/Item/AccountItemWithName';
import React from 'react';
import { AccountProxyItem } from 'screens/Account/AccountsScreen';

interface Props<T> {
item: T;
selectedValueMap: Record<string, boolean>;
onSelectItem?: (item: T) => void;
onCloseModal?: () => void;
showAccountSignModeIcon?: boolean;
}

export function AccountProxySelectItem<T>({
item,
selectedValueMap,
onSelectItem,
onCloseModal,
showAccountSignModeIcon,
}: Props<T>) {
const { id, name } = item as AccountProxyItem;

return (
<AccountItemWithName
customStyle={{ container: { marginBottom: 8, marginHorizontal: 16 } }}
avatarSize={24}
address={id}
accountName={name}
isSelected={!!selectedValueMap[id]}
showAccountSignModeIcon={showAccountSignModeIcon}
onPress={() => {
onSelectItem && onSelectItem(item);
onCloseModal && onCloseModal();
}}
/>
);
}
2 changes: 1 addition & 1 deletion src/components/design-system-ui/modal/SwModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ const SwModal = React.forwardRef<ModalRefProps, SWModalProps>(
height={childrenHeight}
ref={modalBaseV2Ref}
disabledOnPressBackDrop={disabledOnPressBackDrop}
isUseForceHidden={Platform.OS === 'android'}
isUseForceHidden={isUseForceHidden === undefined ? Platform.OS === 'android' : isUseForceHidden}
onChangeModalVisible={onChangeModalVisible}
isAllowSwipeDown={isAllowSwipeDown}
onBackButtonPress={onBackButtonPress}
Expand Down
Loading

0 comments on commit 5355218

Please sign in to comment.