Bugzilla – Attachment 99757 Details for
Bug 6815
Capture member photo via webcam
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Move webcam interface into modal
Move-webcam-interface-into-modal.patch (text/plain), 16.11 KB, created by
Owen Leonard
on 2020-02-28 14:05:51 UTC
(
hide
)
Description:
Move webcam interface into modal
Filename:
MIME Type:
Creator:
Owen Leonard
Created:
2020-02-28 14:05:51 UTC
Size:
16.11 KB
patch
obsolete
>From e3a2873821c9b9d081f3fd3e6c4c03a3a2b0a655 Mon Sep 17 00:00:00 2001 >From: Owen Leonard <oleonard@myacpl.org> >Date: Tue, 9 Jul 2019 13:00:13 +0000 >Subject: [PATCH] Move webcam interface into modal > >https://bugs.koha-community.org/show_bug.cgi?id=6815 >--- > .../intranet-tmpl/prog/en/includes/circ-menu.inc | 7 ++ > .../prog/en/includes/intranet-bottom.inc | 18 --- > .../prog/en/modules/members/member-webcam.tt | 140 +++++---------------- > .../prog/en/modules/members/moremember.tt | 11 +- > .../intranet-tmpl/prog/js/pages/patron-webcam.js | 113 +++++++++++++++++ > 5 files changed, 161 insertions(+), 128 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/pages/patron-webcam.js > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >index 95ace5e2485..a3f36e3e567 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/circ-menu.inc >@@ -149,6 +149,13 @@ > <div class="modal-body"> > <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> > </div> >+ <form method="post" action="/cgi-bin/koha/tools/picture-upload.pl" enctype="multipart/form-data"> >+ <input type="hidden" id="webcam_csrf_token" name="csrf_token" value="[% csrf_token | html %]" /> >+ <input type="hidden" id="webcam_image" name="filetype" value="image" /> >+ <input type="hidden" id="webcam_cardnumber" name="cardnumber" value="[% patron.cardnumber | html %]" /> >+ <input type="hidden" id="webcam_borrowernumber" name="borrowernumber" value="[% patron.borrowernumber | html %]" /> >+ <input id="webcam_op" name="op" type="hidden" value="Upload" /> >+ </form> > <div class="modal-footer"> > <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> > </div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc >index b3638001348..e0bce02522d 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc >@@ -68,24 +68,6 @@ > [% END %] > [% END %] > <span id="audio-alert"></span> >- >- <script> >- function detectWebcam(callback) { >- let md = navigator.mediaDevices; >- if (!md || !md.enumerateDevices) return callback(false); >- md.enumerateDevices().then(devices => { >- callback(devices.some(device => 'videoinput' === device.kind)); >- }) >- } >- >- detectWebcam(function(hasWebcam) { >- let div_take_image = document.getElementById('take_patron_image'); >- if (div_take_image) { >- div_take_image.style.display = hasWebcam ? "block" : "none"; >- } >- }); >- </script> >- > [% IF ( footerjs ) %] > [% INCLUDE js_includes.inc %] > [% jsinclude | $raw # Parse the page template's JavaScript block if necessary %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-webcam.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-webcam.tt >index 7c254e26543..3189ee2d1ea 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-webcam.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/member-webcam.tt >@@ -1,107 +1,33 @@ >-<!DOCTYPE html> >-<html lang="en" dir="ltr"> >- >- <head> >- <meta charset="utf-8" /> >- <title>Koha Patron Image Via Webcam</title> >- <meta name="description" >- content="Attempt to take a patron picture using the webcam" /> >- </head> >- >- <body> >- <h1>Koha Patron Image Taker</h1> >- <p>Ask the patron to face the webcam to take their picture.</p> >- <p>WARNING: If your machine does not have a webcam, >- your browser is not allowed camera access, your operating >- system blocks the browser app from accessing the camera, >- or your browser does not support the javascript used >- in this page, this may not work and likely looks like >- a empty page. If this is working you will see a video >- playing of what the webcam sees.</p> >- >- <!-- display what will be captured --> >- <video id="video" width="640" height="480" autoplay></video><br> >- <!-- button to trigger cascading clicks resulting in a saved file --> >- <!-- first stick the image into a hidden canvas below --> >- <button id="snap">Take the Patron's Picture</button> >- <canvas id="canvas" width="640" height="480" style="display:none"></canvas> >- <!-- then change the href in a hidden link to the picture data --> >- <button id="save" style="display:none">Save the Patron's Picture</button> >- <!-- which will get programmatically clicked forcing the download --> >- <a href="#" id="download" style="display:none">Download the Patron's Picture</a> >- >- <!-- the javascript magic that makes it happen --> >- <script> >- // Put event listeners into place >- window.addEventListener("DOMContentLoaded", >- function() { >- // Grab elements, create settings, etc. >- var canvas = document.getElementById('canvas'); >- var context = canvas.getContext('2d'); >- var video = document.getElementById('video'); >- var mediaConfig = { video: true }; >- var errBack = function(e) { >- alert('An error has occurred!'); >- }; >- >- // Put video listeners into place >- if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { >- navigator.mediaDevices.getUserMedia(mediaConfig).then( >- function(stream) { >- video.srcObject = stream; >- video.play(); >- } >- ); >- } >- /* Legacy code below! */ >- else if (navigator.getUserMedia) { // Standard >- navigator.getUserMedia(mediaConfig, >- function(stream) { >- video.src = stream; >- video.play(); >- }, >- errBack >- ); >- } else if (navigator.webkitGetUserMedia) { // WebKit-prefixed >- navigator.webkitGetUserMedia(mediaConfig, >- function(stream) { >- video.src = window.webkitURL.createObjectURL(stream); >- video.play(); >- }, >- errBack >- ); >- } else if (navigator.mozGetUserMedia) { // Mozilla-prefixed >- navigator.mozGetUserMedia(mediaConfig, >- function(stream) { >- video.src = window.URL.createObjectURL(stream); >- video.play(); >- }, >- errBack >- ); >- } >- >- // Trigger photo take >- document.getElementById('snap').addEventListener('click', >- function() { >- context.drawImage(video, 0, 0, 640, 480); >- var save_button = document.getElementById('save'); >- save_button.click(); >- } >- ); >- >- // Save photo taken >- document.getElementById('save').addEventListener('click', >- function() { >- var download_anchor = document.getElementById('download'); >- download_anchor.href = canvas.toDataURL('image/jpeg'); >- download_anchor.download = "SamplePhoto.jpg"; >- download_anchor.click(); >- } >- ); >- }, >- false >- ); >- >- </script> >- </body> >-</html> >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Patrons › Capture patron image</title> >+[% INCLUDE 'doc-head-close.inc' %] >+<style>#snap{width:100%;background-color:#336699;color:white;}</style> >+</head> >+ >+<body id="pat_take_photo" class="pat"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'patron-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> › Capture patron image</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ <div class="col-md-8 col-md-offset-2"> >+ <h1>Capture patron image</h1> >+ <div id="webcam"> >+ <p>Ask the patron to face the webcam to take their picture.</p> >+ >+ <!-- display what will be captured --> >+ <video id="video" width="100%" autoplay></video><br> >+ <!-- button to trigger cascading clicks resulting in a saved file --> >+ <!-- first stick the image into a hidden canvas below --> >+ <button id="snap"><i class="fa fa-camera"></i> Take the patron's picture</button> >+ <canvas id="canvas" width="640" height="480" style="display:none"></canvas> >+ <!-- which will get programmatically clicked forcing the download --> >+ <a href="#" id="download" style="display:none">Download the patron's picture</a> >+ </div> >+ </div> <!-- /.col-md-8.col-md-offset-2 --> >+ </div> <!-- /.row --> >+</div> <!-- /.main.container-fluid --> >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >index 16f409c72b3..21d0ad89e1c 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -15,6 +15,7 @@ > [% END %] > </title> > [% INCLUDE 'doc-head-close.inc' %] >+<style>video{width:100%;}</style> > </head> > > <body id="pat_moremember" class="pat"> >@@ -297,7 +298,7 @@ > </div> > [% ELSE %] > <div class="patroninfo-heading"> >- <h3>Upload patron image</h3> >+ <h3>Add patron image</h3> > <a class="btn btn-default btn-xs" id="show-picture-upload" href="#"><i class="fa fa-plus"></i> Add</a> > </div> > [% END %] >@@ -323,9 +324,9 @@ > <a href="#" id="cancel-picture-upload" class="cancel">Cancel</a> > </div> > </form> >- <div class="patroninfo-heading" id="take_patron_image"> >+ <div class="patroninfo-heading" id="take_patron_image" style="display:block"> > <h3>Take patron image</h3> >- <a class="btn btn-default btn-xs" id="trigger-webcam" href="/cgi-bin/koha/members/webcam.pl" target="_blank"><i class="fa fa-camera"></i> Take</a> >+ <a class="btn btn-default btn-xs" id="trigger-webcam" href="/cgi-bin/koha/members/webcam.pl" title="Capture patron image"> <i class="fa fa-camera"></i> Take</a> > </div> > </div> [% # /div#manage-patron-image %] > [% END %] >@@ -864,6 +865,9 @@ > [% Asset.js("lib/jquery/plugins/jquery.checkboxes.min.js") | $raw %] > [% Asset.js("lib/jquery/plugins/jquery-ui-timepicker-addon.min.js") | $raw %] > [% INCLUDE 'timepicker.inc' %] >+ [% IF ( Koha.Preference('patronimages') ) %] >+ [% Asset.js("js/pages/patron-webcam.js") %] >+ [% END %] > <script> > /* Set some variable needed in circulation.js */ > var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]"; >@@ -956,6 +960,7 @@ > }); > > }); >+ > function uncheck_sibling(me){ > nodename=me.getAttribute("name"); > if (nodename =="barcodes[]"){ >diff --git a/koha-tmpl/intranet-tmpl/prog/js/pages/patron-webcam.js b/koha-tmpl/intranet-tmpl/prog/js/pages/patron-webcam.js >new file mode 100644 >index 00000000000..3677b84abe7 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/pages/patron-webcam.js >@@ -0,0 +1,113 @@ >+function initializeCamera( camera_form ){ >+ // Grab elements, create settings, etc. >+ console.log(camera_form); >+ var context = camera_form.find("#canvas")[0].getContext('2d'); >+ var video = camera_form.find("#video")[0]; >+ var mediaConfig = { video: true }; >+ var errBack = function( error ) { >+ if( error.name = "NotAllowedError" ){ >+ alert("No permission to use camera"); >+ } else { >+ alert("Cannot load camera interface"); >+ } >+ }; >+ >+ // Put video listeners into place >+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { >+ navigator.mediaDevices.getUserMedia(mediaConfig).then( >+ function(stream) { >+ video.srcObject = stream; >+ video.play(); >+ }, >+ errBack >+ ); >+ } >+ /* Legacy code below! */ >+ else if (navigator.getUserMedia) { // Standard >+ navigator.getUserMedia(mediaConfig, >+ function(stream) { >+ video.src = stream; >+ video.play(); >+ }, >+ errBack >+ ); >+ } else if (navigator.webkitGetUserMedia) { // WebKit-prefixed >+ navigator.webkitGetUserMedia(mediaConfig, >+ function(stream) { >+ video.src = window.webkitURL.createObjectURL(stream); >+ video.play(); >+ }, >+ errBack >+ ); >+ } else if (navigator.mozGetUserMedia) { // Mozilla-prefixed >+ navigator.mozGetUserMedia(mediaConfig, >+ function(stream) { >+ video.src = window.URL.createObjectURL(stream); >+ video.play(); >+ }, >+ errBack >+ ); >+ } >+ >+ camera_form.find("#snap").on("click", function(){ >+ context.drawImage(video, 0, 0, 640, 480); >+ var download_anchor = document.getElementById('download'); >+ download_anchor.href = canvas.toDataURL('image/jpeg'); >+ download_anchor.download = "patron-photo.jpg"; >+ download_anchor.click(); >+ // gather form data for AJAX POST >+ var data = new FormData(); >+ data.append("uploadfiletext", download_anchor.href ); >+ data.append("csrf_token", $("#webcam_csrf_token").val() ); >+ data.append("filetype", "image" ); >+ data.append("uploadfilename", "patron-photo.jpg" ); >+ data.append("cardnumber", $("#webcam_cardnumber").val() ); >+ data.append("borrowernumber", $("#webcam_borrowernumber").val() ); >+ data.append("op", $("#webcam_op").val() ); >+ $.ajax({ >+ type: "POST", >+ url: "/cgi-bin/koha/tools/picture-upload.pl", >+ data: data, >+ cache: false, >+ contentType: false, >+ processData: false >+ }).done(function() { >+ >+ }); >+ }); >+} >+ >+function detectWebcam(callback) { >+ let md = navigator.mediaDevices; >+ if (!md || !md.enumerateDevices) return callback(false); >+ md.enumerateDevices().then(devices => { >+ callback(devices.some(device => 'videoinput' === device.kind)); >+ }) >+} >+ >+detectWebcam(function(hasWebcam) { >+ let div_take_image = document.getElementById('take_patron_image'); >+ if (div_take_image) { >+ div_take_image.style.display = hasWebcam ? "block" : "none"; >+ } >+}); >+ >+$(document).ready(function(){ >+ $("#trigger-webcam").on("click", function(e){ >+ e.preventDefault(); >+ var borrowernumber = $(this).data("borrowernumber"); >+ $.get("/cgi-bin/koha/members/webcam.pl", { borrowernumber : borrowernumber }, function( data ){ >+ var image_form = $(data).find("#webcam"); >+ initializeCamera( image_form ); >+ $("#patronImageEdit .modal-body").html( image_form ); >+ }); >+ var modalTitle = $(this).attr("title"); >+ $("#patronImageEdit .modal-title").text(modalTitle); >+ $("#patronImageEdit") >+ .modal("show") >+ .on("hidden.bs.modal", function(){ >+ video.pause(); >+ }); >+ }); >+ >+}) >\ No newline at end of file >-- >2.11.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 6815
:
22623
|
29613
|
38518
|
91302
|
91303
|
91335
|
99015
|
99016
|
99757
|
106774
|
106775
|
106776
|
106777
|
106782
|
106783
|
106787
|
106788
|
106789
|
106790
|
106791
|
106792
|
106793
|
106794
|
106795
|
106796
|
106797
|
106798
|
106799
|
106800
|
106801
|
106802
|
106803
|
106804
|
106938
|
106939
|
106940
|
131174
|
131554
|
131985
|
131987
|
131988
|
131999
|
132000
|
132001