fix: (BREAKING CHANGE) remove only your device call membership if room is not msc3757

This commit is contained in:
td 2025-09-16 10:52:22 +02:00
parent 86ad4689db
commit 9b0e9b7c56
No known key found for this signature in database
GPG Key ID: 62A30523D4D6CE28
2 changed files with 44 additions and 9 deletions

View File

@ -197,7 +197,6 @@ class GroupCallSession {
} }
return room.removeFamedlyCallMemberEvent( return room.removeFamedlyCallMemberEvent(
groupCallId, groupCallId,
client.deviceID!,
voip, voip,
application: application, application: application,
scope: scope, scope: scope,

View File

@ -121,12 +121,14 @@ extension FamedlyCallMemberEventsExtension on Room {
await setFamedlyCallMemberEvent( await setFamedlyCallMemberEvent(
newContent, newContent,
callMembership.voip, callMembership.voip,
callMembership.callId,
application: callMembership.application,
scope: callMembership.scope,
); );
} }
Future<void> removeFamedlyCallMemberEvent( Future<void> removeFamedlyCallMemberEvent(
String groupCallId, String groupCallId,
String deviceId,
VoIP voip, { VoIP voip, {
String? application = 'm.call', String? application = 'm.call',
String? scope = 'm.room', String? scope = 'm.room',
@ -140,7 +142,7 @@ extension FamedlyCallMemberEventsExtension on Room {
ownMemberships.removeWhere( ownMemberships.removeWhere(
(mem) => (mem) =>
mem.callId == groupCallId && mem.callId == groupCallId &&
mem.deviceId == deviceId && mem.deviceId == client.deviceID! &&
mem.application == application && mem.application == application &&
mem.scope == scope, mem.scope == scope,
); );
@ -148,7 +150,13 @@ extension FamedlyCallMemberEventsExtension on Room {
final newContent = { final newContent = {
'memberships': List.from(ownMemberships.map((e) => e.toJson())), 'memberships': List.from(ownMemberships.map((e) => e.toJson())),
}; };
await setFamedlyCallMemberEvent(newContent, voip); await setFamedlyCallMemberEvent(
newContent,
voip,
groupCallId,
application: application,
scope: scope,
);
_restartDelayedLeaveEventTimer?.cancel(); _restartDelayedLeaveEventTimer?.cancel();
if (_delayedLeaveEventId != null) { if (_delayedLeaveEventId != null) {
@ -163,7 +171,10 @@ extension FamedlyCallMemberEventsExtension on Room {
Future<void> setFamedlyCallMemberEvent( Future<void> setFamedlyCallMemberEvent(
Map<String, List> newContent, Map<String, List> newContent,
VoIP voip, VoIP voip,
) async { String groupCallId, {
String? application = 'm.call',
String? scope = 'm.room',
}) async {
if (canJoinGroupCall) { if (canJoinGroupCall) {
final stateKey = (roomVersion?.contains('msc3757') ?? false) final stateKey = (roomVersion?.contains('msc3757') ?? false)
? '${client.userID!}_${client.deviceID!}' ? '${client.userID!}_${client.deviceID!}'
@ -175,7 +186,7 @@ extension FamedlyCallMemberEventsExtension on Room {
/// can use delayed events and haven't used it yet /// can use delayed events and haven't used it yet
if (useDelayedEvents && _delayedLeaveEventId == null) { if (useDelayedEvents && _delayedLeaveEventId == null) {
// get existing ones // get existing ones and cancel them
final List<ScheduledDelayedEvent> alreadyScheduledEvents = []; final List<ScheduledDelayedEvent> alreadyScheduledEvents = [];
String? nextBatch; String? nextBatch;
final sEvents = await client.getScheduledDelayedEvents(); final sEvents = await client.getScheduledDelayedEvents();
@ -200,14 +211,39 @@ extension FamedlyCallMemberEventsExtension on Room {
); );
} }
Map<String, List> newContent;
if (roomVersion?.contains('msc3757') ?? false) {
// scoped to deviceIds so clear the whole mems list
newContent = {
'memberships': [],
};
} else {
// only clear our own deviceId
final ownMemberships = getCallMembershipsForUser(
client.userID!,
client.deviceID!,
voip,
);
ownMemberships.removeWhere(
(mem) =>
mem.callId == groupCallId &&
mem.deviceId == client.deviceID! &&
mem.application == application &&
mem.scope == scope,
);
newContent = {
'memberships': List.from(ownMemberships.map((e) => e.toJson())),
};
}
_delayedLeaveEventId = await client.setRoomStateWithKeyWithDelay( _delayedLeaveEventId = await client.setRoomStateWithKeyWithDelay(
id, id,
EventTypes.GroupCallMember, EventTypes.GroupCallMember,
stateKey, stateKey,
voip.timeouts!.delayedEventApplyLeave.inMilliseconds, voip.timeouts!.delayedEventApplyLeave.inMilliseconds,
{ newContent,
'memberships': [],
},
); );
_restartDelayedLeaveEventTimer = Timer.periodic( _restartDelayedLeaveEventTimer = Timer.periodic(