mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 01:25:55 +02:00
Integrated barcode scanner via Webcam.
This commit is contained in:
parent
1812e6f5bc
commit
48f4a360f4
6 changed files with 123 additions and 2 deletions
|
@ -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;
|
||||
}
|
|
@ -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 () {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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, [
|
||||
|
|
|
@ -3,7 +3,31 @@
|
|||
{% block card_title %}<i class="fas fa-atom fa-fw"></i> {% trans %}label_scanner.title{% endtrans %}{% endblock %}
|
||||
|
||||
{% block card_content %}
|
||||
{{ form_start(form) }}
|
||||
<div class="alert alert-warning" id="scanner-warning">
|
||||
<strong>{% trans %}label_scanner.no_cam_found.title{% endtrans %}</strong>: {% trans %}label_scanner.no_cam_found.text{% endtrans %}
|
||||
</div>
|
||||
|
||||
{{ form_start(form, {'attr': {'id': 'scan_dialog_form'}}) }}
|
||||
|
||||
{{ form_end(form) }}
|
||||
|
||||
<div class="">
|
||||
<div class="form-group row">
|
||||
<div class="offset-sm-3 col-sm-9">
|
||||
<video id="video" width="100%" height="auto" class="scanner-video img-thumbnail d-none">
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# <div>
|
||||
<button type="button" class="btn btn-secondary" id="changeSrcBtn">Change Source</button>
|
||||
</div>#}
|
||||
|
||||
<div id="sourceSelectPanel" class="form-group row d-none">
|
||||
<label for="sourceSelect" class="col-sm-3 col-form-label">{% trans %}label_scanner.source_select{% endtrans %}</label>
|
||||
<div class="col-sm-9">
|
||||
<select id="sourceSelect" style="" class="form-control"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -1018,6 +1018,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
||||
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
||||
|
||||
"@zxing/library@^0.16.3":
|
||||
version "0.16.3"
|
||||
resolved "https://registry.yarnpkg.com/@zxing/library/-/library-0.16.3.tgz#3d9d2a031f03b01b67ee6defc232aae106329f84"
|
||||
integrity sha512-GjhP1eWfj76fn8JnipDXKEErgfNJO8CJb0bEgkZ14RLSo1z2U1wD7RUt609oRWYYq2gPQfK3X+Z159K4ecNzHQ==
|
||||
dependencies:
|
||||
ts-custom-error "^3.0.0"
|
||||
|
||||
accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
|
||||
|
@ -6686,6 +6693,11 @@ toidentifier@1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||
|
||||
ts-custom-error@^3.0.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-3.1.1.tgz#d30c7415461dac93dc2cc9e9eb2dae92e6423901"
|
||||
integrity sha512-f/syoy+pTE4z82qaiRuthEeZtCGNKzlfs0Zc8jpQFcz/CYMaFSwFSdfFt1sSFnPlDLOEm7RCROdIxZ44N8UlwA==
|
||||
|
||||
ts-loader@^5.3.0:
|
||||
version "5.4.5"
|
||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.4.5.tgz#a0c1f034b017a9344cef0961bfd97cc192492b8b"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue