9e80aee1c6
#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>