Fix notification bugs #2 (open+backgrounded chat) and #3 (reactions)

#2: a message arriving in the currently-OPEN chat produced no notification
when the app was minimized. onChatMessage marked the open chat read even
while document.hidden, which fired a notif-clear that closed the very
notification the service worker had just shown. Now the open chat is only
marked read while visible; markOpenChatRead() catches up on focus/visibility
return, and a message received while hidden stays unread with its alert intact.

#3: reacting to a message fired no notification. The react route only pushed
over the live socket (nothing for a closed app) and the client added a silent
bell entry. Now the server sends a native/web push to the message owner, and
onChatReaction pings + shows an OS/in-page popup (unless you're viewing that chat).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 22:23:16 +05:30
parent a0f9ab10f2
commit 9e80aee1c6
2 changed files with 46 additions and 4 deletions
+12
View File
@@ -1712,6 +1712,18 @@ route('POST', '/api/messages/react', async (req, res) => {
try { CHAT.pushToUser(other, { type: 'chat-reaction', messageId, reactions: await reactionsForMessage(messageId, other, names), ...meta }); } catch (_) {}
try { CHAT.pushToUser(u.id, { type: 'chat-reaction', messageId, reactions: await reactionsForMessage(messageId, u.id, names), ...meta }); } catch (_) {}
}
// #3: notify the message OWNER that someone reacted — a native/web push so a CLOSED app is alerted too
// (previously reactions only pushed over the live socket, so a backgrounded owner got nothing). Only when
// the reaction was ADDED (not removed) and by someone other than the owner.
if (added && msg.sender_id && msg.sender_id !== u.id) {
const reactor = u.name || u.email;
if (msg.conversation_id) {
const conv = await R.conversations.byId(msg.conversation_id); const gname = (conv && conv.name) || 'Group';
try { PUSH.sendToUser(msg.sender_id, { title: gname, body: reactor + ' reacted ' + e + ' to your message', kind: 'group', id: msg.conversation_id, tag: 'react:' + messageId, icon: u.avatar_url || undefined }); } catch (_) {}
} else {
try { PUSH.sendToUser(msg.sender_id, { title: reactor, body: 'reacted ' + e + ' to your message', kind: 'dm', id: u.id, tag: 'react:' + messageId, icon: u.avatar_url || undefined }); } catch (_) {}
}
}
json(res, 200, { ok: true, messageId, added, reactions: await reactionsForMessage(messageId, u.id, names) });
});