Extract common search logic
This commit is contained in:
parent
33939054f2
commit
0b43df6b75
|
@ -1,45 +1,18 @@
|
|||
import React, { useState, useRef, useContext } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import React, { useState, useContext } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode";
|
||||
import useKeyboardShortcut from "use-keyboard-shortcut";
|
||||
import PriceBox from "./PriceBox";
|
||||
import SourcifyMenu from "./SourcifyMenu";
|
||||
import { RuntimeContext } from "./useRuntime";
|
||||
import { search } from "./search/search";
|
||||
import { useGenericSearch } from "./search/search";
|
||||
import Otter from "./otter.jpg";
|
||||
|
||||
const CameraScanner = React.lazy(() => import("./search/CameraScanner"));
|
||||
|
||||
const Title: React.FC = () => {
|
||||
const Header: React.FC = () => {
|
||||
const { provider } = useContext(RuntimeContext);
|
||||
const [searchString, setSearchString] = useState<string>("");
|
||||
const [canSubmit, setCanSubmit] = useState<boolean>(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
const searchTerm = e.target.value.trim();
|
||||
setCanSubmit(searchTerm.length > 0);
|
||||
setSearchString(searchTerm);
|
||||
};
|
||||
|
||||
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
|
||||
e.preventDefault();
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (searchRef.current) {
|
||||
searchRef.current.value = "";
|
||||
}
|
||||
search(searchString, navigate);
|
||||
};
|
||||
|
||||
const searchRef = useRef<HTMLInputElement>(null);
|
||||
useKeyboardShortcut(["/"], () => {
|
||||
searchRef.current?.focus();
|
||||
});
|
||||
|
||||
const [searchRef, handleChange, handleSubmit] = useGenericSearch();
|
||||
const [isScanning, setScanning] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
|
@ -97,4 +70,4 @@ const Title: React.FC = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default Title;
|
||||
export default Header;
|
24
src/Home.tsx
24
src/Home.tsx
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useContext } from "react";
|
||||
import { NavLink, useNavigate } from "react-router-dom";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { commify } from "@ethersproject/units";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn";
|
||||
|
@ -9,30 +9,13 @@ import Timestamp from "./components/Timestamp";
|
|||
import { RuntimeContext } from "./useRuntime";
|
||||
import { useLatestBlock } from "./useLatestBlock";
|
||||
import { blockURL } from "./url";
|
||||
import { search } from "./search/search";
|
||||
import { useGenericSearch } from "./search/search";
|
||||
|
||||
const CameraScanner = React.lazy(() => import("./search/CameraScanner"));
|
||||
|
||||
const Home: React.FC = () => {
|
||||
const { provider } = useContext(RuntimeContext);
|
||||
const [searchString, setSearchString] = useState<string>("");
|
||||
const [canSubmit, setCanSubmit] = useState<boolean>(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
const searchTerm = e.target.value.trim();
|
||||
setCanSubmit(searchTerm.length > 0);
|
||||
setSearchString(searchTerm);
|
||||
};
|
||||
|
||||
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
|
||||
e.preventDefault();
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
search(searchString, navigate);
|
||||
};
|
||||
const [searchRef, handleChange, handleSubmit] = useGenericSearch();
|
||||
|
||||
const latestBlock = useLatestBlock(provider);
|
||||
const [isScanning, setScanning] = useState<boolean>(false);
|
||||
|
@ -58,6 +41,7 @@ const Home: React.FC = () => {
|
|||
size={50}
|
||||
placeholder="Search by address / txn hash / block number / ENS name"
|
||||
onChange={handleChange}
|
||||
ref={searchRef}
|
||||
autoFocus
|
||||
/>
|
||||
<button
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useMemo, useState } from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import Title from "./Title";
|
||||
import Header from "./Header";
|
||||
import { AppConfig, AppConfigContext } from "./useAppConfig";
|
||||
import { SourcifySource } from "./url";
|
||||
|
||||
|
@ -17,7 +17,7 @@ const Main: React.FC = () => {
|
|||
|
||||
return (
|
||||
<AppConfigContext.Provider value={appConfig}>
|
||||
<Title />
|
||||
<Header />
|
||||
<Outlet />
|
||||
</AppConfigContext.Provider>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import {
|
||||
ChangeEventHandler,
|
||||
FormEventHandler,
|
||||
RefObject,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { NavigateFunction, useNavigate } from "react-router";
|
||||
import { JsonRpcProvider, TransactionResponse } from "@ethersproject/providers";
|
||||
import { isAddress } from "@ethersproject/address";
|
||||
import { isHexString } from "@ethersproject/bytes";
|
||||
import { NavigateFunction } from "react-router";
|
||||
import useKeyboardShortcut from "use-keyboard-shortcut";
|
||||
import { PAGE_SIZE } from "../params";
|
||||
import { ProcessedTransaction, TransactionChunk } from "../types";
|
||||
|
||||
|
@ -198,7 +206,7 @@ export class SearchController {
|
|||
}
|
||||
}
|
||||
|
||||
export const search = (q: string, navigate: NavigateFunction) => {
|
||||
const doSearch = (q: string, navigate: NavigateFunction) => {
|
||||
if (isAddress(q)) {
|
||||
navigate(`/address/${q}`, { replace: true });
|
||||
return;
|
||||
|
@ -218,3 +226,38 @@ export const search = (q: string, navigate: NavigateFunction) => {
|
|||
// Assume it is an ENS name
|
||||
navigate(`/address/${q}`);
|
||||
};
|
||||
|
||||
export const useGenericSearch = (): [
|
||||
RefObject<HTMLInputElement>,
|
||||
ChangeEventHandler<HTMLInputElement>,
|
||||
FormEventHandler<HTMLFormElement>
|
||||
] => {
|
||||
const [searchString, setSearchString] = useState<string>("");
|
||||
const [canSubmit, setCanSubmit] = useState<boolean>(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
const searchTerm = e.target.value.trim();
|
||||
setCanSubmit(searchTerm.length > 0);
|
||||
setSearchString(searchTerm);
|
||||
};
|
||||
|
||||
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
|
||||
e.preventDefault();
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (searchRef.current) {
|
||||
searchRef.current.value = "";
|
||||
}
|
||||
doSearch(searchString, navigate);
|
||||
};
|
||||
|
||||
const searchRef = useRef<HTMLInputElement>(null);
|
||||
useKeyboardShortcut(["/"], () => {
|
||||
searchRef.current?.focus();
|
||||
});
|
||||
|
||||
return [searchRef, handleChange, handleSubmit];
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue