feat(17): cap discussion height at 32rem with auto-scroll to latest message
- #discussion-messages: max-height 32rem, overflow-y auto, smooth scroll - Auto-scroll to bottom on initial load, on own message sent (htmx:afterRequest), and on SSE message received from other users Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2e8c9de24e
commit
3d5d9a05ea
2 changed files with 16 additions and 0 deletions
|
|
@ -706,6 +706,12 @@
|
||||||
Section 26 — Discussion message bubbles (Phase 17)
|
Section 26 — Discussion message bubbles (Phase 17)
|
||||||
============================================================ */
|
============================================================ */
|
||||||
|
|
||||||
|
#discussion-messages {
|
||||||
|
max-height: 32rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
.message-row {
|
.message-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,11 @@
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scrollToBottom(container) {
|
||||||
|
var messages = container.querySelector("#discussion-messages");
|
||||||
|
if (messages) messages.scrollTop = messages.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
function appendMessage(container, event) {
|
function appendMessage(container, event) {
|
||||||
if (!event || !event.messageId || !event.messageHtml || messageExists(event.messageId)) {
|
if (!event || !event.messageId || !event.messageHtml || messageExists(event.messageId)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -54,6 +59,7 @@
|
||||||
var template = document.createElement("template");
|
var template = document.createElement("template");
|
||||||
template.innerHTML = event.messageHtml.trim();
|
template.innerHTML = event.messageHtml.trim();
|
||||||
list.appendChild(template.content);
|
list.appendChild(template.content);
|
||||||
|
scrollToBottom(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectDiscussion(container) {
|
function connectDiscussion(container) {
|
||||||
|
|
@ -62,6 +68,7 @@
|
||||||
var streamURL = container.dataset.discussionStreamUrl;
|
var streamURL = container.dataset.discussionStreamUrl;
|
||||||
if (!streamURL || !window.EventSource) return;
|
if (!streamURL || !window.EventSource) return;
|
||||||
|
|
||||||
|
scrollToBottom(container);
|
||||||
container.dataset.discussionStreamConnected = "true";
|
container.dataset.discussionStreamConnected = "true";
|
||||||
var source = new EventSource(streamURL);
|
var source = new EventSource(streamURL);
|
||||||
source.addEventListener("discussion-message", function (message) {
|
source.addEventListener("discussion-message", function (message) {
|
||||||
|
|
@ -95,5 +102,8 @@
|
||||||
form.reset();
|
form.reset();
|
||||||
var textarea = form.querySelector("#discussion-message-body");
|
var textarea = form.querySelector("#discussion-message-body");
|
||||||
if (textarea) textarea.value = "";
|
if (textarea) textarea.value = "";
|
||||||
|
|
||||||
|
var tab = form.closest("[data-discussion-stream-url]");
|
||||||
|
if (tab) scrollToBottom(tab);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue