From 22c6e8febc817ccb938e9f548cd55637aaab1947 Mon Sep 17 00:00:00 2001 From: Oliver Hofmann Date: Sun, 17 May 2026 13:53:03 +0200 Subject: [PATCH] fix: use getBoundingClientRect for visibility; DOM-based chat title logging --- src/teampulse/monitor.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/teampulse/monitor.py b/src/teampulse/monitor.py index 2cc2a15..5939c96 100644 --- a/src/teampulse/monitor.py +++ b/src/teampulse/monitor.py @@ -20,10 +20,11 @@ _POLL_JS = r"""() => { const msgs = []; // Channel meeting: channel-pane-message contains reply-message-header + message-body siblings - // Filter to visible elements only — Teams SPA keeps hidden/cached panes in the DOM + // Filter to visible elements only using bounding rect (offsetParent fails with fixed layouts) + const isVisible = el => { const r = el.getBoundingClientRect(); return r.width > 0 && r.height > 0; }; const channelPanes = Array.from( document.querySelectorAll("[data-tid='channel-pane-message']") - ).filter(el => el.offsetParent !== null); + ).filter(isVisible); if (channelPanes.length > 0) { channelPanes.forEach((pane, paneIdx) => { const els = pane.querySelectorAll( @@ -54,7 +55,7 @@ _POLL_JS = r"""() => { // Meeting chat: chat-pane-message with message-author-name inside (visible only) Array.from(document.querySelectorAll("[data-tid='chat-pane-message']")) - .filter(el => el.offsetParent !== null) + .filter(isVisible) .forEach((msg, idx) => { const senderEl = msg.querySelector("[data-tid='message-author-name']"); const sender = senderEl ? senderEl.innerText.trim() : ''; @@ -137,6 +138,8 @@ class Monitor: def poll_new_messages(self) -> list[ChatMessage]: raw = self._page.evaluate(_POLL_JS) + if raw: + print(f" [POLL] {len(raw)} Elemente, davon {sum(1 for r in raw if r['id'] not in self._seen_message_ids)} neu") new_messages = [] for item in raw: if item["id"] in self._seen_message_ids: @@ -163,10 +166,15 @@ class Monitor: print("Monitoring aktiv. Poste '!start Name' im Chat um ein Zeitfenster zu starten.") while True: - current_url = self._page.url - if current_url != last_url: - print(f" [CHAT] {current_url}") - last_url = current_url + current_chat = self._page.evaluate("""() => { + const t = document.querySelector( + "[data-tid='chat-title'], [data-tid='channelTitle-text'], [data-tid='entity-header'] h1" + ); + return t ? t.innerText.trim() : document.title; + }""") + if current_chat != last_url: + print(f" [CHAT] {current_chat}") + last_url = current_chat try: new_msgs = self.poll_new_messages()