diff --git a/src/components/Scanner.astro b/src/components/Scanner.astro
index 92f0fb2..706f703 100644
--- a/src/components/Scanner.astro
+++ b/src/components/Scanner.astro
@@ -617,21 +617,38 @@ body {
Point the camera at the barcode or QR code
-
+
+
+
+
import type { ProductAnalysis } from "../types";
import { analyzeProduct } from "../utils/productAnalysis";
+ import { BrowserMultiFormatReader } from "@zxing/library";
- declare global {
- interface Window {
- ZXing: any;
- }
- }
-
- let codeReader: any = null;
+ let codeReader: BrowserMultiFormatReader | null = null;
let scanning = false;
+ let torchEnabled = false;
+ let videoTrack: MediaStreamTrack | null = null;
// Get DOM elements
const initialView = document.getElementById("initial-view")!;
@@ -891,24 +905,19 @@ body {
async function startScanner() {
try {
- if (!window.ZXing) {
- showError("Barcode scanner not yet loaded. Please wait...");
- return;
- }
-
scanning = true;
barcodeDisplay.style.display = "none";
barcodeDisplay.textContent = "";
showView(scannerView);
- codeReader = new window.ZXing.BrowserMultiFormatReader();
+ codeReader = new BrowserMultiFormatReader();
waitForElement('scanner-video', () => {
- codeReader.decodeFromVideoDevice(undefined, 'scanner-video', (result: unknown, err: unknown) => {
+ codeReader!.decodeFromVideoDevice(undefined, 'scanner-video', (result: { getText: Function }, err: unknown) => {
if (result) {
const code = result.getText();
barcodeDisplay.textContent = code;
barcodeDisplay.style.display = "block";
- codeReader.reset();
+ codeReader!.reset();
searchProduct(code);
}
})
@@ -927,9 +936,50 @@ body {
codeReader.reset();
}
scanning = false;
+ torchEnabled = false;
+ videoTrack = null;
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
document
.getElementById("start-scanner-btn")!
@@ -937,6 +987,9 @@ body {
document
.getElementById("stop-scanner-btn")!
.addEventListener("click", stopScanner);
+ document
+ .getElementById("toggle-torch-btn")!
+ .addEventListener("click", toggleTorch);
document.getElementById("error-back-btn")!.addEventListener("click", () => {
showView(initialView);
});