diff --git a/apps/cowswap-frontend/src/modules/tokensList/containers/TokenSearchResults/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/containers/TokenSearchResults/index.tsx index c148393351..c976379c1d 100644 --- a/apps/cowswap-frontend/src/modules/tokensList/containers/TokenSearchResults/index.tsx +++ b/apps/cowswap-frontend/src/modules/tokensList/containers/TokenSearchResults/index.tsx @@ -1,6 +1,7 @@ import { useSetAtom } from 'jotai/index' import { useCallback, useEffect, useMemo } from 'react' +import { TokenWithLogo } from '@cowprotocol/common-const' import { useNetworkName } from '@cowprotocol/common-hooks' import { doesTokenMatchSymbolOrAddress } from '@cowprotocol/common-utils' import { useSearchToken } from '@cowprotocol/tokens' @@ -16,7 +17,7 @@ import { TokenSourceTitle } from '../../pure/TokenSourceTitle' import { updateSelectTokenWidgetAtom } from '../../state/selectTokenWidgetAtom' import { SelectTokenContext } from '../../types' -const searchResultsLimit = 10 +const SEARCH_RESULTS_LIMIT = 10 export interface TokenSearchResultsProps extends SelectTokenContext { searchInput: string @@ -53,16 +54,29 @@ export function TokenSearchResults({ return searchCount === 0 }, [isLoading, searchCount]) + const [matchedToken, activeList] = useMemo(() => { + let matched: TokenWithLogo | undefined = undefined + const remaining: TokenWithLogo[] = [] + + for (const t of activeListsResult) { + if (doesTokenMatchSymbolOrAddress(t, searchInput)) { + matched = t + } else { + remaining.push(t) + } + } + + return [matched, remaining] + }, [activeListsResult, searchInput]) + // On press Enter, select first token if only one token is found or it's fully matches to the search input const onInputPressEnter = useCallback(() => { if (!searchInput || !activeListsResult) return - const matchedToken = activeListsResult.find((token) => doesTokenMatchSymbolOrAddress(token, searchInput)) - if (activeListsResult.length === 1 || matchedToken) { onSelectToken(matchedToken || activeListsResult[0]) } - }, [searchInput, activeListsResult, onSelectToken]) + }, [searchInput, activeListsResult, matchedToken, onSelectToken]) useEffect(() => { updateSelectTokenWidget({ @@ -84,9 +98,20 @@ export function TokenSearchResults({ return ( <> + {/*Exact match*/} + {matchedToken && ( + + )} {/*Tokens from active lists*/} - {activeListsResult && - activeListsResult.slice(0, searchResultsLimit).map((token) => { + {activeList && + activeList.map((token) => { const addressLowerCase = token.address.toLowerCase() return ( @@ -105,7 +130,7 @@ export function TokenSearchResults({ {/*Tokens from blockchain*/} {blockchainResult?.length ? ( - {blockchainResult.slice(0, searchResultsLimit).map((token) => { + {blockchainResult.slice(0, SEARCH_RESULTS_LIMIT).map((token) => { return })} @@ -118,7 +143,7 @@ export function TokenSearchResults({ Expanded results from inactive Token Lists
- {inactiveListsResult.slice(0, searchResultsLimit).map((token) => { + {inactiveListsResult.slice(0, SEARCH_RESULTS_LIMIT).map((token) => { return ( = { COW[SupportedChainId.GNOSIS_CHAIN], EURE_GNOSIS_CHAIN, WRAPPED_NATIVE_CURRENCY[SupportedChainId.GNOSIS_CHAIN], + GNO_GNOSIS_CHAIN, WETH_GNOSIS_CHAIN, WBTC_GNOSIS_CHAIN, ]), diff --git a/libs/tokens/src/utils/getTokenSearchFilter.ts b/libs/tokens/src/utils/getTokenSearchFilter.ts index 8c69232be1..557d240794 100644 --- a/libs/tokens/src/utils/getTokenSearchFilter.ts +++ b/libs/tokens/src/utils/getTokenSearchFilter.ts @@ -31,5 +31,10 @@ export function getTokenSearchFilter( return queryParts.every((p) => p.length === 0 || parts.some((sp) => sp.startsWith(p) || sp.endsWith(p))) } - return ({ name, symbol }: T | NativeCurrency): boolean => Boolean((symbol && match(symbol)) || (name && match(name))) + return ({ name, symbol }: T | NativeCurrency): boolean => { + // Filter out from token names the bridge info to not pollute the results with garbage entries + const filteredName = name?.replace(/\s*(on\s(gnosis|xdai)|from\s(mainnet|ethereum)).*$/i, '') + + return Boolean((symbol && match(symbol)) || (filteredName && match(filteredName))) + } }