import React, { useState, useContext } from 'react'; import PropTypes from 'prop-types'; import { useHistory } from 'react-router-dom'; import Fuse from 'fuse.js'; import { useDispatch, useSelector } from 'react-redux'; import { IconName, ButtonLink, TextFieldSearch, Text, Box, Modal, ModalContent, ModalOverlay, ModalHeader, } from '../../component-library'; import { AccountListItem, CreateAccount, ImportAccount } from '..'; import { BlockSize, Size, TextColor, } from '../../../helpers/constants/design-system'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { getSelectedAccount, getMetaMaskAccountsOrdered, getConnectedSubjectsForAllAddresses, getOriginOfCurrentTab, } from '../../../selectors'; import { toggleAccountMenu, setSelectedAccount } from '../../../store/actions'; import { MetaMetricsEventAccountType, MetaMetricsEventCategory, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { CONNECT_HARDWARE_ROUTE, ///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps) ADD_SNAP_ACCOUNT_ROUTE, ///: END:ONLY_INCLUDE_IN ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) CUSTODY_ACCOUNT_ROUTE, ///: END:ONLY_INCLUDE_IN } from '../../../helpers/constants/routes'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; export const AccountListMenu = ({ onClose }) => { const t = useI18nContext(); const trackEvent = useContext(MetaMetricsContext); const accounts = useSelector(getMetaMaskAccountsOrdered); const selectedAccount = useSelector(getSelectedAccount); const connectedSites = useSelector(getConnectedSubjectsForAllAddresses); const currentTabOrigin = useSelector(getOriginOfCurrentTab); const history = useHistory(); const dispatch = useDispatch(); const [searchQuery, setSearchQuery] = useState(''); const [actionMode, setActionMode] = useState(''); let searchResults = accounts; if (searchQuery) { const fuse = new Fuse(accounts, { threshold: 0.2, location: 0, distance: 100, maxPatternLength: 32, minMatchCharLength: 1, keys: ['name', 'address'], }); fuse.setCollection(accounts); searchResults = fuse.search(searchQuery); } let title = t('selectAnAccount'); if (actionMode === 'add') { title = t('addAccount'); } else if (actionMode === 'import') { title = t('importAccount'); } return ( setActionMode('')} > {title} {actionMode === 'add' ? ( { if (confirmed) { dispatch(toggleAccountMenu()); } else { setActionMode(''); } }} /> ) : null} {actionMode === 'import' ? ( { if (confirmed) { dispatch(toggleAccountMenu()); } else { setActionMode(''); } }} /> ) : null} {actionMode === '' ? ( {/* Search box */} {accounts.length > 1 ? ( setSearchQuery(e.target.value)} clearButtonOnClick={() => setSearchQuery('')} clearButtonProps={{ size: Size.SM, }} inputProps={{ autoFocus: true }} /> ) : null} {/* Account list block */} {searchResults.length === 0 && searchQuery !== '' ? ( {t('noAccountsFound')} ) : null} {searchResults.map((account) => { const connectedSite = connectedSites[account.address]?.find( ({ origin }) => origin === currentTabOrigin, ); return ( { dispatch(toggleAccountMenu()); trackEvent({ category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.NavAccountSwitched, properties: { location: 'Main Menu', }, }); dispatch(setSelectedAccount(account.address)); }} identity={account} key={account.address} selected={selectedAccount.address === account.address} closeMenu={onClose} connectedAvatar={connectedSite?.iconUrl} connectedAvatarName={connectedSite?.name} /> ); })} {/* Add / Import / Hardware */} { trackEvent({ category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.AccountAddSelected, properties: { account_type: MetaMetricsEventAccountType.Default, location: 'Main Menu', }, }); setActionMode('add'); }} data-testid="multichain-account-menu-popover-add-account" > {t('addAccount')} { trackEvent({ category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.AccountAddSelected, properties: { account_type: MetaMetricsEventAccountType.Imported, location: 'Main Menu', }, }); setActionMode('import'); }} > {t('importAccount')} { dispatch(toggleAccountMenu()); trackEvent({ category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.AccountAddSelected, properties: { account_type: MetaMetricsEventAccountType.Hardware, location: 'Main Menu', }, }); if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) { global.platform.openExtensionInBrowser( CONNECT_HARDWARE_ROUTE, ); } else { history.push(CONNECT_HARDWARE_ROUTE); } }} > {t('hardwareWallet')} { ///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps) <> { dispatch(toggleAccountMenu()); getEnvironmentType() === ENVIRONMENT_TYPE_POPUP ? global.platform.openExtensionInBrowser( ADD_SNAP_ACCOUNT_ROUTE, null, true, ) : history.push(ADD_SNAP_ACCOUNT_ROUTE); }} > {t('settingAddSnapAccount')} ///: END:ONLY_INCLUDE_IN } { ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) { dispatch(toggleAccountMenu()); trackEvent({ category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.UserClickedConnectCustodialAccount, }); if (getEnvironmentType() === ENVIRONMENT_TYPE_POPUP) { global.platform.openExtensionInBrowser( CUSTODY_ACCOUNT_ROUTE, ); } else { history.push(CUSTODY_ACCOUNT_ROUTE); } }} > {t('connectCustodialAccountMenu')} ///: END:ONLY_INCLUDE_IN } ) : null} ); }; AccountListMenu.propTypes = { /** * Function that executes when the menu closes */ onClose: PropTypes.func.isRequired, };