From ec7f65c851b0294469b87cf2343d807ad361f1f6 Mon Sep 17 00:00:00 2001 From: Abhijith Reddy Date: Mon, 6 Dec 2021 21:21:01 -0500 Subject: [PATCH 1/2] Fuzzy search. debounce search field --- src/data/search/index.ts | 46 ++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/data/search/index.ts b/src/data/search/index.ts index 2a028b27..f59be87a 100644 --- a/src/data/search/index.ts +++ b/src/data/search/index.ts @@ -7,6 +7,7 @@ import { client } from 'apollo/client' import { usePoolDatas, useAllPoolData } from 'state/pools/hooks' import { PoolData } from 'state/pools/reducer' import { notEmpty, escapeRegExp } from 'utils' +import useDebounce from 'hooks/useDebounce' export const TOKEN_SEARCH = gql` query tokens($value: String, $id: String) { @@ -137,12 +138,21 @@ export function useFetchSearchResults( pools: PoolData[] loading: boolean } { + const debouncedValue = useDebounce(value, 300) + const allTokens = useAllTokenData() const allPools = useAllPoolData() const [tokenData, setTokenData] = useState() const [poolData, setPoolData] = useState() + const symbols = debouncedValue + ? debouncedValue + .split(/[\/|\s]/) //split using forward slash and space + .map((val) => val.toUpperCase()) + .filter((val) => !!val) + : [] + // fetch data based on search input useEffect(() => { async function fetch() { @@ -150,15 +160,16 @@ export function useFetchSearchResults( const tokens = await client.query({ query: TOKEN_SEARCH, variables: { - value: value ? value.toUpperCase() : '', - id: value, + symbols: symbols, + value: debouncedValue ? debouncedValue.toUpperCase() : '', + id: debouncedValue, }, }) const pools = await client.query({ query: POOL_SEARCH, variables: { tokens: tokens.data.asSymbol?.map((t) => t.id), - id: value, + id: debouncedValue, }, }) @@ -172,10 +183,10 @@ export function useFetchSearchResults( console.log(e) } } - if (value && value.length > 0) { + if (debouncedValue && debouncedValue.length > 0) { fetch() } - }, [value]) + }, [debouncedValue]) const allFetchedTokens = useMemo(() => { if (tokenData) { @@ -213,21 +224,21 @@ export function useFetchSearchResults( const filteredSortedTokens = useMemo(() => { return combinedTokens.filter((t) => { const regexMatches = Object.keys(t).map((tokenEntryKey) => { - const isAddress = value.slice(0, 2) === '0x' + const isAddress = debouncedValue.slice(0, 2) === '0x' if (tokenEntryKey === 'address' && isAddress) { - return t[tokenEntryKey].match(new RegExp(escapeRegExp(value), 'i')) + return t[tokenEntryKey].match(new RegExp(escapeRegExp(debouncedValue), 'i')) } if (tokenEntryKey === 'symbol' && !isAddress) { - return t[tokenEntryKey].match(new RegExp(escapeRegExp(value), 'i')) + return t[tokenEntryKey].match(new RegExp(escapeRegExp(debouncedValue), 'i')) } if (tokenEntryKey === 'name' && !isAddress) { - return t[tokenEntryKey].match(new RegExp(escapeRegExp(value), 'i')) + return t[tokenEntryKey].match(new RegExp(escapeRegExp(debouncedValue), 'i')) } return false }) return regexMatches.some((m) => m) }) - }, [combinedTokens, value]) + }, [combinedTokens, debouncedValue]) const newPools = useMemo(() => { return poolDatasFull.filter((p) => !Object.keys(allPools).includes(p.address)) @@ -245,21 +256,24 @@ export function useFetchSearchResults( const filteredSortedPools = useMemo(() => { return combinedPools.filter((t) => { const regexMatches = Object.keys(t).map((key) => { - const isAddress = value.slice(0, 2) === '0x' + const isAddress = debouncedValue.slice(0, 2) === '0x' if (key === 'address' && isAddress) { - return t[key].match(new RegExp(escapeRegExp(value), 'i')) + return t[key].match(new RegExp(escapeRegExp(debouncedValue), 'i')) } if ((key === 'token0' || key === 'token1') && !isAddress) { return ( - t[key].name.match(new RegExp(escapeRegExp(value), 'i')) || - t[key].symbol.toLocaleLowerCase().match(new RegExp(escapeRegExp(value.toLocaleLowerCase()), 'i')) + t[key].name.match(new RegExp(escapeRegExp(debouncedValue), 'i')) || + t[key].symbol.toLocaleLowerCase().match(new RegExp(escapeRegExp(debouncedValue.toLocaleLowerCase()), 'i')) ) } return false }) - return regexMatches.some((m) => m) + const fuzzyString = `${t.token0.symbol} ${t.token1.symbol} ${t.feeTier / 10000}%` + const fuzzyRegex = new RegExp(`(${symbols.join('|')})`, 'g') + const fuzzyMatch = fuzzyString.match(fuzzyRegex)?.length === symbols.length + return regexMatches.some((m) => m) || fuzzyMatch }) - }, [combinedPools, value]) + }, [combinedPools, debouncedValue]) return { tokens: filteredSortedTokens, From df7fec93a274098838933754ce2067ccc1f37542 Mon Sep 17 00:00:00 2001 From: Abhijith Reddy Date: Mon, 6 Dec 2021 21:23:25 -0500 Subject: [PATCH 2/2] move symbols further down the function --- src/data/search/index.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/data/search/index.ts b/src/data/search/index.ts index f59be87a..f54bb1ef 100644 --- a/src/data/search/index.ts +++ b/src/data/search/index.ts @@ -146,13 +146,6 @@ export function useFetchSearchResults( const [tokenData, setTokenData] = useState() const [poolData, setPoolData] = useState() - const symbols = debouncedValue - ? debouncedValue - .split(/[\/|\s]/) //split using forward slash and space - .map((val) => val.toUpperCase()) - .filter((val) => !!val) - : [] - // fetch data based on search input useEffect(() => { async function fetch() { @@ -160,7 +153,6 @@ export function useFetchSearchResults( const tokens = await client.query({ query: TOKEN_SEARCH, variables: { - symbols: symbols, value: debouncedValue ? debouncedValue.toUpperCase() : '', id: debouncedValue, }, @@ -253,6 +245,13 @@ export function useFetchSearchResults( ] }, [allPools, newPools]) + const symbols = debouncedValue + ? debouncedValue + .split(/[\/|\s]/) //split using forward slash and space + .map((val) => val.toUpperCase()) + .filter((val) => !!val) + : [] + const filteredSortedPools = useMemo(() => { return combinedPools.filter((t) => { const regexMatches = Object.keys(t).map((key) => {