diff --git a/lib/src/client.dart b/lib/src/client.dart index 8910a6ed7..e8bc59e17 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1741,6 +1741,8 @@ class Client extends MatrixApi { await processToDeviceQueue(); } catch (_) {} // we want to dispose any errors this throws + await singleShotStaleCallChecker(); + _retryDelay = Future.value(); onSyncStatus.add(SyncStatusUpdate(SyncStatus.finished)); } on MatrixException catch (e, s) { @@ -2148,6 +2150,9 @@ class Client extends MatrixApi { } } + /// stores when we last checked for stale calls + DateTime lastStaleCallRun = DateTime(0); + Future _updateRoomsByRoomUpdate( String roomId, SyncRoomUpdate chatUpdate) async { // Update the chat list item. @@ -2188,9 +2193,6 @@ class Client extends MatrixApi { } // If the membership is "leave" then remove the item and stop here else if (found && membership == Membership.leave) { - // stop stale group call checker for left room. - room.stopStaleCallsChecker(room.id); - rooms.removeAt(roomIndex); // in order to keep the archive in sync, add left room to archive diff --git a/lib/src/room.dart b/lib/src/room.dart index d65d26901..3c3b24436 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -90,9 +90,6 @@ class Room { /// Key-Value store for private account data only visible for this user. Map roomAccountData = {}; - /// stores stale group call checking timers for rooms. - Map staleGroupCallsTimer = {}; - final _sendingQueue = []; Map toJson() => { @@ -137,9 +134,6 @@ class Room { setState(state); } } - if (!isArchived) { - startStaleCallsChecker(id); - } partial = false; } diff --git a/lib/src/voip/voip_room_extension.dart b/lib/src/voip/voip_room_extension.dart index 707d84e07..c707222da 100644 --- a/lib/src/voip/voip_room_extension.dart +++ b/lib/src/voip/voip_room_extension.dart @@ -43,17 +43,6 @@ extension GroupCallUtils on Room { return []; } - /// stops the stale call checker timer - void stopStaleCallsChecker(String roomId) { - if (staleGroupCallsTimer.tryGet(roomId) != null) { - staleGroupCallsTimer[roomId]!.cancel(); - staleGroupCallsTimer.remove(roomId); - Logs().d('[VOIP] stopped stale group calls checker for room $id'); - } else { - Logs().d('[VOIP] no stale call checker for room found'); - } - } - static const staleCallCheckerDuration = Duration(seconds: 30); bool callMemberStateIsExpired( @@ -89,23 +78,16 @@ extension GroupCallUtils on Room { } /// checks for stale calls in a room and sends `m.terminated` if all the - /// expires_ts are expired. Call when opening a room - void startStaleCallsChecker(String roomId) async { - stopStaleCallsChecker(roomId); - await singleShotStaleCallCheckerOnRoom(); - staleGroupCallsTimer[roomId] = Timer.periodic( - staleCallCheckerDuration, - (timer) async => await singleShotStaleCallCheckerOnRoom(), - ); - } - + /// expires_ts are expired. Called regularly on sync. Future singleShotStaleCallCheckerOnRoom() async { - Logs().d('[VOIP] checking for stale group calls in room $id'); - // make sure we have all the to-device messages we are supposed to have - await client.oneShotSync(); + if (partial) return; + final copyGroupCallIds = states.tryGetMap(EventTypes.GroupCallPrefix); if (copyGroupCallIds == null) return; + + Logs().d('[VOIP] checking for stale group calls in room $id'); + for (final groupCall in copyGroupCallIds.entries) { final groupCallId = groupCall.key; final groupCallEvent = groupCall.value; @@ -165,3 +147,16 @@ extension GroupCallUtils on Room { } } } + +extension GroupCallClientUtils on Client { + // call after sync + Future singleShotStaleCallChecker() async { + if (lastStaleCallRun + .add(GroupCallUtils.staleCallCheckerDuration) + .isBefore(DateTime.now())) { + await Future.wait(rooms + .where((r) => r.membership == Membership.join) + .map((r) => r.singleShotStaleCallCheckerOnRoom())); + } + } +}