p1: prioritize mention browser notifications
All checks were successful
CI / test (push) Successful in 21s

This commit is contained in:
2026-03-08 14:06:02 +03:00
parent f670305073
commit 539ba70294
2 changed files with 15 additions and 6 deletions

View File

@@ -238,4 +238,6 @@ Validation/runtime error during WS processing:
- On `chat_updated`, refresh chat metadata via REST (`GET /api/v1/chats` or `GET /api/v1/chats/{chat_id}`). - On `chat_updated`, refresh chat metadata via REST (`GET /api/v1/chats` or `GET /api/v1/chats/{chat_id}`).
- On reconnect/visibility restore, reconcile state by reloading already-opened chats/messages via REST - On reconnect/visibility restore, reconcile state by reloading already-opened chats/messages via REST
to recover missed `message_deleted`/delivery updates after transient disconnects or backend restarts. to recover missed `message_deleted`/delivery updates after transient disconnects or backend restarts.
- For browser notifications, mentions (`@username`) should be treated as high-priority and can bypass
per-chat-type notification toggles in client preferences.
- Use REST message history endpoints for pagination; WS is realtime transport, not history source. - Use REST message history endpoints for pagination; WS is realtime transport, not history source.

View File

@@ -104,7 +104,7 @@ export function useRealtime() {
} else if (wasInserted) { } else if (wasInserted) {
chatStore.incrementUnread(chatId, hasMentionForUser(message.text, authStore.me?.username ?? null)); chatStore.incrementUnread(chatId, hasMentionForUser(message.text, authStore.me?.username ?? null));
} }
maybeShowBrowserNotification(chatId, message, chatStore.activeChatId); maybeShowBrowserNotification(chatId, message, chatStore.activeChatId, authStore.me?.username ?? null);
} }
if (!chatStore.chats.some((chat) => chat.id === chatId)) { if (!chatStore.chats.some((chat) => chat.id === chatId)) {
scheduleReloadChats(); scheduleReloadChats();
@@ -307,7 +307,12 @@ export function useRealtime() {
return null; return null;
} }
function maybeShowBrowserNotification(chatId: number, message: Message, activeChatId: number | null): void { function maybeShowBrowserNotification(
chatId: number,
message: Message,
activeChatId: number | null,
currentUsername: string | null
): void {
const prefs = getAppPreferences(); const prefs = getAppPreferences();
if (!prefs.webNotifications) { if (!prefs.webNotifications) {
return; return;
@@ -319,16 +324,18 @@ function maybeShowBrowserNotification(chatId: number, message: Message, activeCh
return; return;
} }
const chat = useChatStore.getState().chats.find((item) => item.id === chatId); const chat = useChatStore.getState().chats.find((item) => item.id === chatId);
if (chat?.type === "private" && !prefs.privateNotifications) { const isMention = hasMentionForUser(message.text, currentUsername);
if (!isMention && chat?.type === "private" && !prefs.privateNotifications) {
return; return;
} }
if (chat?.type === "group" && !prefs.groupNotifications) { if (!isMention && chat?.type === "group" && !prefs.groupNotifications) {
return; return;
} }
if (chat?.type === "channel" && !prefs.channelNotifications) { if (!isMention && chat?.type === "channel" && !prefs.channelNotifications) {
return; return;
} }
const title = chat?.display_title || chat?.title || "New message"; const titleBase = chat?.display_title || chat?.title || "New message";
const title = isMention ? `@ Mention in ${titleBase}` : titleBase;
const preview = buildNotificationPreview(message, prefs.messagePreview); const preview = buildNotificationPreview(message, prefs.messagePreview);
void (async () => { void (async () => {