mirror of
https://github.com/grocy/grocy.git
synced 2025-08-21 04:43:32 +00:00
Replaced barcode scanning library with ZXing (#2706)
* Replaced barcode scanning library with ZXing * Applied code formatting rules * Delete now obsolete user settings * Review --------- Co-authored-by: Bernd Bestel <bernd@berrnd.de>
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
Grocy.Components.CameraBarcodeScanner = {};
|
||||
|
||||
Grocy.Components.CameraBarcodeScanner.Scanner = null;
|
||||
Grocy.Components.CameraBarcodeScanner.LiveVideoSizeAdjusted = false;
|
||||
Grocy.Components.CameraBarcodeScanner.CameraSelectLoaded = false;
|
||||
Grocy.Components.CameraBarcodeScanner.TorchIsOn = false;
|
||||
|
||||
Grocy.Components.CameraBarcodeScanner.CheckCapabilities = async function()
|
||||
{
|
||||
var track = Quagga.CameraAccess.getActiveTrack();
|
||||
var track = Grocy.Components.CameraBarcodeScanner.Scanner.stream.getVideoTracks()[0];
|
||||
var capabilities = {};
|
||||
if (typeof track.getCapabilities === 'function')
|
||||
{
|
||||
@@ -17,7 +18,7 @@ Grocy.Components.CameraBarcodeScanner.CheckCapabilities = async function()
|
||||
if (!Grocy.Components.CameraBarcodeScanner.CameraSelectLoaded)
|
||||
{
|
||||
var cameraSelect = document.querySelector('.cameraSelect');
|
||||
var cameras = await Quagga.CameraAccess.enumerateVideoDevices();
|
||||
var cameras = await Grocy.Components.CameraBarcodeScanner.Scanner.listVideoInputDevices();
|
||||
cameras.forEach(camera =>
|
||||
{
|
||||
var option = document.createElement("option");
|
||||
@@ -46,7 +47,7 @@ Grocy.Components.CameraBarcodeScanner.CheckCapabilities = async function()
|
||||
document.querySelector('.camerabarcodescanner-modal .modal-footer').setAttribute('style', 'flex;');
|
||||
}
|
||||
|
||||
// Reduce the height of the video, if it's higher than then the viewport
|
||||
// Reduce the height of the video if it's higher than the viewport
|
||||
if (!Grocy.Components.CameraBarcodeScanner.LiveVideoSizeAdjusted)
|
||||
{
|
||||
var bc = document.getElementById('camerabarcodescanner-container');
|
||||
@@ -56,13 +57,11 @@ Grocy.Components.CameraBarcodeScanner.CheckCapabilities = async function()
|
||||
var settings = track.getSettings();
|
||||
if (bcAspectRatio > settings.aspectRatio)
|
||||
{
|
||||
var v = document.querySelector('#camerabarcodescanner-livestream video');
|
||||
var v = document.querySelector('#camerabarcodescanner-livestream');
|
||||
if (v)
|
||||
{
|
||||
var c = document.querySelector('#camerabarcodescanner-livestream canvas')
|
||||
var newWidth = v.clientWidth / bcAspectRatio * settings.aspectRatio + 'px';
|
||||
v.style.width = newWidth;
|
||||
c.style.width = newWidth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,65 +72,35 @@ Grocy.Components.CameraBarcodeScanner.CheckCapabilities = async function()
|
||||
|
||||
Grocy.Components.CameraBarcodeScanner.StartScanning = function()
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.DecodedCodesCount = 0;
|
||||
Grocy.Components.CameraBarcodeScanner.DecodedCodesErrorCount = 0;
|
||||
Grocy.Components.CameraBarcodeScanner.Scanner.decodeFromVideoDevice(
|
||||
window.localStorage.getItem('cameraId'),
|
||||
document.querySelector("#camerabarcodescanner-livestream"),
|
||||
(result, error) =>
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Quagga.init({
|
||||
inputStream: {
|
||||
name: "Live",
|
||||
type: "LiveStream",
|
||||
target: document.querySelector("#camerabarcodescanner-livestream"),
|
||||
constraints: {
|
||||
facingMode: "environment",
|
||||
...(window.localStorage.getItem('cameraId') && { deviceId: window.localStorage.getItem('cameraId') }), // If preferred cameraId is set, request to use that specific camera
|
||||
Grocy.Components.CameraBarcodeScanner.StopScanning();
|
||||
|
||||
$(document).trigger("Grocy.BarcodeScanned", [result.getText(), Grocy.Components.CameraBarcodeScanner.CurrentTarget]);
|
||||
$(".modal").last().modal("hide");
|
||||
}
|
||||
)
|
||||
.then(() =>
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.CheckCapabilities();
|
||||
|
||||
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_AUTO_TORCH_ON_WITH_CAMERA)
|
||||
{
|
||||
setTimeout(function()
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.TorchToggle(Grocy.Components.CameraBarcodeScanner.Scanner.stream.getVideoTracks()[0]);
|
||||
}, 250);
|
||||
}
|
||||
},
|
||||
locator: {
|
||||
patchSize: Grocy.UserSettings.quagga2_patchsize,
|
||||
halfSample: Grocy.UserSettings.quagga2_halfsample,
|
||||
debug: {
|
||||
showCanvas: Grocy.UserSettings.quagga2_debug,
|
||||
showPatches: Grocy.UserSettings.quagga2_debug,
|
||||
showFoundPatches: Grocy.UserSettings.quagga2_debug,
|
||||
showSkeleton: Grocy.UserSettings.quagga2_debug,
|
||||
showLabels: Grocy.UserSettings.quagga2_debug,
|
||||
showPatchLabels: Grocy.UserSettings.quagga2_debug,
|
||||
showRemainingPatchLabels: Grocy.UserSettings.quagga2_debug,
|
||||
boxFromPatches: {
|
||||
showTransformed: Grocy.UserSettings.quagga2_debug,
|
||||
showTransformedBox: Grocy.UserSettings.quagga2_debug,
|
||||
showBB: Grocy.UserSettings.quagga2_debug
|
||||
}
|
||||
}
|
||||
},
|
||||
numOfWorkers: Grocy.UserSettings.quagga2_numofworkers,
|
||||
frequency: Grocy.UserSettings.quagga2_frequency,
|
||||
decoder: {
|
||||
readers: [
|
||||
"ean_reader",
|
||||
"ean_8_reader",
|
||||
"code_128_reader",
|
||||
"code_39_reader"
|
||||
],
|
||||
debug: {
|
||||
showCanvas: Grocy.UserSettings.quagga2_debug,
|
||||
showPatches: Grocy.UserSettings.quagga2_debug,
|
||||
showFoundPatches: Grocy.UserSettings.quagga2_debug,
|
||||
showSkeleton: Grocy.UserSettings.quagga2_debug,
|
||||
showLabels: Grocy.UserSettings.quagga2_debug,
|
||||
showPatchLabels: Grocy.UserSettings.quagga2_debug,
|
||||
showRemainingPatchLabels: Grocy.UserSettings.quagga2_debug,
|
||||
boxFromPatches: {
|
||||
showTransformed: Grocy.UserSettings.quagga2_debug,
|
||||
showTransformedBox: Grocy.UserSettings.quagga2_debug,
|
||||
showBB: Grocy.UserSettings.quagga2_debug
|
||||
}
|
||||
}
|
||||
},
|
||||
locate: true
|
||||
}, function(error)
|
||||
{
|
||||
if (error)
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError("Error while initializing the barcode scanning library", error.message);
|
||||
toastr.info(__t("Camera access is only possible when supported and allowed by your browser and when Grocy is served via a secure (https://) connection"));
|
||||
@@ -141,27 +110,13 @@ Grocy.Components.CameraBarcodeScanner.StartScanning = function()
|
||||
$(".modal").last().modal("hide");
|
||||
}, Grocy.FormFocusDelay);
|
||||
return;
|
||||
}
|
||||
|
||||
Grocy.Components.CameraBarcodeScanner.CheckCapabilities();
|
||||
Quagga.start();
|
||||
|
||||
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_AUTO_TORCH_ON_WITH_CAMERA)
|
||||
{
|
||||
setTimeout(function()
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.TorchToggle(Quagga.CameraAccess.getActiveTrack());
|
||||
}, 250);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
Grocy.Components.CameraBarcodeScanner.StopScanning = function()
|
||||
{
|
||||
Quagga.stop();
|
||||
Grocy.Components.CameraBarcodeScanner.Scanner.reset();
|
||||
|
||||
Grocy.Components.CameraBarcodeScanner.DecodedCodesCount = 0;
|
||||
Grocy.Components.CameraBarcodeScanner.DecodedCodesErrorCount = 0;
|
||||
Grocy.Components.CameraBarcodeScanner.LiveVideoSizeAdjusted = false;
|
||||
Grocy.Components.CameraBarcodeScanner.CameraSelectLoaded = false;
|
||||
Grocy.Components.CameraBarcodeScanner.TorchIsOn = false;
|
||||
@@ -182,60 +137,10 @@ Grocy.Components.CameraBarcodeScanner.TorchToggle = function(track)
|
||||
}
|
||||
}
|
||||
|
||||
Quagga.onDetected(function(result)
|
||||
{
|
||||
$.each(result.codeResult.decodedCodes, function(id, error)
|
||||
{
|
||||
if (error.error != undefined)
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.DecodedCodesCount++;
|
||||
Grocy.Components.CameraBarcodeScanner.DecodedCodesErrorCount += Number.parseFloat(error.error);
|
||||
}
|
||||
});
|
||||
|
||||
if ((Grocy.Components.CameraBarcodeScanner.DecodedCodesErrorCount / Grocy.Components.CameraBarcodeScanner.DecodedCodesCount < 0.15) ||
|
||||
(Grocy.Components.CameraBarcodeScanner.DecodedCodesErrorCount == 0 && Grocy.Components.CameraBarcodeScanner.DecodedCodesCount == 0 && result.codeResult.code.length != 0))
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.StopScanning();
|
||||
$(document).trigger("Grocy.BarcodeScanned", [result.codeResult.code, Grocy.Components.CameraBarcodeScanner.CurrentTarget]);
|
||||
$(".modal").last().modal("hide");
|
||||
}
|
||||
});
|
||||
|
||||
Quagga.onProcessed(function(result)
|
||||
{
|
||||
var drawingCtx = Quagga.canvas.ctx.overlay;
|
||||
var drawingCanvas = Quagga.canvas.dom.overlay;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (result.boxes)
|
||||
{
|
||||
drawingCtx.clearRect(0, 0, Number.parseInt(drawingCanvas.getAttribute("width")), Number.parseInt(drawingCanvas.getAttribute("height")));
|
||||
result.boxes.filter(function(box)
|
||||
{
|
||||
return box !== result.box;
|
||||
}).forEach(function(box)
|
||||
{
|
||||
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "yellow", lineWidth: 4 });
|
||||
});
|
||||
}
|
||||
|
||||
if (result.box)
|
||||
{
|
||||
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 4 });
|
||||
}
|
||||
|
||||
if (result.codeResult && result.codeResult.code)
|
||||
{
|
||||
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: "red", lineWidth: 4 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("click", "#camerabarcodescanner-start-button", async function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var inputElement = $(e.currentTarget).prev();
|
||||
if (inputElement.hasAttr("disabled"))
|
||||
{
|
||||
@@ -247,7 +152,7 @@ $(document).on("click", "#camerabarcodescanner-start-button", async function(e)
|
||||
Grocy.Components.CameraBarcodeScanner.CurrentTarget = inputElement.attr("data-target");
|
||||
|
||||
var dialog = bootbox.dialog({
|
||||
message: '<div id="camerabarcodescanner-container" class="col"><div id="camerabarcodescanner-livestream"></div></div>',
|
||||
message: '<div id="camerabarcodescanner-container" class="col"><video id="camerabarcodescanner-livestream"></div></div>',
|
||||
title: __t('Scan a barcode'),
|
||||
size: 'large',
|
||||
backdrop: true,
|
||||
@@ -259,7 +164,10 @@ $(document).on("click", "#camerabarcodescanner-start-button", async function(e)
|
||||
className: 'btn-warning responsive-button torch',
|
||||
callback: function()
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.TorchToggle(Quagga.CameraAccess.getActiveTrack());
|
||||
if (Grocy.Components.CameraBarcodeScanner.Scanner.stream)
|
||||
{
|
||||
Grocy.Components.CameraBarcodeScanner.TorchToggle(Grocy.Components.CameraBarcodeScanner.Scanner.stream.getVideoTracks()[0]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -271,12 +179,12 @@ $(document).on("click", "#camerabarcodescanner-start-button", async function(e)
|
||||
});
|
||||
|
||||
// Add camera select to existing dialog
|
||||
dialog.find('.bootbox-body').append('<div class="form-group py-0 my-1 d-block cameraSelect-wrapper"><select class="custom-control custom-select cameraSelect"></select></div>');
|
||||
dialog.find('.bootbox-body').append('<div class="form-group pb-0 pt-2 my-1 d-block cameraSelect-wrapper"><select class="custom-control custom-select cameraSelect"></select></div>');
|
||||
var cameraSelect = document.querySelector('.cameraSelect');
|
||||
cameraSelect.onchange = function()
|
||||
{
|
||||
window.localStorage.setItem('cameraId', cameraSelect.value);
|
||||
Quagga.stop();
|
||||
Grocy.Components.CameraBarcodeScanner.Scanner.reset();
|
||||
Grocy.Components.CameraBarcodeScanner.StartScanning();
|
||||
};
|
||||
|
||||
@@ -291,6 +199,15 @@ Grocy.Components.CameraBarcodeScanner.Init = function()
|
||||
return;
|
||||
}
|
||||
|
||||
Grocy.Components.CameraBarcodeScanner.Scanner = new ZXing.BrowserMultiFormatReader(new Map().set(ZXing.DecodeHintType.POSSIBLE_FORMATS, [
|
||||
ZXing.BarcodeFormat.EAN_8,
|
||||
ZXing.BarcodeFormat.EAN_13,
|
||||
ZXing.BarcodeFormat.CODE_39,
|
||||
ZXing.BarcodeFormat.CODE_128,
|
||||
ZXing.BarcodeFormat.DATA_MATRIX,
|
||||
ZXing.BarcodeFormat.QR_CODE,
|
||||
]));
|
||||
|
||||
$(".barcodescanner-input:visible").each(function()
|
||||
{
|
||||
if ($(this).hasAttr("disabled"))
|
||||
|
Reference in New Issue
Block a user