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,6 +7,7 @@ import { up as up0005DropIsAdmin } from "./migrations/0005_drop_is_admin.ts";
import { up as up0006Categories } from "./migrations/0006_categories.ts";
import { up as up0007PasswordResetTokens } from "./migrations/0007_password_reset_tokens.ts";
import { up as up0008ChatMessages } from "./migrations/0008_chat_messages.ts";
import { up as up0009ChatReply } from "./migrations/0009_chat_reply.ts";
interface Migration {
name: string;
@@ -25,6 +26,7 @@ const MIGRATIONS: Migration[] = [
{ name: "0006_categories", up: up0006Categories },
{ name: "0007_password_reset_tokens", up: up0007PasswordResetTokens },
{ name: "0008_chat_messages", up: up0008ChatMessages },
{ name: "0009_chat_reply", up: up0009ChatReply },
];
export function runMigrations(db: DatabaseSync): void {

View File

@@ -0,0 +1,17 @@
import type { DatabaseSync } from "node:sqlite";
// Adds an optional self-reference so a chat message can reply to another.
// Kept as a plain column (no FK): when the replied-to message is later deleted
// the id is retained but the join yields null, letting the UI show a subtle
// "deleted message" reference instead of breaking the insert.
//
// Idempotent: also runs against fresh databases created from schema.sql, where
// the column already exists.
export function up(db: DatabaseSync): void {
const cols = db.prepare(`PRAGMA table_info(chat_messages);`).all() as {
name: string;
}[];
if (!cols.some((c) => c.name === "reply_to_id")) {
db.exec(`ALTER TABLE chat_messages ADD COLUMN reply_to_id TEXT;`);
}
}

View File

@@ -194,11 +194,12 @@ CREATE UNIQUE INDEX idx_notifications_dedup
WHERE source_key IS NOT NULL;
CREATE TABLE chat_messages (
id TEXT NOT NULL PRIMARY KEY,
user_id TEXT NOT NULL,
body TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT,
id TEXT NOT NULL PRIMARY KEY,
user_id TEXT NOT NULL,
body TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT,
reply_to_id TEXT,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX idx_chat_messages_created ON chat_messages(created_at);