import React, { useContext } from 'react'; import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import Identicon from '../../../../components/ui/identicon'; import UrlIcon from '../../../../components/ui/url-icon'; import Button from '../../../../components/ui/button'; import ActionableMessage from '../../../../components/ui/actionable-message/actionable-message'; import { I18nContext } from '../../../../contexts/i18n'; import { getCurrentChainId, getRpcPrefsForCurrentProvider, getUseCurrencyRateCheck, } from '../../../../selectors'; import { MetaMetricsEventCategory } from '../../../../../shared/constants/metametrics'; import { SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP } from '../../../../../shared/constants/swaps'; import { getURLHostName } from '../../../../helpers/utils/util'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; export default function ItemList({ results = [], onClickItem, onOpenImportTokenModalClick, Placeholder, listTitle, maxListItems = 6, searchQuery = '', containerRef, hideRightLabels, hideItemIf, listContainerClassName, }) { const t = useContext(I18nContext); const chainId = useSelector(getCurrentChainId); const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); const blockExplorerLink = rpcPrefs.blockExplorerUrl ?? SWAPS_CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP[chainId] ?? null; const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); const blockExplorerHostName = getURLHostName(blockExplorerLink); const trackEvent = useContext(MetaMetricsContext); // If there is a token for import based on a contract address, it's the only one in the list. const hasTokenForImport = results.length === 1 && results[0].notImported; const placeholder = Placeholder ? ( ) : null; return results.length === 0 ? ( placeholder ) : (
{listTitle ? (
{listTitle}
) : null}
{results.slice(0, maxListItems).map((result, i) => { if (hideItemIf?.(result)) { return null; } const onClick = () => { if (result.notImported) { onOpenImportTokenModalClick(result); } else { onClickItem?.(result); } }; const { iconUrl, identiconAddress, selected, disabled, primaryLabel, secondaryLabel, rightPrimaryLabel, rightSecondaryLabel, IconComponent, } = result; return (
e.key === 'Enter' && onClick()} key={`searchable-item-list-item-${i}`} > {iconUrl || primaryLabel ? ( ) : null} {!(iconUrl || primaryLabel) && identiconAddress ? (
) : null} {IconComponent ? : null}
{primaryLabel ? ( {primaryLabel} ) : null} {secondaryLabel ? ( {secondaryLabel} ) : null}
{!hideRightLabels && (rightPrimaryLabel || rightSecondaryLabel) ? (
{rightPrimaryLabel ? ( {rightPrimaryLabel} ) : null} {rightSecondaryLabel && useCurrencyRateCheck ? ( {rightSecondaryLabel} ) : null}
) : null}
{result.notImported && ( )}
); })} {!hasTokenForImport && blockExplorerLink && (
{ /* istanbul ignore next */ trackEvent({ event: 'Clicked Block Explorer Link', category: MetaMetricsEventCategory.Swaps, properties: { link_type: 'Token Tracker', action: 'Verify Contract Address', block_explorer_domain: blockExplorerHostName, }, }); global.platform.openTab({ url: blockExplorerLink, }); }} target="_blank" rel="noopener noreferrer" > {blockExplorerHostName} , ])} />
)}
); } ItemList.propTypes = { results: PropTypes.arrayOf( PropTypes.shape({ iconUrl: PropTypes.string, selected: PropTypes.bool, disabled: PropTypes.bool, primaryLabel: PropTypes.string, secondaryLabel: PropTypes.string, rightPrimaryLabel: PropTypes.string, rightSecondaryLabel: PropTypes.string, }), ), onClickItem: PropTypes.func, onOpenImportTokenModalClick: PropTypes.func, Placeholder: PropTypes.func, listTitle: PropTypes.string, maxListItems: PropTypes.number, searchQuery: PropTypes.string, containerRef: PropTypes.shape({ current: PropTypes.instanceOf(window.Element), }), hideRightLabels: PropTypes.bool, hideItemIf: PropTypes.func, listContainerClassName: PropTypes.string, };