up
This commit is contained in:
+115
-58
@@ -1425,6 +1425,9 @@ if (!isset($_SESSION['user_id'])) {
|
||||
// Solo incrementar unread_count si no es la conversación activa
|
||||
if (String(this.currentUserId) !== String(userId)) {
|
||||
conv.unread_count = (conv.unread_count || 0) + 1;
|
||||
} else {
|
||||
// Si es la conversación activa, mantener unread_count en 0
|
||||
conv.unread_count = 0;
|
||||
}
|
||||
|
||||
// Mover al inicio de la lista
|
||||
@@ -1445,8 +1448,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
|
||||
// Re-renderizar solo la lista de conversaciones
|
||||
console.log('🔄 Re-renderizando lista de conversaciones...');
|
||||
console.log('🔍 Verificando this:', this);
|
||||
console.log('🔍 this.renderConversations existe?', typeof this.renderConversations);
|
||||
console.log('🔍 Filtro activo:', this.conversationFilter);
|
||||
console.log('🔍 this.conversations:', this.conversations);
|
||||
|
||||
if (typeof this.renderConversations === 'function') {
|
||||
@@ -2252,8 +2254,14 @@ if (!isset($_SESSION['user_id'])) {
|
||||
filterSelect.value = this.conversationFilter;
|
||||
filterSelect.addEventListener('change', (e) => {
|
||||
this.conversationFilter = e.target.value || 'all';
|
||||
// reload conversations from first page
|
||||
this.loadConversations(1, false);
|
||||
console.log('🔍 Filtro cambiado a:', this.conversationFilter);
|
||||
// Re-renderizar la lista actual sin recargar desde el servidor
|
||||
this.renderConversations();
|
||||
// También recargar desde el servidor para asegurar datos actualizados
|
||||
// (pero esto es secundario y puede ser en background)
|
||||
this.loadConversations(1, false).catch(err => {
|
||||
console.warn('Error recargando conversaciones después de cambiar filtro:', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2505,8 +2513,16 @@ if (!isset($_SESSION['user_id'])) {
|
||||
}
|
||||
|
||||
console.log('✅ Container encontrado:', container);
|
||||
console.log('🔍 Filtro activo:', this.conversationFilter);
|
||||
|
||||
if (this.conversations.length === 0) {
|
||||
// Aplicar filtro de no leídos
|
||||
let conversationsToShow = this.conversations;
|
||||
if (this.conversationFilter === 'unread') {
|
||||
conversationsToShow = this.conversations.filter(c => (c.unread_count || 0) > 0);
|
||||
console.log(`🔍 Filtro 'unread' aplicado: ${conversationsToShow.length} de ${this.conversations.length} conversaciones`);
|
||||
}
|
||||
|
||||
if (conversationsToShow.length === 0) {
|
||||
const emptyMsg = this.conversationFilter === 'unread' ? 'No hay conversaciones no leídas' : 'No hay conversaciones aún';
|
||||
container.innerHTML = `
|
||||
<div class="text-center p-4">
|
||||
@@ -2518,13 +2534,35 @@ if (!isset($_SESSION['user_id'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('📋 Generando HTML para', this.conversations.length, 'conversaciones');
|
||||
console.log('📋 Generando HTML para', conversationsToShow.length, 'conversaciones');
|
||||
|
||||
// Ahora el backend devuelve por usuario: last_message, last_time, unread_count y avatar_url
|
||||
const html = this.conversations.map(conv => {
|
||||
const html = conversationsToShow.map(conv => {
|
||||
const isActive = conv.user_id == this.currentUserId ? 'active' : '';
|
||||
const time = this.formatTime(conv.last_time);
|
||||
const preview = this.truncateText(conv.last_message || 'Sin mensajes', 50);
|
||||
|
||||
// Mostrar miniatura si el último mensaje es multimedia y tiene archivo local
|
||||
let preview = '';
|
||||
const hasLocalMedia = conv.last_local_file || conv.last_local_thumb;
|
||||
const isMediaType = conv.message_type && ['image', 'video', 'audio', 'document'].includes(conv.message_type);
|
||||
|
||||
if (hasLocalMedia && isMediaType) {
|
||||
const thumbSrc = conv.last_local_thumb || conv.last_local_file;
|
||||
const mediaIcon = {
|
||||
'image': '🖼️',
|
||||
'video': '🎥',
|
||||
'audio': '🎵',
|
||||
'document': '📎'
|
||||
}[conv.message_type] || '📎';
|
||||
|
||||
if (conv.message_type === 'image' || conv.message_type === 'video') {
|
||||
preview = `<img src="/${thumbSrc}" alt="media" style="width:40px; height:40px; object-fit:cover; border-radius:4px; margin-right:8px; vertical-align:middle;"> ${mediaIcon} ${conv.last_message || 'Multimedia'}`;
|
||||
} else {
|
||||
preview = `${mediaIcon} ${conv.last_message || 'Archivo'}`;
|
||||
}
|
||||
} else {
|
||||
preview = this.truncateText(conv.last_message || 'Sin mensajes', 50);
|
||||
}
|
||||
|
||||
const avatar = conv.avatar_url ? `<img src="${conv.avatar_url}" alt="avatar" class="conversation-avatar-img">` : `<div class="conversation-avatar">${this.getInitials(conv.name)}</div>`;
|
||||
|
||||
@@ -2555,7 +2593,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
|
||||
console.log('📄 HTML generado, longitud:', html.length, 'caracteres');
|
||||
|
||||
// Detectar nuevas notificaciones: comparar unread counts previos
|
||||
// Detectar nuevas notificaciones: comparar unread counts previos (usar todas las conversaciones, no solo las filtradas)
|
||||
if (!this._prevConversations) this._prevConversations = {};
|
||||
this.conversations.forEach(c => {
|
||||
const prev = this._prevConversations[c.user_id] || { unread_count: 0 };
|
||||
@@ -2690,6 +2728,14 @@ if (!isset($_SESSION['user_id'])) {
|
||||
// Clear any staged messages from a previous conversation and hide indicator
|
||||
try { if (this._stagedMessageIds) { this._stagedMessageIds.clear(); this._stagedCount = 0; this.hideNewMessagesIndicator(); } } catch(e) {}
|
||||
|
||||
// Actualizar inmediatamente el contador de no leídos a 0 en la lista local
|
||||
const conv = this.conversations.find(c => c.user_id === userId);
|
||||
if (conv) {
|
||||
conv.unread_count = 0;
|
||||
// Re-renderizar la lista para reflejar el cambio inmediatamente
|
||||
this.renderConversations();
|
||||
}
|
||||
|
||||
// Actualizar UI
|
||||
document.getElementById('no-conversation').style.display = 'none';
|
||||
document.getElementById('chat-area').style.display = 'flex';
|
||||
@@ -2706,8 +2752,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
});
|
||||
document.querySelector(`[data-user-id="${userId}"]`)?.classList.add('active');
|
||||
|
||||
// Actualizar estado del toggle del bot según datos de la conversación
|
||||
const conv = this.conversations.find(c => c.user_id === userId);
|
||||
// Actualizar estado del toggle del bot según datos de la conversación (ya obtuvimos conv arriba)
|
||||
if (conv) {
|
||||
const btn = document.getElementById('bot-toggle');
|
||||
const holdIndicator = document.getElementById('hold-indicator');
|
||||
@@ -4744,6 +4789,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
|
||||
const uploadResponse = await fetch('api/upload_media.php', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin', // Enviar cookies de sesión
|
||||
body: formData
|
||||
});
|
||||
const uploadContentType = uploadResponse.headers.get('content-type') || '';
|
||||
@@ -4769,6 +4815,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
|
||||
const sendResponse = await fetch('api/send_media_message.php', {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin', // Enviar cookies de sesión
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
@@ -4834,9 +4881,13 @@ if (!isset($_SESSION['user_id'])) {
|
||||
}
|
||||
|
||||
// Éxito
|
||||
console.log('✅ Archivo enviado exitosamente, recargando mensajes...');
|
||||
this.cancelMediaUpload();
|
||||
await this.loadconversations(this.currentUserId, false);
|
||||
// SSE actualizará las conversaciones automáticamente
|
||||
|
||||
// Recargar mensajes para mostrar el multimedia recién enviado
|
||||
await this.loadMessages(this.currentUserId, true, true);
|
||||
|
||||
// SSE actualizará las conversaciones en la lista automáticamente
|
||||
// this.loadConversations();
|
||||
|
||||
} catch (error) {
|
||||
@@ -4867,27 +4918,60 @@ if (!isset($_SESSION['user_id'])) {
|
||||
renderMediaMessage(message) {
|
||||
if (!message) return '';
|
||||
const mediaType = message.message_type || message.media_type || 'text';
|
||||
const mediaUrl = message.media_url || message.media_url_external || '';
|
||||
const mediaUrl = message.media_url || '';
|
||||
const mediaUrlExternal = message.media_url_external || '';
|
||||
const caption = message.content || '';
|
||||
const localFile = message.local_file || '';
|
||||
const localThumb = message.local_thumb || '';
|
||||
const thumb = localThumb ? (`/${localThumb}`) : (localFile ? (`/${localFile}`) : (message.media_url_external || mediaUrl));
|
||||
|
||||
const messageId = message.id || message.message_id || '';
|
||||
|
||||
// Debug completo del mensaje
|
||||
if (mediaType === 'audio' || mediaType === 'image' || mediaType === 'video') {
|
||||
console.log(`🎵 Media message (${mediaType}) - Datos completos:`, {
|
||||
id: messageId,
|
||||
localFile: localFile,
|
||||
localThumb: localThumb,
|
||||
mediaUrl: mediaUrl,
|
||||
mediaUrlExternal: mediaUrlExternal,
|
||||
hasLocalFile: !!localFile,
|
||||
messageType: mediaType
|
||||
});
|
||||
}
|
||||
|
||||
// Prioridad: archivo local > proxy con DB id > media_url_external > URL externa
|
||||
let full = '';
|
||||
let thumb = '';
|
||||
|
||||
if (localFile) {
|
||||
full = `/api/version/media-url.php?local=${encodeURIComponent(localFile)}`;
|
||||
} else if (message.media_url_external) {
|
||||
if (message.media_url_external.indexOf('api/get_media.php?id=') !== -1) {
|
||||
const parts = message.media_url_external.split('id=');
|
||||
const mid = parts[1] ? decodeURIComponent(parts[1]) : '';
|
||||
full = `/api/version/media-url.php?id=${encodeURIComponent(mid)}`;
|
||||
} else if (/^https?:\/\//i.test(message.media_url_external)) {
|
||||
full = message.media_url_external;
|
||||
} else {
|
||||
full = `/api/version/media-url.php?url=${encodeURIComponent(message.media_url_external)}`;
|
||||
}
|
||||
// ✅ PRIORIDAD 1: Archivo local guardado
|
||||
full = `/${localFile}`;
|
||||
thumb = localThumb ? `/${localThumb}` : `/${localFile}`;
|
||||
console.log('✅ Usando archivo local:', full);
|
||||
} else if (messageId && !mediaUrlExternal) {
|
||||
// ⚠️ PRIORIDAD 2: Usar proxy con el ID de la base de datos solo si no hay media_url_external
|
||||
full = `/api/version/media-url.php?id=${encodeURIComponent(messageId)}`;
|
||||
thumb = full;
|
||||
console.log('⚠️ No hay local_file, usando proxy con messageId:', messageId);
|
||||
} else if (mediaUrlExternal) {
|
||||
// 🔄 PRIORIDAD 3: Usar media_url_external (puede ser api/get_media.php o URL directa)
|
||||
full = mediaUrlExternal.startsWith('/') ? mediaUrlExternal : `/${mediaUrlExternal}`;
|
||||
thumb = full;
|
||||
console.log('🔄 Usando media_url_external:', full);
|
||||
} else if (mediaUrl && /^\d+$/.test(mediaUrl)) {
|
||||
// 📱 PRIORIDAD 4: Es un ID de WhatsApp (solo números)
|
||||
full = `/api/get_media.php?id=${encodeURIComponent(mediaUrl)}`;
|
||||
thumb = full;
|
||||
console.log('📱 Usando whatsapp_media_id con get_media.php:', mediaUrl);
|
||||
} else if (mediaUrl && /^https?:\/\//i.test(mediaUrl)) {
|
||||
// 🌐 PRIORIDAD 5: URL externa directa (puede estar caducada)
|
||||
full = mediaUrl;
|
||||
thumb = mediaUrl;
|
||||
console.log('🌐 Usando URL externa:', full);
|
||||
} else {
|
||||
full = mediaUrl || '';
|
||||
// ❌ Fallback: sin media disponible
|
||||
console.warn('❌ No hay fuente de media disponible para el mensaje', messageId);
|
||||
full = '';
|
||||
thumb = '';
|
||||
}
|
||||
|
||||
switch (mediaType) {
|
||||
@@ -4913,22 +4997,8 @@ if (!isset($_SESSION['user_id'])) {
|
||||
${caption ? `<div>${escapeHtml(caption)}</div>` : ''}
|
||||
`;
|
||||
case 'audio': {
|
||||
let audioSrc = '';
|
||||
if (localFile) {
|
||||
audioSrc = `/${localFile}`;
|
||||
} else if (message.media_url_external) {
|
||||
if (message.media_url_external.indexOf('api/get_media.php?id=') !== -1) {
|
||||
const parts = message.media_url_external.split('id=');
|
||||
const mid = parts[1] ? decodeURIComponent(parts[1]) : '';
|
||||
audioSrc = `/api/version/media-url.php?id=${encodeURIComponent(mid)}`;
|
||||
} else if (/^https?:\/\//i.test(message.media_url_external)) {
|
||||
audioSrc = message.media_url_external;
|
||||
} else {
|
||||
audioSrc = `/api/version/media-url.php?url=${encodeURIComponent(message.media_url_external)}`;
|
||||
}
|
||||
} else {
|
||||
audioSrc = mediaUrl;
|
||||
}
|
||||
// Para audio, usar la misma lógica de full
|
||||
let audioSrc = full;
|
||||
return `
|
||||
<div class="message-media">
|
||||
<audio controls>
|
||||
@@ -4939,20 +5009,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
`;
|
||||
}
|
||||
case 'document': {
|
||||
let docUrl = '';
|
||||
if (localFile) {
|
||||
docUrl = `/api/version/media-url.php?local=${encodeURIComponent(localFile)}&download=1`;
|
||||
} else if (message.media_url_external) {
|
||||
if (message.media_url_external.indexOf('api/get_media.php?id=') !== -1) {
|
||||
const parts = message.media_url_external.split('id=');
|
||||
const mid = parts[1] ? decodeURIComponent(parts[1]) : '';
|
||||
docUrl = `/api/version/media-url.php?id=${encodeURIComponent(mid)}&download=1`;
|
||||
} else if (/^https?:\/\//i.test(message.media_url_external)) {
|
||||
docUrl = `/api/version/media-url.php?url=${encodeURIComponent(message.media_url_external)}&download=1`;
|
||||
} else {
|
||||
docUrl = `/api/version/media-url.php?url=${encodeURIComponent(message.media_url_external)}&download=1`;
|
||||
}
|
||||
}
|
||||
let docUrl = full;
|
||||
if (!docUrl) {
|
||||
return `
|
||||
<div class="message-document disabled">
|
||||
|
||||
Reference in New Issue
Block a user