import { Currency, DEV, Token } from 'moonbeamswap' import React, { KeyboardEvent, RefObject, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' import ReactGA from 'react-ga' import { useTranslation } from 'react-i18next' import { FixedSizeList } from 'react-window' import { Text } from 'rebass' import { ThemeContext } from 'styled-components' import { useActiveWeb3React } from '../../hooks' import { useAllTokens, useToken } from '../../hooks/Tokens' import { useSelectedListInfo } from '../../state/lists/hooks' import { CloseIcon, LinkStyledButton, TYPE } from '../../theme' import { isAddress } from '../../utils' import Card from '../Card' import Column from '../Column' import ListLogo from '../ListLogo' import QuestionHelper from '../QuestionHelper' import Row, { RowBetween } from '../Row' import CommonBases from './CommonBases' import CurrencyList from './CurrencyList' import { filterTokens } from './filtering' import SortButton from './SortButton' import { useTokenComparator } from './sorting' import { PaddedColumn, SearchInput, Separator } from './styleds' import AutoSizer from 'react-virtualized-auto-sizer' interface CurrencySearchProps { isOpen: boolean onDismiss: () => void selectedCurrency?: Currency | null onCurrencySelect: (currency: Currency) => void otherSelectedCurrency?: Currency | null showCommonBases?: boolean onChangeList: () => void } export function CurrencySearch({ selectedCurrency, onCurrencySelect, otherSelectedCurrency, showCommonBases, onDismiss, isOpen, onChangeList }: CurrencySearchProps) { const { t } = useTranslation() const { chainId } = useActiveWeb3React() const theme = useContext(ThemeContext) const fixedList = useRef() const [searchQuery, setSearchQuery] = useState('') const [invertSearchOrder, setInvertSearchOrder] = useState(false) const allTokens = useAllTokens() // if they input an address, use it const isAddressSearch = isAddress(searchQuery) const searchToken = useToken(searchQuery) useEffect(() => { if (isAddressSearch) { ReactGA.event({ category: 'Currency Select', action: 'Search by address', label: isAddressSearch }) } }, [isAddressSearch]) const showETH: boolean = useMemo(() => { const s = searchQuery.toLowerCase().trim() return s === '' || s === 'd' || s === 'de' || s === 'dev' }, [searchQuery]) const tokenComparator = useTokenComparator(invertSearchOrder) const filteredTokens: Token[] = useMemo(() => { if (isAddressSearch) return searchToken ? [searchToken] : [] return filterTokens(Object.values(allTokens), searchQuery) }, [isAddressSearch, searchToken, allTokens, searchQuery]) const filteredSortedTokens: Token[] = useMemo(() => { if (searchToken) return [searchToken] const sorted = filteredTokens.sort(tokenComparator) const symbolMatch = searchQuery .toLowerCase() .split(/\s+/) .filter(s => s.length > 0) if (symbolMatch.length > 1) return sorted return [ ...(searchToken ? [searchToken] : []), // sort any exact symbol matches first ...sorted.filter(token => token.symbol?.toLowerCase() === symbolMatch[0]), ...sorted.filter(token => token.symbol?.toLowerCase() !== symbolMatch[0]) ] }, [filteredTokens, searchQuery, searchToken, tokenComparator]) const handleCurrencySelect = useCallback( (currency: Currency) => { onCurrencySelect(currency) onDismiss() }, [onDismiss, onCurrencySelect] ) // clear the input on open useEffect(() => { if (isOpen) setSearchQuery('') }, [isOpen]) // manage focus on modal show const inputRef = useRef() const handleInput = useCallback(event => { const input = event.target.value const checksummedInput = isAddress(input) setSearchQuery(checksummedInput || input) fixedList.current?.scrollTo(0) }, []) const handleEnter = useCallback( (e: KeyboardEvent) => { if (e.key === 'Enter') { const s = searchQuery.toLowerCase().trim() if (s === 'dev') { handleCurrencySelect(DEV) } else if (filteredSortedTokens.length > 0) { if ( filteredSortedTokens[0].symbol?.toLowerCase() === searchQuery.trim().toLowerCase() || filteredSortedTokens.length === 1 ) { handleCurrencySelect(filteredSortedTokens[0]) } } } }, [filteredSortedTokens, handleCurrencySelect, searchQuery] ) const selectedListInfo = useSelectedListInfo() return ( Select a token } onChange={handleInput} onKeyDown={handleEnter} /> {showCommonBases && ( )} Token Name setInvertSearchOrder(iso => !iso)} />
{({ height }) => ( )}
{selectedListInfo.current ? ( {selectedListInfo.current.logoURI ? ( ) : null} {selectedListInfo.current.name} ) : null} {selectedListInfo.current ? 'Change' : 'Select a list'}
) }