diff --git a/static/src/js/sign_image_upload.js b/static/src/js/sign_image_upload.js index 767721e..646bf9b 100755 --- a/static/src/js/sign_image_upload.js +++ b/static/src/js/sign_image_upload.js @@ -1,9 +1,9 @@ /** @odoo-module **/ import { patch } from "@web/core/utils/patch"; -import { SignablePDFIframe } from "@sign/components/sign_request/signable_PDF_iframe"; +import { PDFIframe } from "@sign/components/sign_request/PDF_iframe"; -patch(SignablePDFIframe.prototype, { +patch(PDFIframe.prototype, { enableCustom(signItem) { super.enableCustom(signItem); if (signItem.data.type === 'image') { @@ -36,94 +36,111 @@ patch(SignablePDFIframe.prototype, { } const input = el.querySelector('.o_sign_image_upload_input'); - if (!input) return; + if (input) { + el.addEventListener('click', (e) => { + if (this.readonly || (data.responsible > 0 && data.responsible !== this.currentRole)) return; + // Prevent recursive click if clicking the input itself bubbles up + if (e.target !== input) { + input.click(); + } + }); - el.addEventListener('click', (e) => { - if (this.readonly || (data.responsible > 0 && data.responsible !== this.currentRole)) return; - // Prevent recursive click if clicking the input itself bubbles up - if (e.target !== input) { - input.click(); - } - }); + input.addEventListener('change', (e) => { + const file = e.target.files[0]; + if (!file) return; - input.addEventListener('change', (e) => { - const file = e.target.files[0]; - if (!file) return; + const reader = new FileReader(); + reader.onload = (readerEvent) => { + const img = new Image(); + img.onload = () => { + const canvas = document.createElement('canvas'); + let width = img.width; + let height = img.height; - const reader = new FileReader(); - reader.onload = (readerEvent) => { - const img = new Image(); - img.onload = () => { - const canvas = document.createElement('canvas'); - let width = img.width; - let height = img.height; - - const MAX_SIZE = 1080; - if (width > height) { - if (width > MAX_SIZE) { - height *= MAX_SIZE / width; - width = MAX_SIZE; + const MAX_SIZE = 1080; + if (width > height) { + if (width > MAX_SIZE) { + height *= MAX_SIZE / width; + width = MAX_SIZE; + } + } else { + if (height > MAX_SIZE) { + width *= MAX_SIZE / height; + height = MAX_SIZE; + } } - } else { - if (height > MAX_SIZE) { - width *= MAX_SIZE / height; - height = MAX_SIZE; + + canvas.width = width; + canvas.height = height; + + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0, width, height); + + const compressedDataUrl = canvas.toDataURL('image/jpeg', 0.7); + + // Update state and element + data.value = compressedDataUrl; + el.dataset.value = compressedDataUrl; + + // Force immediate display update + const placeholder = el.querySelector('.o_placeholder'); + if (placeholder) placeholder.remove(); + + let existingImg = el.querySelector('img'); + if (!existingImg) { + existingImg = document.createElement('img'); + existingImg.style.maxWidth = '100%'; + existingImg.style.maxHeight = '100%'; + existingImg.style.objectFit = 'contain'; + const body = el.querySelector('.sign_item_body') || el; + body.appendChild(existingImg); } - } + existingImg.src = compressedDataUrl; - canvas.width = width; - canvas.height = height; - - const ctx = canvas.getContext('2d'); - ctx.drawImage(img, 0, 0, width, height); - - const compressedDataUrl = canvas.toDataURL('image/jpeg', 0.7); - - // Update state and element - data.value = compressedDataUrl; - el.dataset.value = compressedDataUrl; - - // Force immediate display update - const placeholder = el.querySelector('.o_placeholder'); - if (placeholder) placeholder.remove(); - - let existingImg = el.querySelector('img'); - if (!existingImg) { - existingImg = document.createElement('img'); - existingImg.style.maxWidth = '100%'; - existingImg.style.maxHeight = '100%'; - existingImg.style.objectFit = 'contain'; - const body = el.querySelector('.sign_item_body') || el; - body.appendChild(existingImg); - } - existingImg.src = compressedDataUrl; - - // Notify Odoo of the value change - if (this.handleInput) { - this.handleInput(); - } + // Notify Odoo of the value change + if (this.handleInput) { + this.handleInput(); + } + }; + img.src = readerEvent.target.result; }; - img.src = readerEvent.target.result; - }; - reader.readAsDataURL(file); - }); + reader.readAsDataURL(file); + }); + } - // Performance Fix: Lazy Load existing images - const lazyImg = el.querySelector('.o_sign_image_lazy'); - if (lazyImg && lazyImg.dataset.src) { - const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - lazyImg.src = lazyImg.dataset.src; - lazyImg.onload = () => { - lazyImg.classList.remove('o_sign_image_loading'); - lazyImg.style.opacity = 1; - }; - observer.unobserve(lazyImg); - } - }); - }, { rootMargin: '200px' }); // Load 200px before reaching viewport - observer.observe(lazyImg); + // Performance Fix: Trigger lazy load if already visible + this._triggerLazyLoad(el); + } + }, + + refreshSignItemsForPage(page) { + super.refreshSignItemsForPage(page); + if (this.signItems && this.signItems[page]) { + for (const id in this.signItems[page]) { + const item = this.signItems[page][id]; + if (item && item.el) { + this._triggerLazyLoad(item.el); + } + } + } + }, + + /** + * Triggers the load of a lazy-loaded image if it has a data-src attribute + * @param {HTMLElement} el + */ + _triggerLazyLoad(el) { + if (!el) return; + const lazyImg = el.querySelector('.o_sign_image_lazy'); + if (lazyImg && lazyImg.dataset.src) { + const currentSrc = lazyImg.getAttribute('src'); + // If src is still the transparent placeholder gif or empty, load the real image + if (!currentSrc || currentSrc.startsWith('data:image/gif')) { + lazyImg.src = lazyImg.dataset.src; + lazyImg.onload = () => { + lazyImg.classList.remove('o_sign_image_loading'); + lazyImg.style.opacity = 1; + }; } } },