feat(qr-scanner): integrate jsQR for QR code scanning fallback
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
QrCode,
|
||||
Xmark,
|
||||
} from "@gravity-ui/icons";
|
||||
import jsQR from "jsqr";
|
||||
import { api } from "@/lib/api";
|
||||
import dayjs from "@/lib/dayjs";
|
||||
|
||||
@@ -155,20 +156,34 @@ function QrScanner({ onResult, onClose }: ScannerProps) {
|
||||
|
||||
if (!mountedRef.current) return;
|
||||
|
||||
if (!("BarcodeDetector" in window)) {
|
||||
if (mountedRef.current) setError("当前浏览器不支持实时扫描,请升级至最新版本");
|
||||
return;
|
||||
const useNative = "BarcodeDetector" in window;
|
||||
if (useNative) {
|
||||
detector = new (window as any).BarcodeDetector({ formats: ["qr_code"] });
|
||||
}
|
||||
|
||||
detector = new (window as any).BarcodeDetector({ formats: ["qr_code"] });
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const scan = async () => {
|
||||
if (!scanningRef.current || !videoRef.current) return;
|
||||
try {
|
||||
const codes: Array<{ rawValue: string }> = await detector.detect(videoRef.current);
|
||||
if (codes.length > 0) {
|
||||
onResult(codes[0].rawValue);
|
||||
return;
|
||||
if (useNative) {
|
||||
const codes: Array<{ rawValue: string }> = await detector.detect(videoRef.current);
|
||||
if (codes.length > 0) {
|
||||
onResult(codes[0].rawValue);
|
||||
return;
|
||||
}
|
||||
} else if (ctx) {
|
||||
const video = videoRef.current;
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
ctx.drawImage(video, 0, 0);
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
const code = jsQR(imageData.data, imageData.width, imageData.height);
|
||||
if (code) {
|
||||
onResult(code.data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
requestAnimationFrame(scan);
|
||||
@@ -411,8 +426,7 @@ function ChargePageContent() {
|
||||
.filter((cp) => cp.registrationStatus === "Accepted")
|
||||
.map((cp) => {
|
||||
const online =
|
||||
!!cp.lastHeartbeatAt &&
|
||||
dayjs().diff(dayjs(cp.lastHeartbeatAt), "second") < 120;
|
||||
!!cp.lastHeartbeatAt && dayjs().diff(dayjs(cp.lastHeartbeatAt), "second") < 120;
|
||||
const availableCount = cp.connectors.filter(
|
||||
(c) => c.status === "Available",
|
||||
).length;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"@types/qrcode": "^1.5.6",
|
||||
"better-auth": "catalog:",
|
||||
"dayjs": "catalog:",
|
||||
"jsqr": "^1.4.0",
|
||||
"next": "16.1.6",
|
||||
"qrcode.react": "^4.2.0",
|
||||
"react": "19.2.3",
|
||||
|
||||
Reference in New Issue
Block a user