add @ mentions in chat

This commit is contained in:
JCEEE
2026-09-09 20:57:25 +01:00
parent 3f95d50d2e
commit 8a02640cdc
9 changed files with 296 additions and 40 deletions
+21 -2
View File
@@ -1,5 +1,6 @@
import { pb } from '$lib/pocketbase';
import type { ChatMessage, TypingRow } from '$lib/types';
import type { ChatMessage, TypingRow, MentionMember } from '$lib/types';
import { addAutoDismissNotice } from './notices.svelte';
interface ChatInit {
famId: string;
@@ -8,7 +9,7 @@ interface ChatInit {
actorName: string;
actorColor: string;
pbToken?: string;
members?: MentionMember[];
}
// Client id for optimistic chat messages. `crypto.randomUUID()` requires a
@@ -34,6 +35,7 @@ class ChatStore {
actorName = $state('');
actorColor = $state('');
pbToken = $state('');
members = $state<MentionMember[]>([]);
private unsubs: (() => void)[] = [];
private destroyed = false;
@@ -80,6 +82,7 @@ class ChatStore {
this.actorName = opts.actorName;
this.actorColor = opts.actorColor;
this.pbToken = opts.pbToken || '';
this.members = opts.members || [];
this.messages = [];
this.typing = {};
this.unread = 0;
@@ -160,9 +163,24 @@ class ChatStore {
if (record.authorId !== this.actorId) {
if (!this.open) this.unread++;
this.playDunk();
this.notifyIfMentioned(record);
}
}
// Toast the current user when a message @mentions them by name.
private notifyIfMentioned(record: ChatMessage) {
const lower = (record.content || '').toLowerCase();
const me = this.members.find((m) => m.id === this.actorId);
if (!me || !me.name) return;
if (!lower.includes('@' + me.name.toLowerCase())) return;
addAutoDismissNotice({
type: 'info',
title: 'You were mentioned 👋',
message: `${record.authorName || 'Someone'}: ${record.content}`,
dismissible: true
});
}
private onTyping(action: string, record: TypingRow) {
if (record.famId !== this.famId) return;
if (action === 'delete') {
@@ -310,6 +328,7 @@ class ChatStore {
for (const t of this.typingTimers.values()) clearTimeout(t);
this.typingTimers.clear();
this.initialized = false;
this.members = [];
}
}