Extract common camera scan code; apply it to home also

This commit is contained in:
Willian Mitsuda 2021-09-01 17:40:42 -03:00
parent 4078c6ba34
commit 51b18b763f
3 changed files with 80 additions and 50 deletions

View File

@ -3,7 +3,9 @@ import { NavLink, useHistory } 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";
import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode";
import Logo from "./Logo"; import Logo from "./Logo";
import CameraScanner from "./search/CameraScanner";
import Timestamp from "./components/Timestamp"; import Timestamp from "./components/Timestamp";
import { RuntimeContext } from "./useRuntime"; import { RuntimeContext } from "./useRuntime";
import { useLatestBlock } from "./useLatestBlock"; import { useLatestBlock } from "./useLatestBlock";
@ -30,11 +32,13 @@ const Home: React.FC = () => {
}; };
const latestBlock = useLatestBlock(provider); const latestBlock = useLatestBlock(provider);
const [isScanning, setScanning] = useState<boolean>(false);
document.title = "Home | Otterscan"; document.title = "Home | Otterscan";
return ( return (
<div className="m-auto"> <div className="m-auto">
{isScanning && <CameraScanner turnOffScan={() => setScanning(false)} />}
<Logo /> <Logo />
<form <form
className="flex flex-col" className="flex flex-col"
@ -42,14 +46,24 @@ const Home: React.FC = () => {
autoComplete="off" autoComplete="off"
spellCheck={false} spellCheck={false}
> >
<input <div className="flex mb-10">
className="w-full border rounded focus:outline-none px-2 py-1 mb-10" <input
type="text" className="w-full border-l border-t border-b rounded-l focus:outline-none px-2 py-1"
size={50} type="text"
placeholder="Search by address / txn hash / block number / ENS name" size={50}
onChange={handleChange} placeholder="Search by address / txn hash / block number / ENS name"
autoFocus onChange={handleChange}
></input> autoFocus
/>
<button
className="border rounded-r bg-gray-100 hover:bg-gray-200 focus:outline-none px-2 py-1 text-base text-gray-500 flex justify-center items-center"
type="button"
onClick={() => setScanning(true)}
title="Scan an ETH address using your camera"
>
<FontAwesomeIcon icon={faQrcode} />
</button>
</div>
<button <button
className="mx-auto px-3 py-1 mb-10 rounded bg-gray-100 hover:bg-gray-200 focus:outline-none" className="mx-auto px-3 py-1 mb-10 rounded bg-gray-100 hover:bg-gray-200 focus:outline-none"
type="submit" type="submit"

View File

@ -1,14 +1,10 @@
import React, { useState, useRef, useContext } from "react"; import React, { useState, useRef, useContext } from "react";
import { isAddress } from "@ethersproject/address";
import { Link, useHistory } from "react-router-dom"; import { Link, useHistory } from "react-router-dom";
import { QrReader } from "@blackbox-vision/react-qr-reader";
import { OnResultFunction } from "@blackbox-vision/react-qr-reader/dist-types/types";
import { BarcodeFormat } from "@zxing/library";
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 { Dialog } from "@headlessui/react";
import useKeyboardShortcut from "use-keyboard-shortcut"; import useKeyboardShortcut from "use-keyboard-shortcut";
import PriceBox from "./PriceBox"; import PriceBox from "./PriceBox";
import CameraScanner from "./search/CameraScanner";
import { RuntimeContext } from "./useRuntime"; import { RuntimeContext } from "./useRuntime";
const Title: React.FC = () => { const Title: React.FC = () => {
@ -37,45 +33,10 @@ const Title: React.FC = () => {
}); });
const [isScanning, setScanning] = useState<boolean>(false); const [isScanning, setScanning] = useState<boolean>(false);
const onScan = () => {
setScanning(true);
};
const evaluateScan: OnResultFunction = (result, error, codeReader) => {
console.log("scan");
if (!error && result?.getBarcodeFormat() === BarcodeFormat.QR_CODE) {
const text = result.getText();
console.log(`Scanned: ${text}`);
if (!isAddress(text)) {
console.log("Not an ETH address");
return;
}
history.push(`/search?q=${text}`);
setScanning(false);
}
};
return ( return (
<> <>
<Dialog {isScanning && <CameraScanner turnOffScan={() => setScanning(false)} />}
className="fixed z-10 inset-0 overflow-y-auto"
open={isScanning}
onClose={() => setScanning(false)}
>
<div className="flex items-center justify-center min-h-screen">
<Dialog.Overlay className="fixed inset-0 bg-black opacity-30" />
<Dialog.Title className="absolute top-0 w-full text-center bg-white text-lg">
Point an ETH address QR code to camera
</Dialog.Title>
<div className="absolute inset-0 bg-transparent rounded min-w-max max-w-3xl w-full h-screen max-h-screen m-auto">
<QrReader
className="m-auto"
constraints={{}}
onResult={evaluateScan}
/>
</div>
</div>
</Dialog>
<div className="px-9 py-2 flex justify-between items-baseline"> <div className="px-9 py-2 flex justify-between items-baseline">
<Link className="self-center" to="/"> <Link className="self-center" to="/">
<div className="text-2xl text-link-blue font-title font-bold flex items-center space-x-2"> <div className="text-2xl text-link-blue font-title font-bold flex items-center space-x-2">
@ -109,7 +70,8 @@ const Title: React.FC = () => {
<button <button
className="border bg-gray-100 hover:bg-gray-200 focus:outline-none px-2 py-1 text-sm text-gray-500" className="border bg-gray-100 hover:bg-gray-200 focus:outline-none px-2 py-1 text-sm text-gray-500"
type="button" type="button"
onClick={onScan} onClick={() => setScanning(true)}
title="Scan an ETH address using your camera"
> >
<FontAwesomeIcon icon={faQrcode} /> <FontAwesomeIcon icon={faQrcode} />
</button> </button>

View File

@ -0,0 +1,54 @@
import React from "react";
import { useHistory } from "react-router-dom";
import { isAddress } from "@ethersproject/address";
import { QrReader } from "@blackbox-vision/react-qr-reader";
import { OnResultFunction } from "@blackbox-vision/react-qr-reader/dist-types/types";
import { BarcodeFormat } from "@zxing/library";
import { Dialog } from "@headlessui/react";
type CameraScannerProps = {
turnOffScan: () => void;
};
const CameraScanner: React.FC<CameraScannerProps> = ({ turnOffScan }) => {
const history = useHistory();
const evaluateScan: OnResultFunction = (result, error, codeReader) => {
console.log("scan");
if (!error && result?.getBarcodeFormat() === BarcodeFormat.QR_CODE) {
const text = result.getText();
console.log(`Scanned: ${text}`);
if (!isAddress(text)) {
console.warn("Not an ETH address");
return;
}
history.push(`/search?q=${text}`);
turnOffScan();
}
};
return (
<Dialog
className="fixed z-10 inset-0 overflow-y-auto"
open={true}
onClose={turnOffScan}
>
<div className="flex items-center justify-center min-h-screen">
<Dialog.Overlay className="fixed inset-0 bg-black opacity-30" />
<Dialog.Title className="absolute top-0 w-full text-center bg-white text-lg">
Point an ETH address QR code to camera
</Dialog.Title>
<div className="absolute inset-0 bg-transparent rounded min-w-max max-w-3xl w-full h-screen max-h-screen m-auto">
<QrReader
className="m-auto"
constraints={{}}
onResult={evaluateScan}
/>
</div>
</div>
</Dialog>
);
};
export default CameraScanner;