From 5ea6f0fb7327703d57f6d6a151f8b709dc5c0751 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Sat, 24 Jan 2026 00:18:49 -0500 Subject: [PATCH] up --- assets/js/chat-common.js | 21 ++++++++++-- conversations.php | 69 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/assets/js/chat-common.js b/assets/js/chat-common.js index 2705a9d..ddc13e8 100644 --- a/assets/js/chat-common.js +++ b/assets/js/chat-common.js @@ -73,8 +73,25 @@ function renderMediaMessage(msg) { } case 'audio': { const src = ensureProxyUrl(effective || msg.media_url || ''); - if (src) return `
`; - return `
Audio no disponible
`; + if (!src) return `
Audio no disponible
`; + // build download link when possible (api/get_media.php?id=... or direct url or local file) + let audioDownload = null; + const candidate = isValidMediaUrl(effective) ? effective : (isValidMediaUrl(msg.media_url) ? msg.media_url : (isValidMediaUrl(localFile) ? localFile : null)); + if (candidate && candidate.indexOf && candidate.indexOf('api/get_media.php?id=') !== -1) { + const parts = candidate.split('id='); + const mid = parts[1] ? parts[1] : ''; + audioDownload = `/api/version/media-url.php?id=${encodeURIComponent(mid)}&download=1`; + } else if (candidate && /^https?:\/\//i.test(candidate)) { + audioDownload = `/api/version/media-url.php?url=${encodeURIComponent(candidate)}&download=1`; + } else if (candidate && candidate === localFile) { + audioDownload = `/api/version/media-url.php?local=${encodeURIComponent(candidate)}&download=1`; + } + + let html = `
`; + if (audioDownload) { + html += `
Descargar audio
`; + } + return html; } case 'document': { const filename = msg.filename || content || 'Documento'; diff --git a/conversations.php b/conversations.php index 9e1f612..9e44f63 100644 --- a/conversations.php +++ b/conversations.php @@ -555,6 +555,50 @@ margin-left: auto; } + /* Media thumbnails and players */ + .message-media img, .message-media .message-media-image { max-width: 320px; border-radius: 8px; display: block; height: auto; } + @media (max-width: 768px) { + .message-media img, .message-media .message-media-image { max-width: 60vw; } + } + .message-media video, .message-media audio { max-width: 100%; border-radius: 8px; } + .message-media { margin-bottom: 6px; } + + /* Quick replies: make them rectangular, full-width in panel, readable */ + .quick-replies-panel { background: #fff; border-radius: 8px; padding: 8px; box-shadow: 0 6px 18px rgba(0,0,0,0.08); } + .quick-replies-panel .btn { + border-radius: 6px; + display: block; + text-align: left; + width: 100%; + padding: 8px 10px; + margin-bottom: 6px; + white-space: normal; + overflow: hidden; + text-overflow: ellipsis; + } + + /* Recording controls: rectangular buttons and clearer contrast */ + #recording-indicator .btn { + border-radius: 6px; + padding: 6px 10px; + min-width: 84px; + } + + /* Audio control visibility: stronger border and accent color */ + .message-media audio { + background: #fff; + border: 1px solid rgba(0,0,0,0.06); + padding: 6px; + border-radius: 8px; + accent-color: var(--whatsapp-green); + box-shadow: 0 1px 3px rgba(0,0,0,0.04); + height: 40px; + } + + /* Ensure mic button contrast */ + #mic-btn { background: var(--whatsapp-green); color: #fff; border-radius: 8px; padding: 8px 10px; } + #mic-btn.recording { background: #c0392b; color: white; } + @media (max-width: 768px) { /* Fullscreen sidebar that can slide in/out */ .chat-container { padding: 0; gap: 0; } @@ -1623,7 +1667,9 @@ } if (btn) { - btn.textContent = conv.bot_enabled ? 'Bot: On' : 'Bot: Off'; + // Mostrar como acciones de Atender / Finalizar + btn.textContent = conv.bot_enabled ? 'Finalizar' : 'Atender'; + btn.title = conv.bot_enabled ? 'Finalizar atención' : 'Atender'; btn.classList.toggle('btn-outline-danger', !conv.bot_enabled); btn.classList.toggle('btn-outline-secondary', conv.bot_enabled); @@ -1644,7 +1690,9 @@ const json = await resp.json(); if (json && json.success) { conv.bot_enabled = !conv.bot_enabled; - btn.textContent = conv.bot_enabled ? 'Bot: On' : 'Bot: Off'; + // update button label to match new state + btn.textContent = conv.bot_enabled ? 'Finalizar' : 'Atender'; + btn.title = conv.bot_enabled ? 'Finalizar atención' : 'Atender'; btn.classList.toggle('btn-outline-danger', !conv.bot_enabled); btn.classList.toggle('btn-outline-secondary', conv.bot_enabled); } else { @@ -1822,6 +1870,23 @@ this.conversations = messages.concat(this.conversations); } + // Dedupe messages by message_id (keep the last occurrence) + try { + const seen = new Map(); + for (let i = this.conversations.length - 1; i >= 0; i--) { + const m = this.conversations[i]; + if (m && m.message_id) { + if (seen.has(m.message_id)) { + this.conversations.splice(i, 1); + } else { + seen.set(m.message_id, true); + } + } + } + } catch (e) { + console.warn('Dedupe failed', e); + } + // Actualizar estado de paginación this.hasMoreMessages = hasMore; if (earliest) this.earliestMessage = earliest;