From 7be73e7f1834bfe7cb60801390815487dc55fe34 Mon Sep 17 00:00:00 2001 From: BenKurrek Date: Sat, 9 Nov 2024 14:25:32 +0700 Subject: [PATCH] fix scanning issues --- src/components/scanner/qr-scanner.tsx | 82 +++++++++++++++------------ src/lib/event.ts | 1 + src/routes/scan.tsx | 19 ++++--- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/components/scanner/qr-scanner.tsx b/src/components/scanner/qr-scanner.tsx index 107eace..729d8f4 100644 --- a/src/components/scanner/qr-scanner.tsx +++ b/src/components/scanner/qr-scanner.tsx @@ -4,10 +4,9 @@ import { isTestEnv } from "@/constants/common"; import { Box } from "@chakra-ui/react"; import { Scanner, useDevices } from "@yudiel/react-qr-scanner"; import { motion } from "framer-motion"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { ErrorBox } from "../ui/error-box"; import { LoadingOverlay } from "./loading-overlay"; -import eventHelperInstance from "@/lib/event"; export const QrScanner = ({ handleScan, @@ -23,44 +22,60 @@ export const QrScanner = ({ const [selectedDevice, setSelectedDevice] = useState( undefined, ); - const [isOnCooldown, setIsOnCooldown] = useState(false); - const [isScanning, setIsScanning] = useState(false); const [showAnimation, setShowAnimation] = useState(false); const devices = useDevices(); - const cooldownDelay = 3000; // Cooldown period after processing (in milliseconds) + // Use refs for scanning logic + const isScanningRef = useRef(false); + const isOnCooldownRef = useRef(false); + + // Use state for triggering re-renders + const [isScanning, setIsScanning] = useState(false); + const [isOnCooldown, setIsOnCooldown] = useState(false); const variants = { open: { x: [0, -50, 50, -50, 50, -50, 50, 0] }, closed: { x: 0 }, }; - const onScan = async (result) => { - if (isOnCooldown || isScanning) return; + const enableCooldown = useCallback(() => { + isOnCooldownRef.current = true; // Set cooldown flag + setIsOnCooldown(true); // Trigger re-render - const value = result[0].rawValue; + setShowAnimation(true); // Optional: Show animation or overlay - setIsScanning(true); + setTimeout(() => { + isOnCooldownRef.current = false; // Reset cooldown flag after 3 seconds + setIsOnCooldown(false); // Trigger re-render + setShowAnimation(false); // Hide animation or overlay + }, 3000); // Cooldown duration in milliseconds + }, []); - try { - await handleScan(value); - } catch (error: any) { - // Errors are handled within handleScan - eventHelperInstance.debugLog(error, "error"); - } finally { - setIsScanning(false); - enableCooldown(); - } - }; + const onScan = useCallback( + async (result: any) => { + if (isOnCooldownRef.current || isScanningRef.current) { + // Ignore scans during cooldown or if already scanning + return; + } - const enableCooldown = () => { - setIsOnCooldown(true); - setShowAnimation(true); - setTimeout(() => { - setIsOnCooldown(false); - setShowAnimation(false); - }, cooldownDelay); - }; + isScanningRef.current = true; // Set scanning flag to true + setIsScanning(true); // Trigger re-render + + const value = result[0]?.rawValue; + + try { + await handleScan(value); + } catch (error) { + // Handle errors + console.error(error); + } finally { + isScanningRef.current = false; // Reset scanning flag + setIsScanning(false); // Trigger re-render + enableCooldown(); // Start cooldown + } + }, + [handleScan, enableCooldown], + ); const useNextDevice = () => { if (devices.length > 0) { @@ -83,18 +98,17 @@ export const QrScanner = ({ // DO NOT REMOVE: Exposes the triggerTestScan function to the window in test environment useEffect(() => { if (isTestEnv) { - // @ts-expect-error - Expose the triggerTestScan function to the window - window.triggerTestScan = (result) => { + // Expose the triggerTestScan function to the window + (window as any).triggerTestScan = (result) => { onScan(result); }; } return () => { if (isTestEnv) { - // @ts-expect-error - Expose the triggerTestScan function to the window - delete window.triggerTestScan; + delete (window as any).triggerTestScan; } }; - }, []); + }, [onScan]); if (!devices) { return ( @@ -163,9 +177,7 @@ export const QrScanner = ({ }, video: { borderRadius: "1rem", - border: `3px solid ${ - showAnimation ? "red" : "var(--green, #00EC97)" - }`, + border: `3px solid var(--green, #00EC97)`, background: "#00ec97", objectFit: "cover", aspectRatio: "1/1", diff --git a/src/lib/event.ts b/src/lib/event.ts index 9d7f6f1..a0f36c2 100644 --- a/src/lib/event.ts +++ b/src/lib/event.ts @@ -505,6 +505,7 @@ class EventJS { isScav: boolean; accountId?: string; }) => { + console.log("claimEventDrop", { secretKey, dropId, dropSecretKey }); const pkToClaim = this.getPubFromSecret(dropSecretKey); this.debugLog(`pkToClaim: ${pkToClaim}`, "log"); diff --git a/src/routes/scan.tsx b/src/routes/scan.tsx index 89079cf..eeabe29 100644 --- a/src/routes/scan.tsx +++ b/src/routes/scan.tsx @@ -16,11 +16,11 @@ import { useEffect, useState } from "react"; import eventHelperInstance from "@/lib/event"; import { useEventCredentials } from "@/stores/event-credentials"; import { useAccountData } from "@/hooks/useAccountData"; -import { LoadingBox } from "@/components/ui/loading-box"; import { ErrorBox } from "@/components/ui/error-box"; import { useExternalLinkModalStore } from "@/stores/external-link-modal"; import { ExternalLinkModal } from "@/components/modals/external-link-modal"; import { CameraAccess } from "@/components/ui/camera-access"; +import { LoadingBox } from "@/components/ui/loading-box"; export default function Scan() { const navigate = useNavigate(); @@ -37,14 +37,10 @@ export default function Scan() { const [statusMessage, setStatusMessage] = useState(""); const handleScan = async (value: string): Promise => { + console.log("Scanning: ", value); + if (!accountId || !secretKey) { - toast({ - title: "Error", - description: "Account information is missing.", - status: "error", - duration: 5000, - isClosable: true, - }); + console.log("Missing credentials"); return; } @@ -127,6 +123,8 @@ export default function Scan() { eventHelperInstance.debugLog(`Scan failed: ${error}`, "error"); setScanStatus("error"); setStatusMessage(`Error scanning QR code: ${error.message || error}`); + } finally { + console.log("Scanning complete"); } }; @@ -152,6 +150,10 @@ export default function Scan() { } }, [scanStatus, statusMessage, toast]); + if (isLoading) { + return ; + } + return ( @@ -171,7 +173,6 @@ export default function Scan() { transform="translateY(-50%)" zIndex={-1} /> - {isLoading && } {isError && }