Commit 6cee3d08 authored by Gabriel Monnerat's avatar Gabriel Monnerat

erp5_document_scanner: Improve gadget following the design defined by Thierry

parent 9e5652f2
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>action_type/object_jio_button</string> <string>action_type/object_onlyjio_action</string>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>category</string> </key> <key> <string>category</string> </key>
<value> <string>object_jio_button</string> </value> <value> <string>object_onlyjio_action</string> </value>
</item> </item>
<item> <item>
<key> <string>condition</string> </key> <key> <string>condition</string> </key>
......
...@@ -7,6 +7,8 @@ if not active_preference: ...@@ -7,6 +7,8 @@ if not active_preference:
active_preference = portal.portal_preferences.getActivePreference() active_preference = portal.portal_preferences.getActivePreference()
canvas_data = active_preference and \ canvas_data = active_preference and \
active_preference.getPreferredCroppedCanvasData() or \ json.loads(active_preference.getPreferredCroppedCanvasData()) or {}
json.dumps({})
return canvas_data canvas_data["dialog_method"] = context.Base_storeDocumentFromCameraInActiveProcess.getId()
return json.dumps(canvas_data)
import json import json
from base64 import decodestring from base64 import decodestring
portal = context.getPortalObject() portal = context.getPortalObject()
gadget_data = json.loads(document_scanner_gadget) gadget_data = json.loads(document_scanner_gadget)
image_str = decodestring(gadget_data["input_value"]) image_str = decodestring(gadget_data.pop("input_value"))
preferred_cropped_canvas_data = json.dumps(gadget_data["preferred_cropped_canvas_data"]) preferred_cropped_canvas_data = json.dumps(gadget_data["preferred_cropped_canvas_data"])
active_preference = portal.portal_preferences.getActiveUserPreference() active_preference = portal.portal_preferences.getActiveUserPreference()
...@@ -15,7 +14,7 @@ if active_preference and preferred_cropped_canvas_data: ...@@ -15,7 +14,7 @@ if active_preference and preferred_cropped_canvas_data:
active_preference.setPreferredCroppedCanvasData(preferred_cropped_canvas_data) active_preference.setPreferredCroppedCanvasData(preferred_cropped_canvas_data)
if not image_str: if not image_str:
return context.Base_renderForm('Base_viewUploadDocumentFromCameraStep1Dialog', return context.Base_renderForm('Base_viewUploadDocumentFromCameraDialog',
message='Nothing to capture') message='Nothing to capture')
if not active_process_url: if not active_process_url:
...@@ -25,5 +24,7 @@ else: ...@@ -25,5 +24,7 @@ else:
active_process = portal.restrictedTraverse(active_process_url) active_process = portal.restrictedTraverse(active_process_url)
active_process.postActiveResult(detail=image_str) active_process.postActiveResult(detail=image_str)
return context.Base_renderForm('Base_viewUploadDocumentFromCameraStep1Dialog', context.REQUEST.form.pop("field_your_document_scanner_gadget")
context.REQUEST.form.pop('document_scanner_gadget')
return context.Base_renderForm('Base_viewUploadDocumentFromCameraDialog',
message='Captured') message='Captured')
...@@ -9,6 +9,7 @@ active_process = portal.restrictedTraverse(active_process_url) ...@@ -9,6 +9,7 @@ active_process = portal.restrictedTraverse(active_process_url)
for result in active_process.getResultList(): for result in active_process.getResultList():
pdf_data_list.append( pdf_data_list.append(
image_module.newContent(data=result.detail, image_module.newContent(data=result.detail,
portal_type="Image",
temp_object=True).convert(format="pdf")[1]) temp_object=True).convert(format="pdf")[1])
pdf_data = context.ERP5Site_mergePDFList(pdf_data_list=pdf_data_list) pdf_data = context.ERP5Site_mergePDFList(pdf_data_list=pdf_data_list)
...@@ -19,10 +20,26 @@ extra_document_kw = { ...@@ -19,10 +20,26 @@ extra_document_kw = {
kw.get("title") or DateTime().strftime('%d-%m-%Y_%Hh%M')) kw.get("title") or DateTime().strftime('%d-%m-%Y_%Hh%M'))
} }
context.Base_contribute(file=file_object, doc = context.Base_contribute(file=file_object,
batch_mode=True, batch_mode=True,
follow_up_list=[context.getRelativeUrl(),], follow_up_list=[context.getRelativeUrl(),],
extra_document_kw=extra_document_kw, extra_document_kw=extra_document_kw,
**kw) **kw)
publication_section = kw.get("field_your_publication_state")
if publication_section == "shared":
action_list = ["share",]
elif publication_section == "relased":
action_list = ["share", "release"]
elif publication_section == "released":
action_list = ["share", "release"]
elif publication_section == "published":
action_list = ["share", "release", "publish"]
else:
action_list = []
for action in action_list:
getattr(doc, action)()
portal.portal_activities.manage_delObjects(ids=[active_process.getId(),]) portal.portal_activities.manage_delObjects(ids=[active_process.getId(),])
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <key> <string>_text</string> </key>
<value> <string>python: [("", ""), ("Draft", "draft"), ("Shared", "shared"), ("Released", "relase"), ("Published", "publish")]</string> </value> <value> <string>python: [("", ""), ("Draft", "draft"), ("Shared", "shared"), ("Released", "released"), ("Published", "published")]</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
font-weight: 400; font-weight: 400;
} }
.camera-input, .camera-output, .camera-header { .camera-input, .camera-output, .camera-header, .edit-picture {
text-align: center; text-align: center;
} }
...@@ -47,15 +47,16 @@ ...@@ -47,15 +47,16 @@
margin: 0 auto; margin: 0 auto;
} }
.startbutton, .capture-button, .reset-button { .reset-btn, .confirm-btn, .edit-btn, .take-picture-btn,
position: relative; .capture-btn, .change-camera-btn, .confirm-btn {
bottom: 3em; font-size: 44px;
background-color: rgba(0, 150, 0, 0.5); color: #212529;
border: 1px solid rgba(255, 255, 255, 0.7); padding: 0 16px 0 16px;
box-shadow: 0px 0px 1px 2px rgba(0, 0, 0, 0.2); }
font-size: 14px;
font-family: "Lucida Grande", "Arial", sans-serif; .take-picture-btn, .capture-btn, .confirm-btn,
color: rgba(255, 255, 255, 1.0); .reset-btn, .confirm-btn, .change-camera-btn, .edit-btn {
display: none;
} }
.contentarea { .contentarea {
......
...@@ -16,16 +16,18 @@ ...@@ -16,16 +16,18 @@
</div> </div>
<div class="camera-input" style="display: none"> <div class="camera-input" style="display: none">
<video class="video">Webcam is not available</video> <video class="video">Webcam is not available</video>
<button type="button" class="startbutton">Take a picture!</button>
</div> </div>
<canvas class="canvas"></canvas> <canvas class="canvas"></canvas>
<div class="camera-output" style="display: none"> <div class="camera-output" style="display: none">
<img class="photo" alt="Photo"> <img class="photo" alt="Photo">
<input class="photoInput" type="hidden"> <input class="photoInput" type="hidden">
<div class="edit-picture"> </div>
<button class="capture-button">Crop</button> <div class="edit-picture">
<button class="reset-button">Reset</button> <button type="button" class="reset-btn ui-btn-icon-left ui-icon-times"></button>
</div> <button type="button" class="take-picture-btn ui-btn-icon-left ui-icon-circle"></button>
<button type="button" class="confirm-btn ui-btn-icon-left ui-icon-check"></button>
<button type="button" class="edit-btn ui-btn-icon-left ui-icon-pencil"></button>
<button type="button" class="change-camera-btn ui-btn-icon-left ui-icon-refresh"></button>
</div> </div>
</div> </div>
</body> </body>
......
...@@ -10,10 +10,12 @@ ...@@ -10,10 +10,12 @@
video, video,
stream, stream,
canvas, canvas,
dialogMethod,
photo, photo,
photoInput, photoInput,
deviceId, deviceId,
imageCapture, imageCapture,
pageNumber = 1,
cameraList = []; cameraList = [];
function readBlobAsDataURL(blob) { function readBlobAsDataURL(blob) {
...@@ -30,6 +32,7 @@ ...@@ -30,6 +32,7 @@
} }
function takePicture(el) { function takePicture(el) {
var start, end;
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
return imageCapture.takePhoto({imageWidth: imageWidth}); return imageCapture.takePhoto({imageWidth: imageWidth});
...@@ -38,21 +41,46 @@ ...@@ -38,21 +41,46 @@
return readBlobAsDataURL(blob); return readBlobAsDataURL(blob);
}) })
.push(function (result) { .push(function (result) {
photoInput.setAttribute("value", result.split(",")[1]);
photo.setAttribute("src", result); photo.setAttribute("src", result);
photo.setAttribute("width", imageWidth); photo.setAttribute("width", imageWidth);
photo.setAttribute("height", imageHeight); photo.setAttribute("height", imageHeight);
el.querySelector(".capture-button").style.display = ""; photoInput.setAttribute("value", result.split(",")[1]);
return drawCanvas(el, photo); return drawCanvas(el, photo);
}); });
} }
function setPageOne(root) { function setPageOne(root) {
root.querySelector(".page-number").innerText = "1"; root.querySelector(".page-number").innerText = pageNumber;
root.querySelector(".reset-btn").style.display = "none";
root.querySelector(".take-picture-btn").style.display = "inline-block";
root.querySelector(".confirm-btn").style.display = "none";
root.querySelector(".camera-input").style.display = "";
if (cameraList.length > 1) {
root.querySelector(".change-camera-btn").style.display = "inline-block";
}
} }
function setPageTwo(root) { function setPageTwo(root) {
root.querySelector(".page-number").innerText = "2"; root.querySelector(".reset-btn").style.display = "inline-block";
root.querySelector(".confirm-btn").style.display = "inline-block";
root.querySelector(".take-picture-btn").style.display = "none";
root.querySelector(".camera-input").style.display = "none";
root.querySelector(".camera-output").style.display = "";
root.querySelector(".change-camera-btn").style.display = "none";
}
function disableButton(root) {
[".reset-btn", ".take-picture-btn",
".confirm-btn", ".change-camera-btn"].forEach(function (e) {
root.querySelector(e).disabled = true;
});
}
function enableButton(root) {
[".reset-btn", ".take-picture-btn",
".confirm-btn", ".change-camera-btn"].forEach(function (e) {
root.querySelector(e).disabled = false;
});
} }
function drawCanvas(gadget, img) { function drawCanvas(gadget, img) {
...@@ -176,43 +204,40 @@ ...@@ -176,43 +204,40 @@
.push(function (photoCapabilities) { .push(function (photoCapabilities) {
imageWidth = photoCapabilities.imageWidth.max; imageWidth = photoCapabilities.imageWidth.max;
imageHeight = photoCapabilities.imageHeight.max; imageHeight = photoCapabilities.imageHeight.max;
root.querySelector(".camera-output").style.maxWidth = imageWidth;
root.querySelector(".camera-output").style.maxHeight = imageHeight;
return video.play(); return video.play();
}) })
.push(function () { .push(function () {
root.querySelector(".camera-input").style.display = ""; return setPageOne(root);
}); });
} }
function startup(root, device_id) { function startup(root, device_id) {
video = root.querySelector(".video"); video = root.querySelector(".video");
canvas = root.querySelector(".canvas"); canvas = root.querySelector(".canvas");
photo = root.querySelector(".photo"); photo = root.querySelector("img");
photoInput = root.querySelector(".photoInput"); photoInput = root.querySelector(".photoInput");
return handleUserMedia(root, device_id, gotStream); return handleUserMedia(root, device_id, gotStream);
} }
function clearphoto() {
var data, context = canvas.getContext("2d");
context.fillRect(0, 0, canvas.width, canvas.height);
data = canvas.toDataURL("image/png");
photo.setAttribute("src", data);
}
rJS(window) rJS(window)
.declareAcquiredMethod("customSubmitDialog", "customSubmitDialog")
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var root; var root;
return this.getElement() return this.getElement()
.push(function (element) { .push(function (element) {
root = element; root = element;
pageNumber = 1;
preferredCroppedCanvasData = preferredCroppedCanvasData || JSON.parse( preferredCroppedCanvasData = preferredCroppedCanvasData || JSON.parse(
options.preferred_cropped_canvas_data options.preferred_cropped_canvas_data
); );
dialogMethod = preferredCroppedCanvasData.dialog_method;
// Clear photo input // Clear photo input
element.querySelector('.photoInput').value = ""; element.querySelector('.photoInput').value = "";
if (deviceId) { if (deviceId) {
root.querySelector(".camera-input").style.display = ""; root.querySelector(".camera-input").style.display = "";
root.querySelector(".capture-button").style.display = "";
root.querySelector(".camera-output").style.display = "none"; root.querySelector(".camera-output").style.display = "none";
} }
if (!navigator.mediaDevices) { if (!navigator.mediaDevices) {
...@@ -224,15 +249,21 @@ ...@@ -224,15 +249,21 @@
var j, var j,
device, device,
len = info_list.length; len = info_list.length;
for (j = 0; j < len; j += 1) {
device = info_list[j]; if (cameraList.length === 0) {
if (device.kind === 'videoinput') { for (j = 0; j < len; j += 1) {
cameraList.push(device); device = info_list[j];
if (device.kind === 'videoinput') {
cameraList.push(device);
}
} }
} }
if (cameraList.length >= 1) { if (cameraList.length >= 1) {
// trick to select back camera in mobile // trick to select back camera in mobile
deviceId = cameraList[cameraList.length - 1].deviceId; deviceId = cameraList[cameraList.length - 1].deviceId;
}
if (deviceId) {
return startup(root, deviceId); return startup(root, deviceId);
} }
}); });
...@@ -240,45 +271,37 @@ ...@@ -240,45 +271,37 @@
.declareMethod('getContent', function () { .declareMethod('getContent', function () {
var input = this.element.querySelector('.photoInput'), var input = this.element.querySelector('.photoInput'),
result = {}; result = {};
result.field_your_document_scanner_gadget = JSON.stringify({ result.field_your_document_scanner_gadget = JSON.stringify({
"input_value": input.value, "input_value": input.value,
"preferred_cropped_canvas_data": preferredCroppedCanvasData "preferred_cropped_canvas_data": preferredCroppedCanvasData
}); });
return result; return result;
}) })
/*.onEvent("change", function (evt) {
if (evt.target.type === "select-one") {
return this.getElement()
.push(function (root) {
var display;
if (stream !== undefined) {
// Stop the streams
stream.getTracks().forEach(function (track) {
track.stop();
});
}
if (!evt.target.value) {
display = "none";
} else {
display = "";
}
root.querySelector(".camera-input").style.display = display;
if (evt.target.value) {
return startup(root, evt.target.value);
}
});
}
}, false, true)*/
.onEvent("click", function (evt) { .onEvent("click", function (evt) {
var root; var root,
newPreferredCroppedCanvasData,
gadget = this;
if (evt.target.name === "grayscale") { if (evt.target.name === "grayscale") {
return this.getElement() return this.getElement()
.push(function () { .push(function () {
return grayscale(canvas, photo); return grayscale(canvas, photo);
}); });
} }
if (evt.target.className === "startbutton") { if (evt.target.className.indexOf("change-camera-btn") !== -1) {
evt.preventDefault();
for (var e in cameraList) {
if (cameraList[e].deviceId !== deviceId) {
deviceId = cameraList[e].deviceId;
break;
}
}
return gadget.getElement()
.push(function (root) {
return startup(root, deviceId);
});
}
if (evt.target.className.indexOf("take-picture-btn") !== -1) {
evt.preventDefault(); evt.preventDefault();
return this.getElement() return this.getElement()
.push(function (el) { .push(function (el) {
...@@ -290,7 +313,7 @@ ...@@ -290,7 +313,7 @@
return setPageTwo(root); return setPageTwo(root);
}); });
} }
if (evt.target.className === "reset-button") { if (evt.target.className.indexOf("reset-btn") !== -1) {
evt.preventDefault(); evt.preventDefault();
return this.getElement() return this.getElement()
.push(function (el) { .push(function (el) {
...@@ -300,19 +323,25 @@ ...@@ -300,19 +323,25 @@
return setPageOne(el); return setPageOne(el);
}); });
} }
if (evt.target.className === "capture-button") { if (evt.target.className.indexOf("confirm-btn") !== -1) {
evt.preventDefault(); evt.preventDefault();
preferredCroppedCanvasData = cropper.getData(); newPreferredCroppedCanvasData = cropper.getData();
for (var p in newPreferredCroppedCanvasData) {
if (newPreferredCroppedCanvasData.hasOwnProperty(p)) {
preferredCroppedCanvasData[p] = newPreferredCroppedCanvasData[p];
}
}
return this.getElement() return this.getElement()
.push(function (el) { .push(function (el) {
root = el; root = el;
disableButton(root);
return cropper.getCroppedCanvas(); return cropper.getCroppedCanvas();
}) })
.push(function (canvas) { .push(function (canvas) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
canvas.toBlob(function (blob) { canvas.toBlob(function (blob) {
resolve(blob); resolve(blob);
}); }, 'image/jpeg', 0.85);
}); });
}) })
.push(function (blob) { .push(function (blob) {
...@@ -325,11 +354,15 @@ ...@@ -325,11 +354,15 @@
photo.src = base64data; photo.src = base64data;
photoInput.value = realData; photoInput.value = realData;
root.querySelector(".camera-input").style.display = "none";
root.querySelector(".camera-output").style.display = "";
root.querySelector(".capture-button").style.display = "none";
cropper.destroy(); cropper.destroy();
return setPageTwo(root); })
.push(function () {
return gadget.customSubmitDialog(dialogMethod);
})
.push(function () {
enableButton(root);
pageNumber = pageNumber + 1;
return setPageOne(root);
}); });
} }
}, false, false); }, false, false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment