diff --git a/b-reference/teams-bot/architecture.md b/b-reference/teams-bot/architecture.md index d617bbf..bc10ee2 100644 --- a/b-reference/teams-bot/architecture.md +++ b/b-reference/teams-bot/architecture.md @@ -1,6 +1,6 @@ - + # Teams Meeting Bot -- Architektur @@ -99,6 +99,84 @@ Es wird **keine Label-Filterung** angewendet — die Tracks haben je nach Sessio Refs: `service-teams-browser-bot/src/bot/audioCaptureProcedure.ts` (`__audioCaptureEnabled`, `__audioCaptureAttachTrack`, `startCapture`); Aufrufer `orchestrator.ts` (`_attemptJoin` STEP 4 → `_setState('in_meeting')` → `_enableTranscriptCapture`). +### Chat-Panel-Toggle-Auswahl im Auth-Layout + +Im authentifizierten Full-Teams-Layout existieren ZWEI sichtbare Buttons mit "Chat" im aria-label: + +1. der **echte Toggle**: UUID-id, `aria-label="Chat (Ctrl+Shift+2)"`, **`aria-pressed="true|false"`** — toggelt das Meeting-Chat-Side-Panel. +2. ein **Schein-Toggle**: `id="chat-button"`, `aria-label="Chat"`, **kein `aria-pressed`** — vermutlich der Side-Nav-Eintrag der Chat-App; klicken hat keinerlei Wirkung auf das Meeting-Chat-Panel. + +In light-meetings (anon) existiert nur `#chat-button` und der IST der echte Toggle (light-meetings nutzt menu-button-Semantik ohne `aria-pressed`). + +`_openChatPanel()` löst das so: + +- Sammelt alle sichtbaren `button` / `[role=button]` / `[role=menuitem]` deren `id`/`data-tid`/`aria-label`/`title` einen der Hints `chat`/`unterhalt`/`besprechung`/`conversation` enthält (sprachunabhängig). +- **Bevorzugt Kandidaten mit `aria-pressed` ∈ {`true`,`false`}** (echte Toggle-Buttons), Fallback ist der erste passende Nicht-Toggle. +- Trackt geklickte Buttons per `id|data-tid|aria-label`-Key und überspringt sie in den nächsten Runden — verhindert die Endlosschleife "klicke 12× denselben falschen Button" wenn der erste Pick nichts bewirkt. + +Refs: `service-teams-browser-bot/src/bot/chatProcedure.ts._openChatPanel`. + +### Chat-Panel-Detection + +`_isChatPanelOpen()` macht **zwei** Checks am `[data-tid="calling-right-side-panel"]`-Container — keine Fallbacks: + +1. **Existenz + echte Visibility** des Side-Pane-Containers: `offsetWidth/Height > 0 && offsetParent !== null`. Wenn das Panel zu ist, ist der Container entweder unmounted oder vom Parent auf 0×0 kollabiert. +2. **Mode-Disambiguation per chat-spezifischen Child-Tids** innerhalb des sichtbaren Containers: `message-pane-layout`, `message-pane-body`, `chat-pane-compose-message-footer`, `message-pane-footer`, `#chat-pane-list`, `[data-app-name="chats"]`. Trennt Chat sauber von People / Info / Captions ohne Text-Lookup. + +Frühere Iterationen hatten zwei zusätzliche Schichten (aria-pressed-Toggle + Compose-Box-Sichtbarkeit) als "Fallback für ältere Auth-Layouts". Diese sind 2026-05-12 entfernt worden — sowohl anon als auch auth nutzen denselben `calling-right-side-panel`-Container, die Fallbacks hätten nie gefeuert (oder wären redundant gewesen wenn doch). Konform zur Coding-Regel "Do not add fallback code, if not necessary". + +#### Trapdoor: `vdi-occlusion` + +Die CSS-Klasse `vdi-occlusion` taucht in der neuen Calling-Layout-Version **als Permanent-Klasse** auf `calling-right-side-panel` UND `message-pane-layout` auf — auch wenn das Panel sichtbar geöffnet ist. Sie ist KEIN Visibility-Indikator. Ein älterer Detection-Code, der `vdi-occlusion → "Panel zu"` ableitete, lieferte deshalb **immer** false-negative bei offenem Panel → periodischer Scan triggerte `_openChatPanel()` → klickte den Toggle → schloss das Panel echt → klickte weitere chat-aria Buttons (Side-Nav-Apps "Chats"/"Meeting chats", Tab-Items `tab-item-com.microsoft.chattabs.*`) → Endlos-Toggle-Loop mit `UPR`-Page-Errors von Teams. Visibility wird ausschließlich über `offsetWidth/Height > 0 && (offsetParent !== null || position === fixed)` geprüft. + +#### Toggle-Button selbst trägt KEINE State-Information + +Im neuen Calling-Layout ist der `