From a6030798c76a9cd1d39b87b2642dcb4fbdbe174c Mon Sep 17 00:00:00 2001 From: Michael Frikke Madsen Date: Mon, 13 Apr 2020 22:07:38 +0200 Subject: [PATCH] Add camera picker button (#733) * Add camera picker button * Remove button and nested dialog - make it a select - Also make Cancel button gray again --- public/viewjs/components/barcodescanner.js | 39 +++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/public/viewjs/components/barcodescanner.js b/public/viewjs/components/barcodescanner.js index 369cba5a..b8bbb618 100644 --- a/public/viewjs/components/barcodescanner.js +++ b/public/viewjs/components/barcodescanner.js @@ -1,6 +1,6 @@ Grocy.Components.BarcodeScanner = { }; -Grocy.Components.BarcodeScanner.CheckCapabilities = function() +Grocy.Components.BarcodeScanner.CheckCapabilities = async function() { var track = Quagga.CameraAccess.getActiveTrack(); var capabilities = {}; @@ -8,6 +8,13 @@ Grocy.Components.BarcodeScanner.CheckCapabilities = function() capabilities = track.getCapabilities(); } + // If there is more than 1 camera, show the camera selection + var cameras = await Quagga.CameraAccess.enumerateVideoDevices(); + var cameraSelect = document.querySelector('.cameraSelect'); + if (cameraSelect) { + cameraSelect.style.display = cameras.length > 1 ? 'inline-block' : 'none'; + } + // Check if the camera is capable to turn on a torch. var canTorch = typeof capabilities.torch === 'boolean' && capabilities.torch // Remove the torch button, if either the device can not torch or AutoTorchOn is set. @@ -48,7 +55,8 @@ Grocy.Components.BarcodeScanner.StartScanning = function() type: "LiveStream", target: document.querySelector("#barcodescanner-livestream"), constraints: { - facingMode: "environment" + facingMode: "environment", + ...(window.localStorage.getItem('cameraId') && {deviceId : window.localStorage.getItem('cameraId')}) // If preferred cameraId is set, request to use that specific camera } }, locator: { @@ -99,6 +107,7 @@ Grocy.Components.BarcodeScanner.StartScanning = function() { 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")); + window.localStorage.removeItem("cameraId"); setTimeout(function() { bootbox.hideAll(); @@ -184,7 +193,7 @@ Quagga.onProcessed(function(result) } }); -$(document).on("click", "#barcodescanner-start-button", function(e) +$(document).on("click", "#barcodescanner-start-button", async function(e) { e.preventDefault(); var inputElement = $(e.currentTarget).prev(); @@ -197,7 +206,7 @@ $(document).on("click", "#barcodescanner-start-button", function(e) Grocy.Components.BarcodeScanner.CurrentTarget = inputElement.attr("data-target"); - bootbox.dialog({ + var dialog = bootbox.dialog({ message: '
', title: __t('Scan a barcode'), onEscape: function() @@ -227,6 +236,28 @@ $(document).on("click", "#barcodescanner-start-button", function(e) } } }); + + // Add camera select to existing dialog + dialog.find('.bootbox-body').append(''); + var cameraSelect = document.querySelector('.cameraSelect'); + + var cameras = await Quagga.CameraAccess.enumerateVideoDevices(); + cameras.forEach(camera => { + var option = document.createElement("option"); + option.text = camera.label ? camera.label : camera.deviceId; // Use camera label if it exists, else show device id + option.value = camera.deviceId; + cameraSelect.appendChild(option); + }); + + // Set initial value to preferred camera if one exists - and if not, start out empty + cameraSelect.value = window.localStorage.getItem('cameraId'); + + cameraSelect.onchange = function(){ + window.localStorage.setItem('cameraId', cameraSelect.value); + Quagga.stop(); + Grocy.Components.BarcodeScanner.StartScanning(); + }; + Grocy.Components.BarcodeScanner.StartScanning(); });