Round 2 fixes from on-device testing (#2,#3,#6,#8,#9,#13,#14,#18 + call re-ring)
#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>
This commit is contained in:
@@ -406,6 +406,10 @@ async function leaveMeeting(ws) {
|
||||
if (!peers) { if (leaverId) CHAT.broadcastPresence(leaverId); return; }
|
||||
try { await require('./calls').finalizeTranscript(room, ws._meetingUserId); } catch (_) {} // save THIS user's transcript
|
||||
peers.delete(pid);
|
||||
// #New1: remember this user LEFT, so a later socket reconnect doesn't auto-ring them back into a call that's
|
||||
// still running for the others (replayActiveCalls sends them noRing state instead). Harmless on a call that
|
||||
// then ends. Only meaningful for a group/promoted call that survives one person leaving.
|
||||
try { if (leaverId) require('./calls').markLeft(room, leaverId); } catch (_) {}
|
||||
// 1:1 call: end it for everyone ONLY when fewer than two people would remain. A DM call that had
|
||||
// extra people ADDED (via "Add people") is effectively a group now — one participant closing their
|
||||
// app must NOT hang up the call for the rest (#11). We only tear the whole thing down when ≤1 person
|
||||
|
||||
Reference in New Issue
Block a user