Added qr scanner
This commit is contained in:
@@ -1,58 +1,78 @@
|
||||
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.html5QrCode = null;
|
||||
this.qrScanner = null;
|
||||
}
|
||||
|
||||
// Öffnet das Modal und startet den Kamera-Stream
|
||||
startCamera(event) {
|
||||
event.preventDefault();
|
||||
|
||||
// Modal anzeigen
|
||||
// 1. Modal anzeigen
|
||||
this.modalTarget.classList.remove("hidden");
|
||||
|
||||
// Neue Instanz auf dem Preview-Div mit der ID des Elements erzeugen
|
||||
this.html5QrCode = new Html5Qrcode(this.previewTarget.id);
|
||||
// 2. Ein HTML5 <video> Element holen oder erstellen (wird für den Stream gebraucht)
|
||||
const videoElement = this.previewTarget.querySelector("video") || this.createVideoElement();
|
||||
|
||||
// FPS-Rate und Scan-Rahmen (250x250px) festlegen
|
||||
const config = { fps: 10, qrbox: { width: 250, height: 250 } };
|
||||
// 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
|
||||
}
|
||||
);
|
||||
|
||||
this.html5QrCode
|
||||
.start(
|
||||
{ facingMode: "environment" }, // Erzwingt die rückseitige Hauptkamera bei Handys
|
||||
config,
|
||||
(decodedText, decodedResult) => {
|
||||
// SUCCESS: Code erkannt!
|
||||
this.inputTarget.value = decodedText; // Trägt die ID (z.B. 10024) ins Textfeld ein
|
||||
|
||||
// NEU: Simuliert das Tippen, damit dein search-form Controller die Live-Suche sofort startet!
|
||||
this.inputTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
|
||||
this.stopCamera(); // Stoppt die Kamera und schließt das Fenster
|
||||
},
|
||||
(errorMessage) => {
|
||||
// Kontinuierlicher Scan-Loop (Fehler ignorieren, wenn kein QR-Code im Bild ist)
|
||||
},
|
||||
)
|
||||
.catch((err) => {
|
||||
console.error("Kamera-Zugriff verweigert oder blockiert:", err);
|
||||
});
|
||||
// 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");
|
||||
});
|
||||
}
|
||||
|
||||
// Schließt das Modal und beendet den Stream sauber
|
||||
// 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.html5QrCode && this.html5QrCode.isScanning) {
|
||||
this.html5QrCode
|
||||
.stop()
|
||||
.then(() => {
|
||||
this.modalTarget.classList.add("hidden");
|
||||
})
|
||||
.catch((err) => console.error("Fehler beim Beenden des Streams:", err));
|
||||
} else {
|
||||
this.modalTarget.classList.add("hidden");
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user