add torch, use zxing library
This commit is contained in:
@@ -617,21 +617,38 @@ body {
|
|||||||
Point the camera at the barcode or QR code
|
Point the camera at the barcode or QR code
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button id="stop-scanner-btn" class="btn btn-cancel">
|
<div style="display: flex; gap: 0.5rem;">
|
||||||
<svg
|
<button id="toggle-torch-btn" class="btn btn-green" style="flex: 1;">
|
||||||
class="icon-sm"
|
<svg
|
||||||
fill="none"
|
class="icon-sm"
|
||||||
stroke="currentColor"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
stroke="currentColor"
|
||||||
>
|
viewBox="0 0 24 24"
|
||||||
<path
|
>
|
||||||
stroke-linecap="round"
|
<path
|
||||||
stroke-linejoin="round"
|
stroke-linecap="round"
|
||||||
stroke-width="2"
|
stroke-linejoin="round"
|
||||||
d="M6 18L18 6M6 6l12 12"></path>
|
stroke-width="2"
|
||||||
</svg>
|
d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"></path>
|
||||||
Cancel
|
</svg>
|
||||||
</button>
|
Torch
|
||||||
|
</button>
|
||||||
|
<button id="stop-scanner-btn" class="btn btn-cancel" style="flex: 1;">
|
||||||
|
<svg
|
||||||
|
class="icon-sm"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M6 18L18 6M6 6l12 12"></path>
|
||||||
|
</svg>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -659,15 +676,12 @@ body {
|
|||||||
<script>
|
<script>
|
||||||
import type { ProductAnalysis } from "../types";
|
import type { ProductAnalysis } from "../types";
|
||||||
import { analyzeProduct } from "../utils/productAnalysis";
|
import { analyzeProduct } from "../utils/productAnalysis";
|
||||||
|
import { BrowserMultiFormatReader } from "@zxing/library";
|
||||||
|
|
||||||
declare global {
|
let codeReader: BrowserMultiFormatReader | null = null;
|
||||||
interface Window {
|
|
||||||
ZXing: any;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let codeReader: any = null;
|
|
||||||
let scanning = false;
|
let scanning = false;
|
||||||
|
let torchEnabled = false;
|
||||||
|
let videoTrack: MediaStreamTrack | null = null;
|
||||||
|
|
||||||
// Get DOM elements
|
// Get DOM elements
|
||||||
const initialView = document.getElementById("initial-view")!;
|
const initialView = document.getElementById("initial-view")!;
|
||||||
@@ -891,24 +905,19 @@ body {
|
|||||||
|
|
||||||
async function startScanner() {
|
async function startScanner() {
|
||||||
try {
|
try {
|
||||||
if (!window.ZXing) {
|
|
||||||
showError("Barcode scanner not yet loaded. Please wait...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
scanning = true;
|
scanning = true;
|
||||||
barcodeDisplay.style.display = "none";
|
barcodeDisplay.style.display = "none";
|
||||||
barcodeDisplay.textContent = "";
|
barcodeDisplay.textContent = "";
|
||||||
showView(scannerView);
|
showView(scannerView);
|
||||||
|
|
||||||
codeReader = new window.ZXing.BrowserMultiFormatReader();
|
codeReader = new BrowserMultiFormatReader();
|
||||||
waitForElement('scanner-video', () => {
|
waitForElement('scanner-video', () => {
|
||||||
codeReader.decodeFromVideoDevice(undefined, 'scanner-video', (result: unknown, err: unknown) => {
|
codeReader!.decodeFromVideoDevice(undefined, 'scanner-video', (result: { getText: Function }, err: unknown) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
const code = result.getText();
|
const code = result.getText();
|
||||||
barcodeDisplay.textContent = code;
|
barcodeDisplay.textContent = code;
|
||||||
barcodeDisplay.style.display = "block";
|
barcodeDisplay.style.display = "block";
|
||||||
codeReader.reset();
|
codeReader!.reset();
|
||||||
searchProduct(code);
|
searchProduct(code);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -927,9 +936,50 @@ body {
|
|||||||
codeReader.reset();
|
codeReader.reset();
|
||||||
}
|
}
|
||||||
scanning = false;
|
scanning = false;
|
||||||
|
torchEnabled = false;
|
||||||
|
videoTrack = null;
|
||||||
showView(initialView);
|
showView(initialView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleTorch() {
|
||||||
|
try {
|
||||||
|
if (!videoTrack) {
|
||||||
|
const videoElement = document.getElementById('scanner-video') as HTMLVideoElement;
|
||||||
|
if (videoElement && videoElement.srcObject) {
|
||||||
|
const stream = videoElement.srcObject as MediaStream;
|
||||||
|
const tracks = stream.getVideoTracks();
|
||||||
|
if (tracks.length > 0) {
|
||||||
|
videoTrack = tracks[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!videoTrack) {
|
||||||
|
console.error('No video track available');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const capabilities = videoTrack.getCapabilities() as any;
|
||||||
|
if (!capabilities.torch) {
|
||||||
|
showError('Torch is not supported on this device');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
torchEnabled = !torchEnabled;
|
||||||
|
await videoTrack.applyConstraints({
|
||||||
|
advanced: [{ torch: torchEnabled } as any]
|
||||||
|
});
|
||||||
|
|
||||||
|
const torchBtn = document.getElementById('toggle-torch-btn');
|
||||||
|
if (torchBtn) {
|
||||||
|
torchBtn.textContent = torchEnabled ? 'Torch On' : 'Torch Off';
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error toggling torch:', err);
|
||||||
|
showError('Could not toggle torch. Feature may not be supported.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Event listeners
|
// Event listeners
|
||||||
document
|
document
|
||||||
.getElementById("start-scanner-btn")!
|
.getElementById("start-scanner-btn")!
|
||||||
@@ -937,6 +987,9 @@ body {
|
|||||||
document
|
document
|
||||||
.getElementById("stop-scanner-btn")!
|
.getElementById("stop-scanner-btn")!
|
||||||
.addEventListener("click", stopScanner);
|
.addEventListener("click", stopScanner);
|
||||||
|
document
|
||||||
|
.getElementById("toggle-torch-btn")!
|
||||||
|
.addEventListener("click", toggleTorch);
|
||||||
document.getElementById("error-back-btn")!.addEventListener("click", () => {
|
document.getElementById("error-back-btn")!.addEventListener("click", () => {
|
||||||
showView(initialView);
|
showView(initialView);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user