diff --git a/assets/css/app.css b/assets/css/app.css index a49b28c5..595dca29 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -832,4 +832,9 @@ div.dataTables_wrapper div.dataTables_info { .darkmode--activated img { mix-blend-mode: difference; +} + +.scanner-video { + max-width: 500px; + max-height: 250px; } \ No newline at end of file diff --git a/assets/ts_src/event_listeners.ts b/assets/ts_src/event_listeners.ts index 25abcbc8..0151266f 100644 --- a/assets/ts_src/event_listeners.ts +++ b/assets/ts_src/event_listeners.ts @@ -23,6 +23,7 @@ import "marked"; import * as marked from "marked"; import "qrcode"; import {parse} from "marked"; +import * as ZXing from "@zxing/library"; /************************************ * @@ -568,6 +569,83 @@ $(document).on("ajaxUI:reload", function() { }) }); +//Init barcode scanner +$(document).on("ajaxUI:start ajaxUI:reload", function() { + + //Skip if we are not on scanner page... + if (!document.getElementById('scan_dialog_form')) { + return; + } + + + let selectedDeviceId; + const codeReader = new ZXing.BrowserMultiFormatReader(); + console.log('ZXing code reader initialized'); + codeReader.listVideoInputDevices() + .then((videoInputDevices) => { + if (videoInputDevices.length >= 1) { + const sourceSelect = document.getElementById('sourceSelect'); + + + videoInputDevices.forEach((element) => { + const sourceOption = document.createElement('option'); + sourceOption.text = element.label; + sourceOption.value = element.deviceId; + sourceSelect.appendChild(sourceOption); + }); + + //Try to retrieve last selected webcam... + let last_cam_id = localStorage.getItem('scanner_last_cam_id'); + if (!!last_cam_id) { + //selectedDeviceId = localStorage.getItem('scanner_last_cam_id'); + $(sourceSelect).val(last_cam_id); + } else { + selectedDeviceId = videoInputDevices[0].deviceId; + } + + sourceSelect.onchange = () => { + //@ts-ignore + selectedDeviceId = sourceSelect.value; + localStorage.setItem('scanner_last_cam_id', selectedDeviceId); + changeHandler(); + }; + + document.getElementById('sourceSelectPanel').classList.remove('d-none'); + document.getElementById('video').classList.remove('d-none'); + document.getElementById('scanner-warning').classList.add('d-none'); + } + + + let changeHandler = () => { + codeReader.reset(); + codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => { + if (result) { + //@ts-ignore + document.getElementById('scan_dialog_input').value = result.text; + //Submit form + //@ts-ignore + document.getElementById('scan_dialog_form').submit(); + } + if (err && !(err instanceof ZXing.NotFoundException)) { + console.error(err); + //document.getElementById('result').textContent = err + } + }); + console.log(`Started continous decode from camera with id ${selectedDeviceId}`) + }; + + //Register Change Src Button + //document.getElementById('changeSrcBtn').addEventListener('click', changeHandler); + + //Try to start logging automatically. + changeHandler(); + + }) + .catch((err) => { + console.error(err) + }) +}); + //Need for proper body padding, with every navbar height $(window).resize(function () { diff --git a/package.json b/package.json index 5f7776e9..41e6746d 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@types/jquery.form": "^3.26.30", "@types/marked": "^0.7.2", "@types/typeahead": "^0.11.32", + "@zxing/library": "^0.16.3", "bootbox": "^5.4.0", "bootstrap-fileinput": "^5.0.1", "bootstrap-select": "^1.13.8", diff --git a/src/Form/LabelSystem/ScanDialogType.php b/src/Form/LabelSystem/ScanDialogType.php index cca128fb..a45d9f93 100644 --- a/src/Form/LabelSystem/ScanDialogType.php +++ b/src/Form/LabelSystem/ScanDialogType.php @@ -34,7 +34,8 @@ class ScanDialogType extends AbstractType $builder->add('input', TextType::class, [ 'attr' => [ 'autofocus' => true, - ] + 'id' => 'scan_dialog_input', + ], ]); $builder->add('submit', SubmitType::class, [ diff --git a/templates/LabelSystem/Scanner/dialog.html.twig b/templates/LabelSystem/Scanner/dialog.html.twig index c077634a..9e5e0503 100644 --- a/templates/LabelSystem/Scanner/dialog.html.twig +++ b/templates/LabelSystem/Scanner/dialog.html.twig @@ -3,7 +3,31 @@ {% block card_title %} {% trans %}label_scanner.title{% endtrans %}{% endblock %} {% block card_content %} - {{ form_start(form) }} +