Update conversations.php

This commit is contained in:
Lizandro Guarnizo
2026-01-23 23:36:20 -05:00
parent 1f1dee883e
commit 1091be531a
+26 -6
View File
@@ -729,6 +729,8 @@
this.currentConversationId = null;
this.currentUserId = null;
this.conversations = [];
// Track shown notifications to avoid duplicates from polling
this._shownNotifications = new Set();
// Message pagination / loading state
this.messageLimit = 50;
this.loadingMessages = false;
@@ -787,6 +789,15 @@
document.body.appendChild(container);
}
// Determine an id to dedupe notifications (prefer server id)
const nid = notification && notification.id ? String(notification.id) : ('msg:' + String((notification && notification.message) || '').slice(0,200));
if (this._shownNotifications.has(nid)) {
// already shown
console.debug('Notification already shown, skipping', nid);
return;
}
this._shownNotifications.add(nid);
const toast = document.createElement('div');
// compact by default
toast.className = 'notification-toast small';
@@ -808,11 +819,18 @@
const actions = document.createElement('div');
actions.className = 'nt-actions';
const removeToast = () => {
if (toast.parentNode) toast.remove();
if (this._shownNotifications.has(nid)) this._shownNotifications.delete(nid);
};
const openBtn = document.createElement('button');
openBtn.className = notification.cool ? 'btn btn-sm btn-light' : 'btn btn-sm btn-primary';
openBtn.textContent = 'Abrir';
openBtn.onclick = async () => {
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
try {
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
} catch(e) { console.warn('mark_notification_read failed', e); }
let data = {};
try { data = notification.data ? JSON.parse(notification.data) : {}; } catch(e) {}
const userId = data.user_id || notification.user_id;
@@ -824,7 +842,7 @@
this.openConversation(userId, 'Usuario', '');
}
}
toast.remove();
removeToast();
};
const dismiss = document.createElement('button');
@@ -832,8 +850,10 @@
dismiss.textContent = '×';
dismiss.title = 'Descartar';
dismiss.onclick = async () => {
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
toast.remove();
try {
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
} catch(e) { console.warn('mark_notification_read failed', e); }
removeToast();
};
actions.appendChild(openBtn);
@@ -842,12 +862,12 @@
container.appendChild(toast);
// Auto remove (shorter for compact notifications)
// Auto remove (shorter for compact notifications) with minimum enforced
const _minToastDuration = 3000;
let timeout = notification.duration ? Number(notification.duration) : (notification.cool ? 15000 : 8000);
if (!isFinite(timeout) || timeout <= 0) timeout = (notification.cool ? 15000 : 8000);
timeout = Math.max(timeout, _minToastDuration);
setTimeout(() => { if (toast.parentNode) toast.remove(); }, timeout);
setTimeout(removeToast, timeout);
}
setupEventListeners() {