From 7df5561e985ef65b75a15b8f3f410b0ce5af9658 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Fri, 5 Jun 2026 20:25:50 -0400 Subject: [PATCH] fix: call ring modal only fires for DMs and private group chats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Space voice channels send room-level RTC notifications (m.mentions.room) whenever any member joins. Previously this triggered the incoming call ring modal for every member of the space, as if they were personally being called. Fix: before setting callInfo, check whether the room is a DM (in mDirectAtom) or a private non-space group (invite/knock/restricted join rule AND no m.space.parent state event). Space channels and public rooms are excluded — joining them should never ring other members. Added JoinRule to the matrix-js-sdk import. Added directs to the useCallback dependency array so the closure sees the current DM set. Co-Authored-By: Claude Sonnet 4.6 --- src/app/components/CallEmbedProvider.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/app/components/CallEmbedProvider.tsx b/src/app/components/CallEmbedProvider.tsx index cfef9b71a..ed86aa421 100644 --- a/src/app/components/CallEmbedProvider.tsx +++ b/src/app/components/CallEmbedProvider.tsx @@ -19,6 +19,7 @@ import { import { EventTimelineSetHandlerMap, EventType, + JoinRule, RelationType, Room, RoomEvent, @@ -323,6 +324,19 @@ function IncomingCallListener({ callEmbed, joined }: IncomingCallListenerProps) ); if (!hasCallPermission) return; + // Only ring for DMs or private non-space group chats. + // Space voice channels and public rooms fire room-level RTC notifications + // whenever anyone joins — ringing every member is incorrect behaviour. + const isDirect = directs.has(room.roomId); + const isSpaceChild = !!getStateEvent(room, StateEvent.SpaceParent); + const joinRule = room.getJoinRule(); + const isPrivateGroup = + !isSpaceChild && + (joinRule === JoinRule.Invite || + joinRule === JoinRule.Knock || + joinRule === JoinRule.Restricted); + if (!isDirect && !isPrivateGroup) return; + const info: IncomingCallInfo = { room, sender, @@ -338,7 +352,7 @@ function IncomingCallListener({ callEmbed, joined }: IncomingCallListenerProps) setCallInfo(info); }, - [mx], + [mx, directs], ); useEffect(() => {