From baa816b9489664a011ddc073a60b5633bdf46f9b Mon Sep 17 00:00:00 2001 From: rajchales-monito Date: Fri, 24 Jul 2026 15:11:13 +0200 Subject: [PATCH] Keep admin alerts until unread chats are opened --- public/admin.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/public/admin.js b/public/admin.js index ddbfcd9..420b1d5 100644 --- a/public/admin.js +++ b/public/admin.js @@ -94,9 +94,9 @@ $("#settingsForm").brandHex.addEventListener("input", (event) => { if (color) $("#settingsForm").brand.value = color; }); -window.addEventListener("focus", stopAttention); +window.addEventListener("focus", syncAttentionWithUnread); document.addEventListener("visibilitychange", () => { - if (!document.hidden) stopAttention(); + if (!document.hidden) syncAttentionWithUnread(); }); $("#onlineToggle").addEventListener("change", async () => { @@ -302,6 +302,7 @@ async function loadConversations() { state.conversations = data.conversations; syncConversationVisitors(); renderConversations(); + syncAttentionWithUnread(); } async function loadVisitors() { @@ -314,7 +315,6 @@ async function loadVisitors() { } async function openConversation(id) { - stopAttention(); state.activeId = id; const data = await api(`/api/admin/conversations/${id}`); state.active = data; @@ -323,6 +323,7 @@ async function openConversation(id) { syncConversationVisitors(); renderConversations(); renderActive(); + syncAttentionWithUnread(); } function connectEvents() { @@ -345,13 +346,17 @@ function connectEvents() { renderVisitors(); return; } + const visitorMessage = isVisitorMessageEvent(data); + const eventConversationId = eventConversationIdFrom(data); + const shouldNotify = data.type === "conversation:new" || (visitorMessage && eventConversationId !== state.activeId); await loadConversations(); if (data.type === "conversation:delete" && data.conversationId === state.activeId) { clearActiveConversation(); return; } if (state.activeId) await openConversation(state.activeId).catch(() => clearActiveConversation()); - if (data.type === "conversation:new" || isVisitorMessageEvent(data)) notify(); + if (shouldNotify) notify(); + else syncAttentionWithUnread(); }); } @@ -647,6 +652,7 @@ function clearActiveConversation() { `; $("#messages").innerHTML = ""; $("#replyForm").classList.add("hidden"); + syncAttentionWithUnread(); } function renderAttachments(attachments) { @@ -888,6 +894,19 @@ function stopRepeatingSound() { state.soundRepeatTimer = null; } +function hasUnreadConversations() { + return state.conversations.some((conversation) => conversation.hasUnread && conversation.id !== state.activeId); +} + +function syncAttentionWithUnread() { + if (hasUnreadConversations()) { + startAttention(); + startRepeatingSound(); + return; + } + stopAttention(); +} + function soundPattern(style) { const patterns = { tap: [ @@ -951,6 +970,10 @@ function isVisitorMessageEvent(data) { return messages[messages.length - 1]?.senderType === "visitor"; } +function eventConversationIdFrom(data) { + return data.conversationId || data.conversation?.id || data.payload?.conversation?.id || null; +} + function flashTyping() { $("#typingNotice").classList.remove("hidden"); clearTimeout(flashTyping.timer);