import React, { useState, ReactNode, useRef, useEffect } from "react";
import { css } from "emotion";
import MixedScanner from "./mixed-scanner";
type FuncDetectedCode = (code: string, codeType: "qrcode" | "barcode") => void;
export let usePopupMixedScanner = (props: {
errorLocale?: string;
/** 预览扫码结果时长 */
previewTime?: number;
onCodeDetected?: FuncDetectedCode;
onScanFinish?: (info: { scanCost: number }) => void;
}) => {
// Model
let [scanning, setScanning] = useState(false);
let [tempResult, setTempResult] = useState(null);
let callbackRef = useRef(undefined as FuncDetectedCode);
// Plugins
// Effects
useEffect(() => {
let listener = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setScanning(false);
}
};
window.addEventListener("keydown", listener);
return () => {
window.removeEventListener("keydown", listener);
};
}, []);
// View
let maxWidth = document.documentElement.clientWidth;
let maxHeight = document.documentElement.clientHeight;
let estimatedSize = Math.min(480, Math.min(maxWidth, maxHeight) - 32);
let ui = scanning ? (
{
setTempResult(code);
setTimeout(() => {
if (callbackRef.current != null) {
callbackRef.current(code, codeType);
callbackRef.current = null;
}
if (props.onCodeDetected != null) {
props.onCodeDetected(code, codeType);
}
setScanning(false);
}, props.previewTime || 800);
}}
/>
{tempResult != null ? {tempResult}
: null}
{
setScanning(false);
}}
>
✕
) : null;
// Controller
let popup = (callback?: FuncDetectedCode) => {
setTempResult(null);
setScanning(true);
callbackRef.current = callback;
};
let close = () => {
setScanning(false);
};
return { ui, popup, close };
};
let styleContainer = css`
z-index: 200; /* same as barcode popup */
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.65);
display: flex;
`;
let styleClose = css`
position: fixed;
top: 16px;
right: 16px;
font-size: 24px;
cursor: pointer;
color: white;
font-family: Arial, Helvetica, sans-serif;
`;
let styleScanner = css`
margin-left: auto;
margin-right: auto;
margin-top: 20%;
margin-top: min(80px, 20%);
margin-bottom: auto;
position: relative;
`;
let styleTempResult = css`
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 16px;
font-size: 20px;
text-align: center;
font-family: Source Code Pro, Menlo, Roboto Mono, Consolas, monospace;
color: white;
background-color: hsl(0, 0%, 0%, 0.4);
`;