import React from "react"; import bs58 from "bs58"; import { useHistory, useLocation } from "react-router-dom"; import Select, { InputActionMeta, ActionMeta, ValueType } from "react-select"; import StateManager from "react-select"; import { LOADER_IDS, PROGRAM_INFO_BY_ID, SPECIAL_IDS, SYSVAR_IDS, LoaderName, } from "utils/tx"; import { Cluster, useCluster } from "providers/cluster"; import { useTokenRegistry } from "providers/mints/token-registry"; import { TokenInfoMap } from "@solana/spl-token-registry"; import { Connection } from "@solana/web3.js"; import { getDomainInfo, hasDomainSyntax } from "utils/name-service"; interface SearchOptions { label: string; options: { label: string; value: string[]; pathname: string; }[]; } export function SearchBar() { const [search, setSearch] = React.useState(""); const searchRef = React.useRef(""); const [searchOptions, setSearchOptions] = React.useState([]); const [loadingSearch, setLoadingSearch] = React.useState(false); const [loadingSearchMessage, setLoadingSearchMessage] = React.useState("loading..."); const selectRef = React.useRef | null>(null); const history = useHistory(); const location = useLocation(); const { tokenRegistry } = useTokenRegistry(); const { url, cluster, clusterInfo } = useCluster(); const onChange = ( { pathname }: ValueType, meta: ActionMeta ) => { if (meta.action === "select-option") { history.push({ ...location, pathname }); setSearch(""); } }; const onInputChange = (value: string, { action }: InputActionMeta) => { if (action === "input-change") { setSearch(value); } }; React.useEffect(() => { searchRef.current = search; setLoadingSearchMessage("Loading..."); setLoadingSearch(true); // builds and sets local search output const options = buildOptions( search, cluster, tokenRegistry, clusterInfo?.epochInfo.epoch ); setSearchOptions(options); // checking for non local search output if (hasDomainSyntax(search)) { // if search input is a potential domain we continue the loading state domainSearch(options); } else { // if search input is not a potential domain we can conclude the search has finished setLoadingSearch(false); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [search]); // appends domain lookup results to the local search state const domainSearch = async (options: SearchOptions[]) => { setLoadingSearchMessage("Looking up domain..."); const connection = new Connection(url); const searchTerm = search; const updatedOptions = await buildDomainOptions( connection, search, options ); if (searchRef.current === searchTerm) { setSearchOptions(updatedOptions); // after attempting to fetch the domain name we can conclude the loading state setLoadingSearch(false); setLoadingSearchMessage("Loading..."); } }; const resetValue = "" as any; return (