diff --git a/js/scanner.js b/js/scanner.js
index 7274781..1462209 100644
--- a/js/scanner.js
+++ b/js/scanner.js
@@ -27,6 +27,7 @@
let currentProduct = null;
let selectedSupplier = null;
let allSuppliers = [];
+ let quaggaInitialized = false;
// DOM Elements (will be set on init)
let elements = {};
@@ -48,10 +49,54 @@
return;
}
+ // Check for camera support
+ checkCameraSupport();
+
bindEvents();
loadAllSuppliers();
}
+ // Check camera support and show appropriate messages
+ function checkCameraSupport() {
+ // Check HTTPS (required for camera access except on localhost)
+ // Note: In test environments without HTTPS, camera may not work but we still allow trying
+ const isSecure = location.protocol === 'https:' || location.hostname === 'localhost' || location.hostname === '127.0.0.1';
+
+ if (!isSecure) {
+ // Show warning but don't disable - some browsers/configs may still work
+ console.warn('HandyBarcodeScanner: HTTPS empfohlen für Kamerazugriff');
+ }
+
+ // Check if getUserMedia is supported
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
+ showCameraError('Kamera wird von diesem Browser nicht unterstützt');
+ elements.startBtn.disabled = true;
+ elements.startBtn.classList.add('butActionRefused');
+ elements.startBtn.classList.remove('butAction');
+ return;
+ }
+
+ // Check if Quagga is loaded
+ if (typeof Quagga === 'undefined') {
+ showCameraError('Scanner-Bibliothek nicht geladen');
+ elements.startBtn.disabled = true;
+ elements.startBtn.classList.add('butActionRefused');
+ elements.startBtn.classList.remove('butAction');
+ return;
+ }
+
+ // All checks passed - enable button
+ elements.startBtn.disabled = false;
+ }
+
+ function showCameraError(message) {
+ const errorDiv = document.createElement('div');
+ errorDiv.className = 'error-message';
+ errorDiv.style.cssText = 'position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #fff; text-align: center; padding: 20px;';
+ errorDiv.innerHTML = '
⚠️
' + message + '
';
+ elements.videoContainer.appendChild(errorDiv);
+ }
+
// Event Bindings
function bindEvents() {
elements.startBtn.addEventListener('click', startScanner);
@@ -73,6 +118,7 @@
// Scanner Functions
function startScanner() {
if (isScanning) return;
+ if (elements.startBtn.disabled) return;
// Check if Quagga is available
if (typeof Quagga === 'undefined') {
@@ -80,6 +126,10 @@
return;
}
+ // Disable button while initializing
+ elements.startBtn.disabled = true;
+ elements.startBtn.textContent = 'Initialisiere...';
+
Quagga.init({
inputStream: {
name: "Live",
@@ -87,8 +137,8 @@
target: elements.videoContainer,
constraints: {
facingMode: "environment",
- width: { ideal: 1280 },
- height: { ideal: 720 }
+ width: { min: 640, ideal: 1280, max: 1920 },
+ height: { min: 480, ideal: 720, max: 1080 }
}
},
decoder: {
@@ -104,25 +154,48 @@
}, function(err) {
if (err) {
console.error('Quagga init error:', err);
- showToast(CONFIG.lang.cameraError, 'error');
+ elements.startBtn.disabled = false;
+ elements.startBtn.textContent = CONFIG.lang.startScan || 'Scan starten';
+
+ // Show specific error message
+ let errorMsg = CONFIG.lang.cameraError || 'Kamerafehler';
+ if (err.name === 'NotAllowedError') {
+ errorMsg = 'Kamerazugriff verweigert. Bitte Berechtigung erteilen.';
+ } else if (err.name === 'NotFoundError') {
+ errorMsg = 'Keine Kamera gefunden.';
+ } else if (err.name === 'NotReadableError') {
+ errorMsg = 'Kamera wird bereits verwendet.';
+ }
+ showToast(errorMsg, 'error');
return;
}
+
+ // Success - start scanning
Quagga.start();
+ quaggaInitialized = true;
isScanning = true;
elements.startBtn.classList.add('hidden');
elements.stopBtn.classList.remove('hidden');
elements.videoContainer.classList.add('scanning');
- });
- Quagga.onDetected(onBarcodeDetected);
+ // Register detection handler
+ Quagga.onDetected(onBarcodeDetected);
+ });
}
function stopScanner() {
if (!isScanning) return;
- Quagga.stop();
+ if (quaggaInitialized) {
+ Quagga.offDetected(onBarcodeDetected);
+ Quagga.stop();
+ }
+
isScanning = false;
+ quaggaInitialized = false;
elements.startBtn.classList.remove('hidden');
+ elements.startBtn.disabled = false;
+ elements.startBtn.textContent = CONFIG.lang.startScan || 'Scan starten';
elements.stopBtn.classList.add('hidden');
elements.videoContainer.classList.remove('scanning');
}