From 50484b2483947a91f24f05d0950bcac3924e573f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Bene=C5=A1?= Date: Sat, 1 Aug 2026 00:31:26 +0200 Subject: [PATCH] One thread template, one sidebar toggle chat/index.html and chat/_thread.html held the same loop, so anything added to the conversation -- a compaction divider, say -- would have had to be written into both and kept in step by hand. index.html includes the partial instead. The sidebar toggle was a raw inline onclick, the only one left in the application. app.js already delegates [data-toggle="#selector"] and gives open/close, aria-expanded and an is-active button state for free; the chat settings gear has used it all along. Also deletes the .sidebar[data-collapsed="true"] rule, which nothing has ever set. Co-Authored-By: Claude Opus 5 (1M context) --- src/lembas/web/static/css/app.css | 4 +++- src/lembas/web/templates/chat/_thread.html | 6 +++++- src/lembas/web/templates/chat/index.html | 13 +++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/lembas/web/static/css/app.css b/src/lembas/web/static/css/app.css index 98580e7..ca59b6b 100644 --- a/src/lembas/web/static/css/app.css +++ b/src/lembas/web/static/css/app.css @@ -626,7 +626,9 @@ button, input, textarea, select { z-index: 40; box-shadow: var(--shadow-lg); } - .sidebar[data-collapsed="true"] { display: none; } + /* Hiding it is the `hidden` attribute, forced to win at the top of this + file. There used to be a `[data-collapsed="true"]` rule here that nothing + ever set. */ } /* --- Toasts ---------------------------------------------------------------- diff --git a/src/lembas/web/templates/chat/_thread.html b/src/lembas/web/templates/chat/_thread.html index f6fc28d..c3c1afa 100644 --- a/src/lembas/web/templates/chat/_thread.html +++ b/src/lembas/web/templates/chat/_thread.html @@ -1,7 +1,11 @@ {# The whole thread. Returned after a rewind, which changes an arbitrary number of messages at once -- replacing the lot is simpler and less error-prone than - working out which individual bubbles to remove. + working out which individual bubbles to remove. Also included by + chat/index.html, so the conversation is described in exactly one place. + + Deliberately has no root element: it is swapped with innerHTML into #thread, + and an outerHTML swap would take the container with it. #} {% for message in messages %} {% with body_html = bodies.get(message.id, "") %} diff --git a/src/lembas/web/templates/chat/index.html b/src/lembas/web/templates/chat/index.html index c4dc057..0b8809c 100644 --- a/src/lembas/web/templates/chat/index.html +++ b/src/lembas/web/templates/chat/index.html @@ -16,7 +16,7 @@
@@ -161,13 +161,10 @@ {% endif %} - {% for message in messages %} - {# Markdown was rendered server-side in pages.py, keyed by message - id, so this loop stays a lookup rather than a render. #} - {% with body_html = bodies.get(message.id, "") %} - {% include "chat/_message.html" %} - {% endwith %} - {% endfor %} + {# The same include the rewind response returns, so the conversation + is described in one place. Markdown was rendered server-side in + pages.py, keyed by message id. #} + {% include "chat/_thread.html" %}