diff --git a/conversations.php b/conversations.php index c339622..f7fda01 100644 --- a/conversations.php +++ b/conversations.php @@ -2200,6 +2200,37 @@ if (!isset($_SESSION['user_id'])) { const cd = (e.clipboardData || window.clipboardData); if (!cd) return; + // ─── Comprimir imagen pegada a JPEG vía Canvas ──────────────────────── + // Las imágenes del portapapeles llegan como PNG sin comprimir (1-5 MB). + // Facebook resetea la conexión TCP al recibir payloads grandes desde este + // contenedor → errno 55. Comprimir a JPEG 0.85 reduce el tamaño ~10x. + // Si el tipo ya es JPEG o WebP, se mantiene sin recomprimir. + const compressToJpeg = (blob) => new Promise((resolve) => { + // Si ya es JPEG o WebP, no recomprimir (ya están comprimidos) + if (blob.type === 'image/jpeg' || blob.type === 'image/webp') { + resolve(blob); + return; + } + const url = URL.createObjectURL(blob); + const img = new Image(); + img.onload = () => { + URL.revokeObjectURL(url); + const canvas = document.createElement('canvas'); + canvas.width = img.naturalWidth; + canvas.height = img.naturalHeight; + const ctx = canvas.getContext('2d'); + // Fondo blanco para transparencias PNG + ctx.fillStyle = '#ffffff'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.drawImage(img, 0, 0); + canvas.toBlob((jpegBlob) => { + resolve(jpegBlob || blob); // fallback al original si toBlob falla + }, 'image/jpeg', 0.85); + }; + img.onerror = () => { URL.revokeObjectURL(url); resolve(blob); }; + img.src = url; + }); + // Helper: convertir base64 a Blob const b64ToBlob = (b64, mime) => { const bytes = atob(b64); @@ -2209,17 +2240,26 @@ if (!isset($_SESSION['user_id'])) { return new Blob([arr], { type: mime }); }; + // Helper: procesar un blob de imagen (comprimir + preview) + const handleImageBlob = async (blob, originalName) => { + const compressed = await compressToJpeg(blob); + const name = (originalName || 'pasted_image').replace(/\.[^.]+$/, '') + '.jpg'; + const file = new File([compressed], name, { type: 'image/jpeg' }); + const max = this.getMaxFileSize(file.type); + if (file.size > max) { + alert('El archivo es demasiado grande. Máximo: ' + (max / 1024 / 1024).toFixed(0) + 'MB'); + return; + } + console.log(`Imagen pegada comprimida: ${(blob.size/1024).toFixed(0)}KB → ${(file.size/1024).toFixed(0)}KB (JPEG 0.85)`); + this.showMediaPreview(file); + }; + // 1) Si hay archivos directos en clipboard (Chrome/Edge) if (cd.files && cd.files.length) { for (const file of cd.files) { if (file && file.type && file.type.startsWith('image/')) { e.preventDefault && e.preventDefault(); - const max = this.getMaxFileSize(file.type); - if (file.size > max) { - alert('El archivo es demasiado grande. Máximo: ' + (max / 1024 / 1024).toFixed(0) + 'MB'); - return; - } - this.showMediaPreview(file); + handleImageBlob(file, file.name); return; } } @@ -2231,11 +2271,9 @@ if (!isset($_SESSION['user_id'])) { try { if (item.kind === 'file' && item.type && item.type.startsWith('image/')) { e.preventDefault && e.preventDefault(); - const file = item.getAsFile(); - if (file) { - const max = this.getMaxFileSize(file.type); - if (file.size > max) { alert('El archivo es demasiado grande. Máximo: ' + (max / 1024 / 1024).toFixed(0) + 'MB'); return; } - this.showMediaPreview(file); + const blob = item.getAsFile(); + if (blob) { + handleImageBlob(blob, blob.name || 'pasted_image.png'); return; } } else if (item.kind === 'string' && (item.type === 'text/html' || item.type === 'text/plain')) { @@ -2244,14 +2282,8 @@ if (!isset($_SESSION['user_id'])) { const m = s && s.match ? s.match(/src=["']data:(image\/[^;]+);base64,([^"']+)["']/i) : null; if (m) { try { - const mime = m[1]; - const b64 = m[2]; - const blob = b64ToBlob(b64, mime); - const ext = (mime.split('/')[1] || 'png').split('+')[0]; - const file = new File([blob], 'pasted_image.' + ext, { type: mime }); - const max = this.getMaxFileSize(file.type); - if (file.size > max) { alert('El archivo es demasiado grande. Máximo: ' + (max / 1024 / 1024).toFixed(0) + 'MB'); return; } - this.showMediaPreview(file); + const blob = b64ToBlob(m[2], m[1]); + handleImageBlob(blob, 'pasted_image.png'); } catch (err) { console.warn('paste image convert failed', err); } } });