v3: chatbox improvements (typing indicators, answer to previous messages, backlog days separators, scroll to last message position, visual tweaks)
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 41s

This commit is contained in:
2026-06-30 12:27:03 +02:00
parent 124866ad4f
commit d2d086831e
17 changed files with 857 additions and 86 deletions

View File

@@ -7,11 +7,13 @@ import {
broadcastChatMessageUpdated,
broadcastCommentLikeUpdate,
broadcastPresence,
broadcastTyping,
broadcastVoteUpdate,
getOnlineUsers,
handleClientPong,
isUserChatOpen,
register,
setClientTyping,
unregister,
type WsClient,
} from "../services/ws-service.ts";
@@ -127,7 +129,10 @@ router.get("/ws", async (ctx) => {
handleCommentLike(client, msg.commentId, "remove");
break;
case "chat_send":
handleChatSend(client, msg.body);
handleChatSend(client, msg.body, msg.replyToId);
break;
case "chat_typing":
if (client.userId) setClientTyping(client, msg.typing);
break;
case "chat_focus":
client.chatOpen = msg.open;
@@ -144,6 +149,8 @@ router.get("/ws", async (ctx) => {
socket.addEventListener("close", () => {
unregister(client);
broadcastPresence();
// If they were mid-compose, drop them from the typing set right away.
if (client.typingAt) broadcastTyping();
});
});
@@ -214,7 +221,11 @@ function handleCommentLike(
}
}
function handleChatSend(client: WsClient, body: string): void {
function handleChatSend(
client: WsClient,
body: string,
replyToId?: string,
): void {
const { socket } = client;
if (!client.userId) {
@@ -225,7 +236,10 @@ function handleChatSend(client: WsClient, body: string): void {
}
try {
const message = createChatMessage(client.userId, body);
const message = createChatMessage(client.userId, body, replyToId);
// Sending a message ends composition — clear the typing flag before the
// message broadcast so the indicator doesn't linger next to it.
setClientTyping(client, false);
// Broadcast to everyone including the sender, so the sender's own message
// simply arrives over the socket — no optimistic-send machinery needed.
broadcastChatMessage(message);