Move BarcodeScanner to colocated hook
This commit is contained in:
@@ -23,14 +23,12 @@ import { LiveSocket } from "phoenix_live_view";
|
|||||||
import { hooks as colocatedHooks } from "phoenix-colocated/music_library";
|
import { hooks as colocatedHooks } from "phoenix-colocated/music_library";
|
||||||
import topbar from "../vendor/topbar";
|
import topbar from "../vendor/topbar";
|
||||||
import { Hooks as FluxonHooks, DOM as FluxonDOM } from "fluxon";
|
import { Hooks as FluxonHooks, DOM as FluxonDOM } from "fluxon";
|
||||||
import BarcodeScannerHook from "./hooks/barcode-scanner";
|
|
||||||
import FormatNumberHook from "./hooks/format-number";
|
import FormatNumberHook from "./hooks/format-number";
|
||||||
import confetti from "canvas-confetti";
|
import confetti from "canvas-confetti";
|
||||||
import { createLiveToastHook } from "live_toast";
|
import { createLiveToastHook } from "live_toast";
|
||||||
import banner from "./banner";
|
import banner from "./banner";
|
||||||
|
|
||||||
let Hooks = FluxonHooks;
|
let Hooks = FluxonHooks;
|
||||||
Hooks.BarcodeScanner = BarcodeScannerHook;
|
|
||||||
Hooks.FormatNumber = FormatNumberHook;
|
Hooks.FormatNumber = FormatNumberHook;
|
||||||
Hooks.LiveToast = createLiveToastHook();
|
Hooks.LiveToast = createLiveToastHook();
|
||||||
|
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
import { BarcodeDetector } from "barcode-detector/ponyfill";
|
|
||||||
|
|
||||||
const barcodeReaderSetup = async function () {
|
|
||||||
const supportedFormats = await BarcodeDetector.getSupportedFormats();
|
|
||||||
|
|
||||||
return new BarcodeDetector({
|
|
||||||
// make sure the formats are supported
|
|
||||||
formats: supportedFormats,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
async mounted() {
|
|
||||||
const detectedBarcodes = new Set([]);
|
|
||||||
const barcodeDetector = await barcodeReaderSetup();
|
|
||||||
this.cameraPreview = this.el.querySelector("#camera-preview");
|
|
||||||
const constraints = {
|
|
||||||
audio: false,
|
|
||||||
video: {
|
|
||||||
width: 800,
|
|
||||||
height: 600,
|
|
||||||
facingMode: {
|
|
||||||
ideal: "environment",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.el.addEventListener("camera_request", () => {
|
|
||||||
navigator.mediaDevices
|
|
||||||
.getUserMedia(constraints)
|
|
||||||
.then((mediaStream) => {
|
|
||||||
console.debug("Camera access allowed");
|
|
||||||
this.pushEventTo(this.el, "camera_allowed", {});
|
|
||||||
this.cameraPreview.srcObject = mediaStream;
|
|
||||||
this.cameraPreview.onloadedmetadata = () => {
|
|
||||||
this.cameraPreview.play();
|
|
||||||
this.scanInterval = window.setInterval(async () => {
|
|
||||||
const barcodes = await barcodeDetector.detect(this.cameraPreview);
|
|
||||||
if (barcodes.length <= 0) return;
|
|
||||||
|
|
||||||
barcodes.forEach((barcode) => {
|
|
||||||
if (!detectedBarcodes.has(barcode.rawValue)) {
|
|
||||||
this.pushEventTo(this.el, "barcode_scanned", {
|
|
||||||
number: barcode.rawValue,
|
|
||||||
});
|
|
||||||
detectedBarcodes.add(barcode.rawValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 500);
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error(`${err.name}: ${err.message}`);
|
|
||||||
this.pushEventTo(this.el, "camera_denied", {});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
if (this.cameraPreview.srcObject) {
|
|
||||||
this.cameraPreview.srcObject.getTracks().forEach((track) => track.stop());
|
|
||||||
window.clearInterval(this.scanInterval);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -19,7 +19,7 @@ defmodule MusicLibraryWeb.BarcodeScannerComponent do
|
|||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="min-w-72" id="barcode-scanner" phx-hook="BarcodeScanner" phx-target={@myself}>
|
<div class="min-w-72" id="barcode-scanner" phx-hook=".BarcodeScanner" phx-target={@myself}>
|
||||||
<header>
|
<header>
|
||||||
<h1 class="text-sm font-medium leading-6 text-zinc-700 dark:text-zinc-400">
|
<h1 class="text-sm font-medium leading-6 text-zinc-700 dark:text-zinc-400">
|
||||||
{gettext("Scan one or more barcodes")}
|
{gettext("Scan one or more barcodes")}
|
||||||
@@ -57,6 +57,72 @@ defmodule MusicLibraryWeb.BarcodeScannerComponent do
|
|||||||
{gettext("Add releases")}
|
{gettext("Add releases")}
|
||||||
</.button>
|
</.button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script :type={Phoenix.LiveView.ColocatedHook} name=".BarcodeScanner">
|
||||||
|
import { BarcodeDetector } from "barcode-detector/ponyfill";
|
||||||
|
|
||||||
|
const barcodeReaderSetup = async function () {
|
||||||
|
const supportedFormats = await BarcodeDetector.getSupportedFormats();
|
||||||
|
|
||||||
|
return new BarcodeDetector({
|
||||||
|
// make sure the formats are supported
|
||||||
|
formats: supportedFormats,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async mounted() {
|
||||||
|
const detectedBarcodes = new Set([]);
|
||||||
|
const barcodeDetector = await barcodeReaderSetup();
|
||||||
|
this.cameraPreview = this.el.querySelector("#camera-preview");
|
||||||
|
const constraints = {
|
||||||
|
audio: false,
|
||||||
|
video: {
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
facingMode: {
|
||||||
|
ideal: "environment",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.el.addEventListener("camera_request", () => {
|
||||||
|
navigator.mediaDevices
|
||||||
|
.getUserMedia(constraints)
|
||||||
|
.then((mediaStream) => {
|
||||||
|
console.debug("Camera access allowed");
|
||||||
|
this.pushEventTo(this.el, "camera_allowed", {});
|
||||||
|
this.cameraPreview.srcObject = mediaStream;
|
||||||
|
this.cameraPreview.onloadedmetadata = () => {
|
||||||
|
this.cameraPreview.play();
|
||||||
|
this.scanInterval = window.setInterval(async () => {
|
||||||
|
const barcodes = await barcodeDetector.detect(this.cameraPreview);
|
||||||
|
if (barcodes.length <= 0) return;
|
||||||
|
|
||||||
|
barcodes.forEach((barcode) => {
|
||||||
|
if (!detectedBarcodes.has(barcode.rawValue)) {
|
||||||
|
this.pushEventTo(this.el, "barcode_scanned", {
|
||||||
|
number: barcode.rawValue,
|
||||||
|
});
|
||||||
|
detectedBarcodes.add(barcode.rawValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(`${err.name}: ${err.message}`);
|
||||||
|
this.pushEventTo(this.el, "camera_denied", {});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
if (this.cameraPreview.srcObject) {
|
||||||
|
this.cameraPreview.srcObject.getTracks().forEach((track) => track.stop());
|
||||||
|
window.clearInterval(this.scanInterval);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user