add debounced search functionality

This commit is contained in:
Dexter 2022-02-16 23:46:34 +00:00 committed by Dexter Edwards
parent 428bf82d01
commit 2014831650
2 changed files with 67 additions and 31 deletions

View File

@ -1,53 +1,90 @@
import React from "react"; import { gql, useQuery } from '@apollo/client';
import { useState } from "react"; import React from 'react';
import { useState } from 'react';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import debounce from 'lodash.debounce';
const PARTY_ID_LENGTH = 64; const TX_LENGTH = 64;
enum PossibleIdTypes { enum PossibleIdTypes {
Block = "Block", Block = 'Block',
Tx = "Tx", Tx = 'Tx',
Party = "Party", Party = 'Party',
Unknown = "Unknown", Market = 'Market',
Unknown = 'Unknown',
} }
const useGuess = () => { const GUESS_QUERY = gql`
const [search, setSearch] = useState<string>(""); query Guess($guess: ID!) {
const [possibleTypes, setPossibleTypes] = useState<PossibleIdTypes[]>(); party(id: $guess) {
id
const getPossibleIds = React.useCallback((search: string) => {
if (!search.length) {
return [];
} else if (
search.startsWith("0x") &&
search.length === PARTY_ID_LENGTH + 2
) {
return [PossibleIdTypes.Tx, PossibleIdTypes.Party];
} else if (!search.startsWith("0x") && search.length === PARTY_ID_LENGTH) {
return [PossibleIdTypes.Tx, PossibleIdTypes.Party];
} else if (!isNaN(Number(search))) {
return [PossibleIdTypes.Block];
} }
return []; market(id: $guess) {
}, []); id
}
}
`;
const usePossibleType = (search: string) => {
const [possibleType, setPossibleType] = useState<PossibleIdTypes>();
const { data, loading, error } = useQuery<any, any>(GUESS_QUERY, {
variables: {
guess: search,
},
skip: !search,
});
React.useEffect(() => {
if (!isNaN(Number(search))) {
setPossibleType(PossibleIdTypes.Block);
} else if (data?.party) {
setPossibleType(PossibleIdTypes.Party);
} else if (data?.market) {
setPossibleType(PossibleIdTypes.Market);
} else if (search.replace('0x', '').length === TX_LENGTH) {
setPossibleType(PossibleIdTypes.Tx);
} else {
setPossibleType(PossibleIdTypes.Unknown);
}
}, [data?.market, data?.party, search, setPossibleType]);
return {
loading,
error,
possibleType,
};
};
const useGuess = () => {
const [search, setSearch] = useState<string>('');
const [debouncedSearch, setDebouncedSearch] = useState<string>('');
const { loading, error, possibleType } = usePossibleType(debouncedSearch);
const debouncedSearchSet = React.useMemo(
() => debounce(setDebouncedSearch, 1000),
[setDebouncedSearch]
);
const onChange = React.useCallback( const onChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => { (event: React.ChangeEvent<HTMLInputElement>) => {
const search = event.target.value; const search = event.target.value;
setSearch(search); setSearch(search);
setPossibleTypes(getPossibleIds(search)); debouncedSearchSet(search);
}, },
[getPossibleIds] [debouncedSearchSet]
); );
return { return {
onChange, onChange,
possibleTypes,
search, search,
loading,
error,
possibleType,
}; };
}; };
const Search = () => { const Search = () => {
const { search, onChange, possibleTypes } = useGuess(); const { search, onChange } = useGuess();
return ( return (
<section> <section>
<h1>Vega Block Explorer</h1> <h1>Vega Block Explorer</h1>
@ -59,8 +96,6 @@ const Search = () => {
onChange={(e) => onChange(e)} onChange={(e) => onChange(e)}
></input> ></input>
</fieldset> </fieldset>
{/* TODO implement links */}
<div>{JSON.stringify(possibleTypes)}</div>
</section> </section>
); );
}; };

View File

@ -17,6 +17,7 @@
"@nrwl/next": "13.8.1", "@nrwl/next": "13.8.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"graphql": "^16.3.0", "graphql": "^16.3.0",
"lodash.debounce": "^4.0.8",
"next": "12.0.7", "next": "12.0.7",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",