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 React, { useState, useContext } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode";
|
import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode";
|
||||||
import useKeyboardShortcut from "use-keyboard-shortcut";
|
|
||||||
import PriceBox from "./PriceBox";
|
import PriceBox from "./PriceBox";
|
||||||
import SourcifyMenu from "./SourcifyMenu";
|
import SourcifyMenu from "./SourcifyMenu";
|
||||||
import { RuntimeContext } from "./useRuntime";
|
import { RuntimeContext } from "./useRuntime";
|
||||||
import { search } from "./search/search";
|
import { useGenericSearch } from "./search/search";
|
||||||
import Otter from "./otter.jpg";
|
import Otter from "./otter.jpg";
|
||||||
|
|
||||||
const CameraScanner = React.lazy(() => import("./search/CameraScanner"));
|
const CameraScanner = React.lazy(() => import("./search/CameraScanner"));
|
||||||
|
|
||||||
const Title: React.FC = () => {
|
const Header: React.FC = () => {
|
||||||
const { provider } = useContext(RuntimeContext);
|
const { provider } = useContext(RuntimeContext);
|
||||||
const [searchString, setSearchString] = useState<string>("");
|
const [searchRef, handleChange, handleSubmit] = useGenericSearch();
|
||||||
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 [isScanning, setScanning] = useState<boolean>(false);
|
const [isScanning, setScanning] = useState<boolean>(false);
|
||||||
|
|
||||||
return (
|
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 React, { useState, useContext } from "react";
|
||||||
import { NavLink, useNavigate } from "react-router-dom";
|
import { NavLink } from "react-router-dom";
|
||||||
import { commify } from "@ethersproject/units";
|
import { commify } from "@ethersproject/units";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn";
|
import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn";
|
||||||
|
@ -9,30 +9,13 @@ import Timestamp from "./components/Timestamp";
|
||||||
import { RuntimeContext } from "./useRuntime";
|
import { RuntimeContext } from "./useRuntime";
|
||||||
import { useLatestBlock } from "./useLatestBlock";
|
import { useLatestBlock } from "./useLatestBlock";
|
||||||
import { blockURL } from "./url";
|
import { blockURL } from "./url";
|
||||||
import { search } from "./search/search";
|
import { useGenericSearch } from "./search/search";
|
||||||
|
|
||||||
const CameraScanner = React.lazy(() => import("./search/CameraScanner"));
|
const CameraScanner = React.lazy(() => import("./search/CameraScanner"));
|
||||||
|
|
||||||
const Home: React.FC = () => {
|
const Home: React.FC = () => {
|
||||||
const { provider } = useContext(RuntimeContext);
|
const { provider } = useContext(RuntimeContext);
|
||||||
const [searchString, setSearchString] = useState<string>("");
|
const [searchRef, handleChange, handleSubmit] = useGenericSearch();
|
||||||
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 latestBlock = useLatestBlock(provider);
|
const latestBlock = useLatestBlock(provider);
|
||||||
const [isScanning, setScanning] = useState<boolean>(false);
|
const [isScanning, setScanning] = useState<boolean>(false);
|
||||||
|
@ -58,6 +41,7 @@ const Home: React.FC = () => {
|
||||||
size={50}
|
size={50}
|
||||||
placeholder="Search by address / txn hash / block number / ENS name"
|
placeholder="Search by address / txn hash / block number / ENS name"
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
ref={searchRef}
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
import Title from "./Title";
|
import Header from "./Header";
|
||||||
import { AppConfig, AppConfigContext } from "./useAppConfig";
|
import { AppConfig, AppConfigContext } from "./useAppConfig";
|
||||||
import { SourcifySource } from "./url";
|
import { SourcifySource } from "./url";
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ const Main: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppConfigContext.Provider value={appConfig}>
|
<AppConfigContext.Provider value={appConfig}>
|
||||||
<Title />
|
<Header />
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</AppConfigContext.Provider>
|
</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 { JsonRpcProvider, TransactionResponse } from "@ethersproject/providers";
|
||||||
import { isAddress } from "@ethersproject/address";
|
import { isAddress } from "@ethersproject/address";
|
||||||
import { isHexString } from "@ethersproject/bytes";
|
import { isHexString } from "@ethersproject/bytes";
|
||||||
import { NavigateFunction } from "react-router";
|
import useKeyboardShortcut from "use-keyboard-shortcut";
|
||||||
import { PAGE_SIZE } from "../params";
|
import { PAGE_SIZE } from "../params";
|
||||||
import { ProcessedTransaction, TransactionChunk } from "../types";
|
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)) {
|
if (isAddress(q)) {
|
||||||
navigate(`/address/${q}`, { replace: true });
|
navigate(`/address/${q}`, { replace: true });
|
||||||
return;
|
return;
|
||||||
|
@ -218,3 +226,38 @@ export const search = (q: string, navigate: NavigateFunction) => {
|
||||||
// Assume it is an ENS name
|
// Assume it is an ENS name
|
||||||
navigate(`/address/${q}`);
|
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