wersja 0.0.4 #7
2
app.py
2
app.py
@@ -2729,4 +2729,4 @@ def create_db():
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.DEBUG if DEBUG_MODE else logging.INFO)
|
||||
socketio.run(app, host="0.0.0.0", port=8000, debug=DEBUG_MODE)
|
||||
socketio.run(app, host="0.0.0.0", port=8000, debug=False)
|
||||
|
@@ -4,22 +4,22 @@ let currentReceiptId;
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const cropModal = document.getElementById("cropModal");
|
||||
const cropImage = document.getElementById("cropImage");
|
||||
const spinner = document.getElementById("cropLoading");
|
||||
|
||||
cropModal.addEventListener("shown.bs.modal", function (event) {
|
||||
const button = event.relatedTarget;
|
||||
const imgSrc = button.getAttribute("data-img-src");
|
||||
currentReceiptId = button.getAttribute("data-receipt-id");
|
||||
|
||||
const image = document.getElementById("cropImage");
|
||||
image.src = imgSrc;
|
||||
cropImage.src = imgSrc;
|
||||
|
||||
if (cropper) {
|
||||
cropper.destroy();
|
||||
cropper = null;
|
||||
}
|
||||
|
||||
image.onload = () => {
|
||||
cropper = new Cropper(image, {
|
||||
cropImage.onload = () => {
|
||||
cropper = new Cropper(cropImage, {
|
||||
viewMode: 1,
|
||||
autoCropArea: 1,
|
||||
responsive: true,
|
||||
@@ -36,7 +36,51 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
document.getElementById("saveCrop").addEventListener("click", function () {
|
||||
if (!cropper) return;
|
||||
|
||||
cropper.getCroppedCanvas().toBlob(function (blob) {
|
||||
spinner.classList.remove("d-none");
|
||||
|
||||
const cropData = cropper.getData();
|
||||
const imageData = cropper.getImageData();
|
||||
|
||||
const scaleX = imageData.naturalWidth / imageData.width;
|
||||
const scaleY = imageData.naturalHeight / imageData.height;
|
||||
|
||||
const width = cropData.width * scaleX;
|
||||
const height = cropData.height * scaleY;
|
||||
|
||||
if (width < 1 || height < 1) {
|
||||
spinner.classList.add("d-none");
|
||||
showToast("Obszar przycięcia jest zbyt mały lub pusty", "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
// Ogranicz do 2000x2000 w proporcji
|
||||
const maxDim = 2000;
|
||||
const scale = Math.min(1, maxDim / Math.max(width, height));
|
||||
|
||||
const finalWidth = Math.round(width * scale);
|
||||
const finalHeight = Math.round(height * scale);
|
||||
|
||||
const croppedCanvas = cropper.getCroppedCanvas({
|
||||
width: finalWidth,
|
||||
height: finalHeight,
|
||||
imageSmoothingEnabled: true,
|
||||
imageSmoothingQuality: 'high',
|
||||
});
|
||||
|
||||
|
||||
if (!croppedCanvas) {
|
||||
spinner.classList.add("d-none");
|
||||
showToast("Nie można uzyskać obrazu przycięcia", "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
croppedCanvas.toBlob(function (blob) {
|
||||
if (!blob) {
|
||||
spinner.classList.add("d-none");
|
||||
showToast("Nie udało się zapisać obrazu", "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("receipt_id", currentReceiptId);
|
||||
formData.append("cropped_image", blob);
|
||||
@@ -47,6 +91,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
spinner.classList.add("d-none");
|
||||
if (data.success) {
|
||||
showToast("Zapisano przycięty paragon", "success");
|
||||
setTimeout(() => location.reload(), 1500);
|
||||
@@ -55,9 +100,10 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
spinner.classList.add("d-none");
|
||||
showToast("Błąd sieci", "danger");
|
||||
console.error(err);
|
||||
});
|
||||
}, "image/webp");
|
||||
}, "image/webp", 1.0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,4 +1,3 @@
|
||||
// receipt_crop_logic.js
|
||||
(function () {
|
||||
function initCropper(imgEl) {
|
||||
return new Cropper(imgEl, {
|
||||
@@ -22,10 +21,34 @@
|
||||
}
|
||||
|
||||
function handleCrop(endpoint, receiptId, cropper, spinner) {
|
||||
const cropData = cropper.getData();
|
||||
const imageData = cropper.getImageData();
|
||||
|
||||
const scaleX = imageData.naturalWidth / imageData.width;
|
||||
const scaleY = imageData.naturalHeight / imageData.height;
|
||||
|
||||
const width = cropData.width * scaleX;
|
||||
const height = cropData.height * scaleY;
|
||||
|
||||
if (width < 1 || height < 1) {
|
||||
spinner.classList.add("d-none");
|
||||
showToast("Obszar przycięcia jest zbyt mały lub pusty", "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
const maxDim = 2000;
|
||||
const scale = Math.min(1, maxDim / Math.max(width, height));
|
||||
|
||||
const finalWidth = Math.round(width * scale);
|
||||
const finalHeight = Math.round(height * scale);
|
||||
|
||||
const croppedCanvas = cropper.getCroppedCanvas({
|
||||
imageSmoothingEnabled: false,
|
||||
imageSmoothingQuality: "high",
|
||||
width: finalWidth,
|
||||
height: finalHeight,
|
||||
imageSmoothingEnabled: true,
|
||||
imageSmoothingQuality: 'high',
|
||||
});
|
||||
|
||||
if (!croppedCanvas) {
|
||||
spinner.classList.add("d-none");
|
||||
showToast("Nie można uzyskać obrazu przycięcia", "danger");
|
||||
@@ -65,7 +88,6 @@
|
||||
}, "image/webp", 1.0);
|
||||
}
|
||||
|
||||
|
||||
window.cropUtils = {
|
||||
initCropper,
|
||||
cleanUpCropper,
|
||||
|
Reference in New Issue
Block a user