79 lines
2.3 KiB
JavaScript
79 lines
2.3 KiB
JavaScript
import { Controller } from "@hotwired/stimulus";
|
|
import QrScanner from "qr-scanner"; // Importiert das saubere, einzelne Modul
|
|
|
|
export default class extends Controller {
|
|
static targets = ["input", "preview", "modal"];
|
|
|
|
connect() {
|
|
this.qrScanner = null;
|
|
}
|
|
|
|
// Öffnet das Modal und startet den Kamera-Stream
|
|
startCamera(event) {
|
|
event.preventDefault();
|
|
|
|
// 1. Modal anzeigen
|
|
this.modalTarget.classList.remove("hidden");
|
|
|
|
// 2. Ein HTML5 <video> Element holen oder erstellen (wird für den Stream gebraucht)
|
|
const videoElement = this.previewTarget.querySelector("video") || this.createVideoElement();
|
|
|
|
// 3. Scanner initialisieren
|
|
this.qrScanner = new QrScanner(
|
|
videoElement,
|
|
(result) => {
|
|
// SUCCESS: Code erkannt!
|
|
this.handleScanSuccess(result.data);
|
|
},
|
|
{
|
|
onDecodeError: (error) => { /* Loop-Fehler während der Suche ignorieren */ },
|
|
highlightScanRegion: true, // Zeichnet einen schicken gelben/grünen Scan-Rahmen ins Bild
|
|
highlightCodeOutline: true,
|
|
maxScansPerSecond: 10
|
|
}
|
|
);
|
|
|
|
// 4. Kamera starten
|
|
this.qrScanner.start().catch((err) => {
|
|
alert("Kamera-Zugriff verweigert, blockiert oder unverschlüsselte Verbindung!");
|
|
console.error("Kamera-Fehler:", err);
|
|
this.modalTarget.classList.add("hidden");
|
|
});
|
|
}
|
|
|
|
// Verarbeitet die gescannte ID und startet das search-form
|
|
handleScanSuccess(decodedText) {
|
|
this.inputTarget.value = decodedText;
|
|
|
|
// Simuliert das Tippen für deinen Live-Filter
|
|
this.inputTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
|
|
|
this.stopCamera();
|
|
}
|
|
|
|
// Beendet den Stream sauber und schließt das Fenster
|
|
stopCamera() {
|
|
if (this.qrScanner) {
|
|
this.qrScanner.stop();
|
|
this.qrScanner.destroy();
|
|
this.qrScanner = null;
|
|
}
|
|
this.modalTarget.classList.add("hidden");
|
|
}
|
|
|
|
// Hilfsmethode: Erstellt das Video-Tag im Vorschau-Fenster
|
|
createVideoElement() {
|
|
const video = document.createElement("video");
|
|
video.autoplay = true;
|
|
video.muted = true;
|
|
video.playsInline = true;
|
|
video.className = "w-full h-full object-cover rounded-xl";
|
|
this.previewTarget.appendChild(video);
|
|
return video;
|
|
}
|
|
|
|
disconnect() {
|
|
this.stopCamera();
|
|
}
|
|
}
|