From 5ac49522d9368577b3ef649ba76c99737902aa9e Mon Sep 17 00:00:00 2001 From: BordedDev <> Date: Fri, 18 Jul 2025 23:57:41 +0200 Subject: [PATCH] Fixed scrolling behavior, reply, cross channel messages --- src/snek/static/message-list.js | 9 +++++---- src/snek/templates/web.html | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/snek/static/message-list.js b/src/snek/static/message-list.js index f8352f0..386a435 100644 --- a/src/snek/static/message-list.js +++ b/src/snek/static/message-list.js @@ -10,7 +10,7 @@ import {app} from "./app.js"; const LONG_TIME = 1000 * 60 * 20 class MessageElement extends HTMLElement { - static observedAttributes = ['data-uid', 'data-color', 'data-channel_uid', 'data-user_nick', 'data-created_at', 'data-user_uid']; + // static observedAttributes = ['data-uid', 'data-color', 'data-channel_uid', 'data-user_nick', 'data-created_at', 'data-user_uid']; isVisible() { if (!this) return false; @@ -99,7 +99,9 @@ class MessageList extends HTMLElement { constructor() { super(); app.ws.addEventListener("update_message_text", (data) => { - this.upsertMessage(data); + if (this.messageMap.has(data.uid)) { + this.upsertMessage(data); + } }); app.ws.addEventListener("set_typing", (data) => { this.triggerGlow(data.user_uid,data.color); @@ -119,7 +121,6 @@ class MessageList extends HTMLElement { this.visibleSet.delete(entry.target); } }); - console.log(this.visibleSet); }, { root: this, threshold: 0.1 @@ -189,7 +190,7 @@ class MessageList extends HTMLElement { isScrolledToBottom() { return this.isElementVisible(this.firstElementChild); } - scrollToBottom(force = false, behavior= 'smooth') { + scrollToBottom(force = false, behavior= 'instant') { if (force || this.isScrolledToBottom()) { this.firstElementChild.scrollIntoView({ behavior, block: 'start' }); setTimeout(() => { diff --git a/src/snek/templates/web.html b/src/snek/templates/web.html index 46a0593..0719b36 100644 --- a/src/snek/templates/web.html +++ b/src/snek/templates/web.html @@ -72,12 +72,13 @@ function throttle(fn, wait) { // --- Scroll: load extra messages, throttled --- let isLoadingExtra = false; async function loadExtra() { - const firstMessage = messagesContainer.children[messagesContainer.children.length - 1]; + const firstMessage = messagesContainer.lastElementChild; if (isLoadingExtra || !isScrolledPastHalf() || !firstMessage) return; isLoadingExtra = true; const messages = await app.rpc.getMessages(channelUid, 0, firstMessage.dataset.created_at); if (messages.length) { const frag = document.createDocumentFragment(); + messages.reverse(); messages.forEach(msg => { const temp = document.createElement("div"); temp.innerHTML = msg.html; @@ -142,6 +143,17 @@ function replyMessage(message) { chatInputField.focus(); } +messagesContainer.addEventListener("click", (e) => { + if (e.target.tagName === "A" && e.target.getAttribute("href") === "#reply") { + e.preventDefault(); + const messageElement = e.target.closest("chat-message"); + if (messageElement) { + const messageText = messageElement.querySelector(".text").textContent.trim(); + replyMessage(messageText); + } + } +}) + // --- Mention helpers --- function extractMentions(message) { return [...new Set(message.match(/@\w+/g) || [])]; @@ -254,7 +266,7 @@ function updateLayout(doScrollDown) { function isScrolledPastHalf() { let scrollTop = messagesContainer.scrollTop; let scrollableHeight = messagesContainer.scrollHeight - messagesContainer.clientHeight; - return scrollTop < scrollableHeight / 2; + return Math.abs(scrollTop) > scrollableHeight / 2; } // --- Initial layout update ---