import { memo, useMemo, useState, useEffect, ChangeEvent } from 'react' import { SearchIcon } from '@heroicons/react/outline' import Image from 'next/image' import { Token } from '../../types/jupiter' import mangoStore from '../../store/mangoStore' import Input from '../forms/Input' import { IconButton } from '../shared/Button' import { QuestionMarkCircleIcon, XIcon } from '@heroicons/react/solid' import { useTranslation } from 'next-i18next' const generateSearchTerm = (item: Token, searchValue: string) => { const normalizedSearchValue = searchValue.toLowerCase() const values = `${item.symbol} ${item.name}`.toLowerCase() const isMatchingWithSymbol = item.symbol.toLowerCase().indexOf(normalizedSearchValue) >= 0 const matchingSymbolPercent = isMatchingWithSymbol ? normalizedSearchValue.length / item.symbol.length : 0 return { token: item, matchingIdx: values.indexOf(normalizedSearchValue), matchingSymbolPercent, } } const startSearch = (items: Token[], searchValue: string) => { return items .map((item) => generateSearchTerm(item, searchValue)) .filter((item) => item.matchingIdx >= 0) .sort((i1, i2) => i1.matchingIdx - i2.matchingIdx) .sort((i1, i2) => i2.matchingSymbolPercent - i1.matchingSymbolPercent) .map((item) => item.token) } const TokenItem = ({ token, onSubmit, }: { token: Token onSubmit: (x: string) => void }) => { const { address, symbol, logoURI, name } = token return (
) } const popularTokenSymbols = ['USDC', 'SOL', 'USDT', 'MNGO', 'BTC', 'ETH'] const SwapFormTokenList = ({ onClose, onTokenSelect, type, }: { onClose: () => void onTokenSelect: (x: string) => void type: string }) => { const { t } = useTranslation() const [search, setSearch] = useState('') const tokens = mangoStore.getState().jupiterTokens const walletTokens = mangoStore((s) => s.wallet.tokens) const jupiterTokens = mangoStore((s) => s.jupiterTokens) const inputBank = mangoStore((s) => s.swap.inputBank) const outputBank = mangoStore((s) => s.swap.outputBank) const popularTokens = useMemo(() => { return walletTokens?.length ? tokens.filter((token) => { const walletMints = walletTokens.map((tok) => tok.mint.toString()) return !token?.name || !token?.symbol ? false : popularTokenSymbols.includes(token.symbol) && walletMints.includes(token.address) }) : tokens.filter((token) => { return !token?.name || !token?.symbol ? false : popularTokenSymbols.includes(token.symbol) }) }, [walletTokens, tokens]) useEffect(() => { function onEscape(e: any) { if (e.keyCode === 27) { onClose() } } window.addEventListener('keydown', onEscape) return () => window.removeEventListener('keydown', onEscape) }, [onClose]) const tokenInfos = useMemo(() => { if (tokens?.length) { const filteredTokens = tokens.filter((token) => { if (type === 'input') { return token.symbol === outputBank?.name ? false : true } else { return token.symbol === inputBank?.name ? false : true } }) if (walletTokens?.length) { const walletMints = walletTokens.map((tok) => tok.mint.toString()) return filteredTokens.sort( (a, b) => walletMints.indexOf(b.address) - walletMints.indexOf(a.address) ) } else { return filteredTokens } } else { return [] } }, [tokens, walletTokens, inputBank, outputBank]) const handleUpdateSearch = (e: ChangeEvent) => { setSearch(e.target.value) } const sortedTokens = search ? startSearch(tokenInfos, search) : tokenInfos return ( <>

{type === 'input' ? t('sell') : t('buy')}

} autoFocus value={search} onChange={handleUpdateSearch} />
{popularTokens.length ? (
{popularTokens.map((token) => { let logoURI if (jupiterTokens.length) { logoURI = jupiterTokens.find( (t) => t.address === token.address )!.logoURI } const disabled = (type === 'input' && token.symbol === outputBank?.name) || (type === 'output' && token.symbol === inputBank?.name) return ( ) })}
) : null}
{sortedTokens.map((token) => ( ))}
) } export default memo(SwapFormTokenList)