From 537f5a52e588d34a22a7091c4a5cbdb12d2b205b Mon Sep 17 00:00:00 2001 From: Oliver Hofmann Date: Sun, 17 May 2026 14:05:51 +0200 Subject: [PATCH] fix: walk message-author-name + chat-pane-message as siblings in document order --- src/teampulse/monitor.py | 46 +++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/teampulse/monitor.py b/src/teampulse/monitor.py index f20a81e..4806ed3 100644 --- a/src/teampulse/monitor.py +++ b/src/teampulse/monitor.py @@ -53,30 +53,32 @@ _POLL_JS = r"""() => { return msgs; } - // Meeting chat: chat-pane-message with message-author-name inside (visible only) - Array.from(document.querySelectorAll("[data-tid='chat-pane-message']")) - .filter(isVisible) - .forEach((msg, idx) => { - const senderEl = msg.querySelector("[data-tid='message-author-name']"); - const sender = senderEl ? senderEl.innerText.trim() : ''; - if (!sender) return; - // Try

elements first (plain text messages) - const pEls = msg.querySelectorAll('p'); - let text; - if (pEls.length > 0) { - text = Array.from(pEls).map(p => p.innerText.trim()).filter(t => t).join('\n'); - } else { - // Fallback: strip sender name + timestamp from innerText - let raw = msg.innerText.trim(); - if (sender && raw.startsWith(sender)) { - raw = raw.slice(sender.length); + // Meeting chat: message-author-name is a SIBLING of chat-pane-message, not a child. + // Walk both element types in document order, tracking current sender. + const chatEls = Array.from(document.querySelectorAll( + "[data-tid='message-author-name'], [data-tid='chat-pane-message']" + )); + let currentSender = ''; + chatEls.forEach((el, idx) => { + const tid = el.getAttribute('data-tid'); + if (tid === 'message-author-name') { + currentSender = el.innerText.trim(); + } else if (tid === 'chat-pane-message' && currentSender && isVisible(el)) { + const pEls = el.querySelectorAll('p'); + let text; + if (pEls.length > 0) { + text = Array.from(pEls).map(p => p.innerText.trim()).filter(t => t).join('\n'); + } else { + let raw = el.innerText.trim(); + if (currentSender && raw.startsWith(currentSender)) { + raw = raw.slice(currentSender.length); + } + raw = raw.replace(/^\s*\d{1,2}:\d{2}(?:\s*(?:AM|PM))?\s*/i, '').trim(); + text = raw; } - // Remove leading timestamp like "13:30" or "1:30 PM" - raw = raw.replace(/^\s*\d{1,2}:\d{2}(?:\s*(?:AM|PM))?\s*/i, '').trim(); - text = raw; + const id = el.getAttribute('id') || (currentSender + '_' + text.substring(0, 40)); + if (text) msgs.push({ sender: currentSender, text, id }); } - const id = msg.getAttribute('id') || (sender + '_' + text.substring(0, 40)); - msgs.push({ sender, text, id }); }); return msgs; }"""