fix(frontend): restore chat DOM structure and guard addMessage against null
CI / test (push) Successful in 1m39s
CI / docker (push) Successful in 49s

This commit is contained in:
zwitschi committed 2026-08-13 14:57:18 +02:00
1 parent 70a5159f81
commit 76397d52d7
3 files changed
+16 -6

No files matched your search

+6
View File
@@ -1155,3 +1155,9 @@ Completed the three Playout enhancement workstreams from `TODO.md`. Remaining po
- Bumped `frontend/package.json` to `1.0.13` and README version badge to `1.0.13` - Bumped `frontend/package.json` to `1.0.13` and README version badge to `1.0.13`
- Committed remaining work + `chore: bump version to 1.0.13`, tagged `1.0.13` (annotated) - Committed remaining work + `chore: bump version to 1.0.13`, tagged `1.0.13` (annotated)
- Pushed `main` + `1.0.13` to origin → CI/CD + `release.yml` builds semver images and creates the Gitea release - Pushed `main` + `1.0.13` to origin → CI/CD + `release.yml` builds semver images and creates the Gitea release
## Session 2026-08-13 — Frontend Error Fix
- Fixed `Uncaught TypeError: Cannot read properties of null (reading 'appendChild')` in the viewer bundle: `index.html` was missing the `#messages` chat container (and had a stray `</section>`), so `addMessage` crashed on WebSocket open/message.
- Restored chat panel structure: added `<section id="messages" class="chat-messages">` and wrapped `#presence-list` in `<section id="presence-panel" class="presence-panel">`.
- Made `addMessage` defensive (returns early when `#messages` is absent), matching the null-guards in `renderPresence`/`showTyping`/`hideTyping`.
+8 -5
View File
@@ -41,7 +41,7 @@
<div class="chat-header-actions"> <div class="chat-header-actions">
<span id="chat-user-label" class="chat-user-label" hidden></span> <span id="chat-user-label" class="chat-user-label" hidden></span>
<button id="auth-toggle-btn" type="button" class="btn btn-secondary">Sign in</button> <button id="auth-toggle-btn" type="button" class="btn btn-secondary">Sign in</button>
<button id="auth-logout-btn" type="button" class="btn btn-secondary" hidden>Sign out</button> <button id="users-toggle-btn" type="button" class="btn btn-secondary" aria-controls="presence-panel" aria-expanded="true">Users</button> <button type="button" class="btn btn-secondary" onclick="togglePrivateDM()">New DM</button> <button id="auth-logout-btn" type="button" class="btn btn-secondary" hidden>Sign out</button> <button id="users-toggle-btn" type="button" class="btn btn-secondary" aria-controls="presence-panel" aria-expanded="true">Users</button> <button type="button" class="btn btn-secondary" onclick="togglePrivateDM()">New DM</button>
</div> </div>
</header> </header>
@@ -55,11 +55,14 @@
<p id="auth-status" class="status-line" aria-live="polite"></p> <p id="auth-status" class="status-line" aria-live="polite"></p>
</div> </div>
<div id="dm-search-row" class="dm-search-row" hidden> <section id="messages" class="chat-messages" aria-live="polite"></section>
<input id="dm-search-input" type="text" class="input" placeholder="Search this conversation..." />
<button id="dm-search-btn" type="button" class="btn btn-secondary">Search</button>
</div>
<div id="dm-search-row" class="dm-search-row" hidden>
<input id="dm-search-input" type="text" class="input" placeholder="Search this conversation..." />
<button id="dm-search-btn" type="button" class="btn btn-secondary">Search</button>
</div>
<section id="presence-panel" class="presence-panel">
<div id="presence-list" class="presence-list"></div> <div id="presence-list" class="presence-list"></div>
</section> </section>
+2 -1
View File
@@ -119,7 +119,8 @@ function connectWebSocket(room: string) {
} }
function addMessage(type: string, text: string, sender = "", timestamp = new Date()) { function addMessage(type: string, text: string, sender = "", timestamp = new Date()) {
const messages = document.getElementById("messages")!; const messages = document.getElementById("messages");
if (!messages) return;
const div = document.createElement("div"); const div = document.createElement("div");
div.className = "message-row"; div.className = "message-row";