From a78c9c27ac5704b53357563a432c322d27f5584e Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Sun, 25 Jan 2026 20:46:09 -0500 Subject: [PATCH] Update conversations.php --- conversations.php | 173 ++++++++++++---------------------------------- 1 file changed, 46 insertions(+), 127 deletions(-) diff --git a/conversations.php b/conversations.php index 77450dd..690f1c3 100644 --- a/conversations.php +++ b/conversations.php @@ -2416,8 +2416,6 @@ const prependEls = []; // elements to insert at top if we loaded older messages - // calculate near-bottom late to decide scrolling after DOM updates (avoids stale value) - for (let i = 0; i < this.conversations.length; i++) { const msg = this.conversations[i]; const mid = String(msg.message_id || msg.id || ('local_' + i)); @@ -2433,134 +2431,57 @@ continue; } - if (existingEl) { - // update in place - try { - const rp = existingEl.querySelector('.reply-preview'); - if (msg.reply_to_message_id) { - const previewSrc = (this.conversations.find(m => m.message_id == msg.reply_to_message_id) || {}).content || ('Mensaje ' + msg.reply_to_message_id); - if (rp) rp.textContent = 'En respuesta a: ' + previewSrc.substring(0,140); - else { - const div = document.createElement('div'); div.className = 'reply-preview'; div.textContent = 'En respuesta a: ' + previewSrc.substring(0,140); existingEl.insertBefore(div, existingEl.firstChild); - } - } else if (rp) rp.remove(); - - const body = existingEl.querySelector('.message-content'); - if (body) { - const mediaPresent = (msg.local_thumb || msg.local_file || msg.media_url_external || msg.media_url); - const existingMedia = body.querySelector('audio,video,img'); - let existingSrc = null; - if (existingMedia) existingSrc = existingMedia.getAttribute('src') || existingMedia.getAttribute('data-src'); - const newMediaUrl = mediaPresent ? (msg.local_thumb || msg.local_file || msg.media_url_external || msg.media_url) : null; - - // If media url unchanged, keep existing element (preserve playback) - if (existingMedia && newMediaUrl && existingSrc && String(existingSrc).includes(newMediaUrl)) { - // nothing to change - } else if (existingMedia && newMediaUrl && (!existingSrc || !String(existingSrc).includes(newMediaUrl))) { - // Replace src but preserve playback state for audio/video - try { - const tag = existingMedia.tagName && existingMedia.tagName.toLowerCase(); - if (tag === 'audio' || tag === 'video') { - const currentTime = existingMedia.currentTime || 0; - const wasPaused = existingMedia.paused; - existingMedia.src = newMediaUrl; - existingMedia.addEventListener('loadedmetadata', () => { - try { - if (typeof existingMedia.duration === 'number' && !isNaN(existingMedia.duration)) { - existingMedia.currentTime = Math.min(currentTime, existingMedia.duration || currentTime); - } - } catch (e) { /* ignore */ } - try { if (!wasPaused) existingMedia.play().catch(()=>{}); } catch(e){} - }, { once: true }); - } else { - // image or other: just replace src - try { existingMedia.src = newMediaUrl; } catch(e) { body.innerHTML = window.renderMediaMessage ? window.renderMediaMessage(msg) : window.escapeHtml(msg.content || '[Mensaje]'); } - } - } catch (e) { - console.warn('preserve media update failed', e); - body.innerHTML = window.renderMediaMessage ? window.renderMediaMessage(msg) : window.escapeHtml(msg.content || '[Mensaje]'); - } - } else if (!existingMedia && newMediaUrl) { - // No existing media element, render new media block without touching other parts - try { - body.innerHTML = window.renderMediaMessage ? window.renderMediaMessage(msg) : window.escapeHtml(msg.content || '[Mensaje]'); - // If after inserting media/text the body appears empty, replace with placeholder - if ((body.textContent || '').trim() === '') { - body.innerHTML = '(Mensaje sin texto)'; - console.warn('Post-update: media/text produced empty body, set placeholder for', msg && (msg.id || msg.message_id)); - } - } catch(e) { /* ignore */ } - } else if (existingMedia && !newMediaUrl) { - // Media removed in new message: replace body with text/content - try { body.innerHTML = window.escapeHtml(msg.content || '[Mensaje]'); } catch(e) { /* ignore */ } - } - } - - const timeEl = existingEl.querySelector('.message-time'); - if (timeEl) timeEl.textContent = msg.created_at ? new Date(msg.created_at).toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' }) : ''; - const statusEl = existingEl.querySelector('.message-status'); - if (statusEl) statusEl.innerHTML = this.getStatusIcon(msg.status); - - const reactBadge = existingEl.querySelector('.reaction-badge'); - if (msg.reaction_emoji) { - if (reactBadge) reactBadge.textContent = msg.reaction_emoji; else { - const b = document.createElement('div'); b.className = 'reaction-badge'; b.textContent = msg.reaction_emoji; const bubble = existingEl.querySelector('.message-bubble') || existingEl; bubble.insertBefore(b, bubble.querySelector('.message-actions')); - } - } else if (reactBadge) reactBadge.remove(); - - } catch (e) { console.warn('update message failed', e); } - existing.delete(mid); + // Renderizar imagen si corresponde + let content = ''; + if (msg.media_type === 'image' || msg.message_type === 'image' || msg.type === 'image') { + const imageUrl = msg.media_url || msg.image_url || msg.url || msg.local_thumb || msg.local_file || msg.media_url_external || msg.content; + const caption = msg.caption || msg.message_text || msg.content || ''; + content = `Imagen recibida`; + if (caption) content += `
${caption}
`; + } else if (msg.media_type === 'video' || msg.message_type === 'video' || msg.type === 'video') { + const videoUrl = msg.media_url || msg.url || msg.local_file || msg.media_url_external; + const caption = msg.caption || msg.message_text || ''; + content = ``; + if (caption) content += `
${caption}
`; + } else if (msg.media_type === 'audio' || msg.message_type === 'audio' || msg.type === 'audio') { + const audioUrl = msg.media_url || msg.url || msg.local_file || msg.media_url_external; + content = ``; } else { - // create new element - try { - const div = document.createElement('div'); - div.className = 'message ' + (msg.direction || 'incoming'); - div.dataset.messageId = mid; + content = window.formatMessageContent ? window.formatMessageContent(msg.content || '') : window.escapeHtml(msg.content || '[Mensaje vacío]'); + } - let replyHtml = ''; - if (msg.reply_to_message_id) { - const target = this.conversations.find(m => m.message_id == msg.reply_to_message_id || m.id == msg.reply_to_message_id); - const previewText = target ? (target.content || target.message_text || '').substring(0,140) : ('Mensaje ' + msg.reply_to_message_id); - replyHtml = `
En respuesta a: ${window.escapeHtml(previewText)}
`; - } - const mediaPresent = (msg.local_thumb || msg.local_file || msg.media_url_external || msg.media_url); - let content = mediaPresent - ? (window.renderMediaMessage ? window.renderMediaMessage(msg) : (window.formatMessageContent ? window.formatMessageContent(msg.content || '[Mensaje]') : window.escapeHtml(msg.content || '[Mensaje]'))) - : (window.formatMessageContent ? window.formatMessageContent(msg.content || '') : window.escapeHtml(msg.content || '')); + let replyHtml = ''; + if (msg.reply_to_message_id) { + const target = this.conversations.find(m => m.message_id == msg.reply_to_message_id || m.id == msg.reply_to_message_id); + const previewText = target ? (target.content || target.message_text || '').substring(0,140) : ('Mensaje ' + msg.reply_to_message_id); + replyHtml = `
En respuesta a: ${window.escapeHtml(previewText)}
`; + } - // If after formatting the content is empty (spaces or nothing), show a clearer placeholder - try { - const tmp = (content || '').replace(/<[^>]*>/g, '').trim(); // strip tags and check - if (!tmp) { - console.warn('Rendered message content empty, replacing with placeholder', mid, msg.id, msg.created_at); - content = '(Mensaje sin texto)'; - } - } catch (e) { /* ignore */ } + const time = msg.created_at ? new Date(msg.created_at).toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' }) : ''; + const statusIcon = this.getStatusIcon(msg.status); + const reactionHtml = msg.reaction_emoji ? `
${msg.reaction_emoji}
` : ''; - const time = msg.created_at ? new Date(msg.created_at).toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' }) : ''; - const statusIcon = this.getStatusIcon(msg.status); - const reactionHtml = msg.reaction_emoji ? `
${msg.reaction_emoji}
` : ''; + const div = document.createElement('div'); + div.className = 'message ' + (msg.direction || 'incoming'); + div.dataset.messageId = mid; + div.innerHTML = ` +
+ ${replyHtml} +
${content}
+ ${reactionHtml} +
+ + +
+
${time} ${msg.direction === 'outgoing' ? `${statusIcon}` : ''}
+
+ `; - div.innerHTML = ` -
- ${replyHtml} -
${content}
- ${reactionHtml} -
- - -
-
${time} ${msg.direction === 'outgoing' ? `${statusIcon}` : ''}
-
- `; - - // For prepended older messages, collect to insert at top later - if (prependCount && i < prependCount) { - prependEls.push(div); - } else { - container.appendChild(div); - } - } catch (e) { console.warn('create message failed', e); } + // For prepended older messages, collect to insert at top later + if (prependCount && i < prependCount) { + prependEls.push(div); + } else { + container.appendChild(div); } } @@ -2581,8 +2502,6 @@ if (shouldScroll) { this.scrollToBottom(); } - - } // Mostrar / quitar hint "No hay más mensajes anteriores"