import React, { useState, useContext, useRef, useEffect } 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 Box from '../../ui/box/box'; import { ButtonLink, TextFieldSearch, Text } from '../../component-library'; // TODO: Replace ICON_NAMES with IconName when ButtonBase/Buttons have been updated import { ICON_NAMES } from '../../component-library/icon/deprecated'; import { AccountListItem } from '..'; import { BLOCK_SIZES, Size, TextColor, } from '../../../helpers/constants/design-system'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import Popover from '../../ui/popover'; import { getSelectedAccount, getMetaMaskAccountsOrdered, getConnectedSubjectsForAllAddresses, getOriginOfCurrentTab, } from '../../../selectors'; import { toggleAccountMenu, setSelectedAccount } from '../../../store/actions'; import { MetaMetricsEventAccountType, MetaMetricsEventCategory, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { IMPORT_ACCOUNT_ROUTE, NEW_ACCOUNT_ROUTE, CONNECT_HARDWARE_ROUTE, } 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 inputRef = useRef(); const [searchQuery, setSearchQuery] = 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); } // Focus on the search box when the popover is opened useEffect(() => { if (inputRef.current) { inputRef.current.rootNode.querySelector('input[type=search]').focus(); } }, [inputRef]); return ( {/* Search box */} setSearchQuery(e.target.value)} /> {/* 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 */} { dispatch(toggleAccountMenu()); trackEvent({ category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.AccountAddSelected, properties: { account_type: MetaMetricsEventAccountType.Default, location: 'Main Menu', }, }); history.push(NEW_ACCOUNT_ROUTE); }} > {t('addAccount')} { dispatch(toggleAccountMenu()); trackEvent({ category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.AccountAddSelected, properties: { account_type: MetaMetricsEventAccountType.Imported, location: 'Main Menu', }, }); history.push(IMPORT_ACCOUNT_ROUTE); }} > {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')} ); }; AccountListMenu.propTypes = { /** * Function that executes when the menu closes */ onClose: PropTypes.func.isRequired, };