971a6fdf22
#2 Don't ping/notify when you're ACTIVELY viewing a chat (app visible + chat open). Alert only when a different chat, OR the open chat while the app is minimised (the backgrounded case that used to stay silent). #3 A reaction to my message now raises an unread badge on that conversation (like a new message), not just a notification. #6 Image lightbox pulls EVERY image in the conversation via /api/messages/media (older images aren't in the DOM yet) — nav arrows reach them all. Nav buttons always in the DOM; syncArrows shows/hides at the ends and for a single image. #8 On app resume (visibilitychange / native appStateChange), reconnect the chat socket if it isn't OPEN and re-pull the sidebar so online/last-seen refresh — iOS freezes the WebView so the socket can be dead while its onclose lags, leaving contacts stuck on a stale "Offline". #9 Real cause was iOS "sticky :hover": a single tap latched :hover and popped the action bar. Gate the hover-reveal behind @media (hover:hover) so touch reveals actions ONLY via long-press; a plain tap performs the primary action. #13 Pinned bar gains a "‹ 1 of n ›" pager to walk through multiple pinned messages (shown only when more than one is pinned). #14 Editing a message no longer eats a half-written draft — the real draft is set aside on edit start and restored on save/cancel. edited_at is now in the message DTO so the "edited" tag survives a reload. #18 One "Delete" entry opens a branded dialog with "Delete for me" / "Delete for everyone" (icons + descriptions) and a ✕/backdrop cancel, replacing the two separate menu items. New: a participant who LEAVES a still-running call is no longer auto-rung back in on every socket reconnect. Track who left per call; replayActiveCalls sends them noRing state (refreshes the Join affordance without ringing). An explicit re-invite clears that and rings again. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>