import React, {useEffect, useMemo, useRef, useState} from 'react'; import {BrowserMultiFormatReader, NotFoundException} from "@zxing/library"; import {Icon, Modal, Spinner} from "@wordpress/components"; import type {FieldProps} from "./Field"; import {closeSmall} from "@wordpress/icons"; import {__} from "@wordpress/i18n"; type ScannerProps = FieldProps & { attrs: Record onResult: (val: string) => void; onError: (err: string) => void; } function VideoAppend({isOpen, element}: { isOpen: boolean; element: HTMLVideoElement }) { const divRef = useRef(null); useEffect(() => { if (!isOpen) { return; } const videoElement = element; videoElement.autoplay = false; videoElement.muted = true; videoElement.playsInline = true; videoElement.classList.add('hulk-video'); divRef.current?.appendChild(videoElement); }, [element, isOpen]); return
} const Scanner = (props: ScannerProps) => { const codeReader = useRef(new BrowserMultiFormatReader()); const videoRef = useRef(document.createElement("video")); const [isOpen, setOpen] = useState(false); const openModal = () => setOpen(true); const closeModal = () => { codeReader.current.reset(); setOpen(false); }; const [loading, setLoading] = useState(false); const icon = useMemo(() => decodeURIComponent(props.icon), [props.icon]); const handleIcon = async (e: React.MouseEvent) => { e.preventDefault(); if (!props.freemius.can_use_premium_code) { return; } setLoading(true); try { const videoInputDevices = await codeReader.current.listVideoInputDevices(); if (videoInputDevices.length === 0) { props.onError(__('No camera found.', 'advanced-fields-for-elementor-forms')); return; } // Find the back camera const backCamera = videoInputDevices .find(device => device.label.toLowerCase().includes('back')); const firstDeviceId = backCamera?.deviceId || videoInputDevices?.[0]?.deviceId; await codeReader.current.decodeFromVideoDevice( firstDeviceId, videoRef.current, (decodedResult, decodeError) => { if (decodedResult) { closeModal(); props.onResult(decodedResult.getText()); } if (decodeError && !(decodeError instanceof NotFoundException)) { props.onError(decodeError?.message || JSON.stringify(decodeError)); } } ); openModal(); } catch (err: any) { codeReader.current.reset(); props.onError(err?.message || JSON.stringify(err)); } finally { setLoading(false); } }; return ( <> {isOpen && (
)} {loading ? (
) : (