2019-09-19 12:48:02 +02:00
Grocy . Components . BarcodeScanner = { } ;
2020-03-29 14:25:04 +02:00
Grocy . Components . BarcodeScanner . CheckCapabilities = function ( )
{
var track = Quagga . CameraAccess . getActiveTrack ( ) ;
var capabilities = { } ;
if ( typeof track . getCapabilities === 'function' ) {
capabilities = track . getCapabilities ( ) ;
}
// 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.
var node = document . querySelector ( '.torch' ) ;
if ( node ) {
node . style . display = canTorch && ! Grocy . FeatureFlags . GROCY _FEATURE _FLAG _AUTO _TORCH _ON _WITH _CAMERA ? 'inline-block' : 'none' ;
}
// If AutoTorchOn is set, turn on the torch.
if ( canTorch && Grocy . FeatureFlags . GROCY _FEATURE _FLAG _AUTO _TORCH _ON _WITH _CAMERA ) {
Grocy . Components . BarcodeScanner . TorchOn ( track ) ;
}
// Reduce the height of the video, if it's heigher than then the viewport
var bc = document . getElementById ( 'barcodescanner-container' ) ;
if ( bc ) {
var bcAspectRatio = bc . offsetWidth / bc . offsetHeight ;
var settings = track . getSettings ( ) ;
if ( bcAspectRatio > settings . aspectRatio ) {
var v = document . querySelector ( '#barcodescanner-livestream video' )
if ( v ) {
var c = document . querySelector ( '#barcodescanner-livestream canvas' )
var newWidth = v . clientWidth / bcAspectRatio * settings . aspectRatio + 'px' ;
v . style . width = newWidth ;
c . style . width = newWidth ;
}
}
}
}
2019-09-19 12:48:02 +02:00
Grocy . Components . BarcodeScanner . StartScanning = function ( )
{
2019-09-21 20:46:23 +02:00
Grocy . Components . BarcodeScanner . DecodedCodesCount = 0 ;
Grocy . Components . BarcodeScanner . DecodedCodesErrorCount = 0 ;
2019-09-19 12:48:02 +02:00
Quagga . init ( {
inputStream : {
name : "Live" ,
type : "LiveStream" ,
target : document . querySelector ( "#barcodescanner-livestream" ) ,
constraints : {
facingMode : "environment"
}
} ,
locator : {
patchSize : "medium" ,
halfSample : false ,
debug : {
showCanvas : true ,
showPatches : true ,
showFoundPatches : true ,
showSkeleton : true ,
showLabels : true ,
showPatchLabels : true ,
showRemainingPatchLabels : true ,
boxFromPatches : {
showTransformed : true ,
showTransformedBox : true ,
showBB : true
}
}
} ,
numOfWorkers : 2 ,
frequency : 10 ,
decoder : {
readers : [
"ean_reader" ,
"ean_8_reader" ,
2019-09-21 20:46:23 +02:00
"code_128_reader"
2019-09-19 12:48:02 +02:00
] ,
debug : {
showCanvas : true ,
showPatches : true ,
showFoundPatches : true ,
showSkeleton : true ,
showLabels : true ,
showPatchLabels : true ,
showRemainingPatchLabels : true ,
boxFromPatches : {
showTransformed : true ,
showTransformedBox : true ,
showBB : true
}
}
} ,
locate : true
} , function ( error )
{
if ( error )
{
Grocy . FrontendHelpers . ShowGenericError ( "Error while initializing the barcode scanning library" , error . message ) ;
2020-03-06 20:58:01 +01:00
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" ) ) ;
2019-09-20 13:37:53 +02:00
setTimeout ( function ( )
{
bootbox . hideAll ( ) ;
} , 500 ) ;
2019-09-19 12:48:02 +02:00
return ;
}
2020-03-29 14:25:04 +02:00
Grocy . Components . BarcodeScanner . CheckCapabilities ( ) ;
2019-09-19 12:48:02 +02:00
Quagga . start ( ) ;
} ) ;
}
Grocy . Components . BarcodeScanner . StopScanning = function ( )
{
Quagga . stop ( ) ;
2019-09-21 20:46:23 +02:00
Grocy . Components . BarcodeScanner . DecodedCodesCount = 0 ;
Grocy . Components . BarcodeScanner . DecodedCodesErrorCount = 0 ;
2019-09-19 12:48:02 +02:00
bootbox . hideAll ( ) ;
}
2020-03-29 14:25:04 +02:00
Grocy . Components . BarcodeScanner . TorchOn = function ( track )
{
if ( track ) {
track . applyConstraints ( {
advanced : [
{
torch : true
}
]
} ) ;
}
}
2019-09-19 12:48:02 +02:00
Quagga . onDetected ( function ( result )
{
2019-09-21 20:46:23 +02:00
$ . each ( result . codeResult . decodedCodes , function ( id , error )
{
if ( error . error != undefined )
{
Grocy . Components . BarcodeScanner . DecodedCodesCount ++ ;
Grocy . Components . BarcodeScanner . DecodedCodesErrorCount += parseFloat ( error . error ) ;
}
} ) ;
if ( Grocy . Components . BarcodeScanner . DecodedCodesErrorCount / Grocy . Components . BarcodeScanner . DecodedCodesCount < 0.15 )
{
Grocy . Components . BarcodeScanner . StopScanning ( ) ;
$ ( document ) . trigger ( "Grocy.BarcodeScanned" , [ result . codeResult . code ] ) ;
}
2019-09-19 12:48:02 +02:00
} ) ;
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 , parseInt ( drawingCanvas . getAttribute ( "width" ) ) , parseInt ( drawingCanvas . getAttribute ( "height" ) ) ) ;
result . boxes . filter ( function ( box )
{
return box !== result . box ;
} ) . forEach ( function ( box )
{
2019-09-21 20:46:23 +02:00
Quagga . ImageDebug . drawPath ( box , { x : 0 , y : 1 } , drawingCtx , { color : "yellow" , lineWidth : 4 } ) ;
2019-09-19 12:48:02 +02:00
} ) ;
}
if ( result . box )
{
2019-09-21 20:46:23 +02:00
Quagga . ImageDebug . drawPath ( result . box , { x : 0 , y : 1 } , drawingCtx , { color : "green" , lineWidth : 4 } ) ;
2019-09-19 12:48:02 +02:00
}
if ( result . codeResult && result . codeResult . code )
{
Quagga . ImageDebug . drawPath ( result . line , { x : 'x' , y : 'y' } , drawingCtx , { color : "red" , lineWidth : 4 } ) ;
}
}
} ) ;
$ ( document ) . on ( "click" , "#barcodescanner-start-button" , function ( e )
{
e . preventDefault ( ) ;
2019-09-27 17:24:44 +02:00
var inputElement = $ ( e . currentTarget ) . prev ( ) ;
if ( inputElement . hasAttr ( "disabled" ) )
{
// Do nothing and disable the barcode scanner start button
$ ( e . currentTarget ) . addClass ( "disabled" ) ;
return ;
}
2019-09-19 12:48:02 +02:00
bootbox . dialog ( {
message : '<div id="barcodescanner-container" class="col"><div id="barcodescanner-livestream"></div></div>' ,
title : _ _t ( 'Scan a barcode' ) ,
onEscape : function ( )
{
Grocy . Components . BarcodeScanner . StopScanning ( ) ;
} ,
size : 'big' ,
backdrop : true ,
2020-03-01 17:53:28 +01:00
closeButton : true ,
2019-09-19 12:48:02 +02:00
buttons : {
2020-03-01 17:53:28 +01:00
torch : {
2020-03-01 17:58:10 +01:00
label : '<i class="far fa-lightbulb"></i>' ,
2020-03-29 14:25:04 +02:00
className : 'btn-warning responsive-button torch' ,
2020-03-01 17:58:10 +01:00
callback : function ( )
{
2020-03-29 14:25:04 +02:00
Grocy . Components . BarcodeScanner . TorchOn ( Quagga . CameraAccess . getActiveTrack ( ) ) ;
2020-03-01 17:58:10 +01:00
return false ;
2020-03-01 17:53:28 +01:00
}
} ,
2019-09-19 12:48:02 +02:00
cancel : {
label : _ _t ( 'Cancel' ) ,
className : 'btn-secondary responsive-button' ,
callback : function ( )
{
Grocy . Components . BarcodeScanner . StopScanning ( ) ;
}
2019-09-20 13:37:53 +02:00
}
2019-09-19 12:48:02 +02:00
}
} ) ;
Grocy . Components . BarcodeScanner . StartScanning ( ) ;
} ) ;
setTimeout ( function ( )
{
2019-09-27 17:24:44 +02:00
$ ( ".barcodescanner-input:visible" ) . each ( function ( )
{
if ( $ ( this ) . hasAttr ( "disabled" ) )
{
$ ( this ) . after ( '<a id="barcodescanner-start-button" class="btn btn-sm btn-primary text-white disabled"><i class="fas fa-camera"></i></a>' ) ;
}
else
{
$ ( this ) . after ( '<a id="barcodescanner-start-button" class="btn btn-sm btn-primary text-white"><i class="fas fa-camera"></i></a>' ) ;
}
} ) ;
2019-09-19 12:48:02 +02:00
} , 50 ) ;