From 0aa5ef9eeaaaa7520a4ddc710f89d23fce282da6 Mon Sep 17 00:00:00 2001 From: Jayesh Nirve Date: Wed, 20 Jul 2022 18:44:03 +0530 Subject: [PATCH 1/2] feat: allow enabling group calls in already created rooms --- lib/src/room.dart | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/src/room.dart b/lib/src/room.dart index 6a6bfac0..b28bec51 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1645,6 +1645,35 @@ class Room { /// The level required to ban a user. bool get canBan => _hasPermissionFor('ban'); + /// if returned value is not null `org.matrix.msc3401.call.member` is present + /// and group calls can be used + bool get groupCallsEnabled { + final powerLevelMap = getState(EventTypes.RoomPowerLevels)?.content; + final groupCallPowerLevel = + powerLevelMap?.tryGetMap('events')?['org.matrix.msc3401.call.member']; + return groupCallPowerLevel != null && + groupCallPowerLevel >= powerLevelMap?['users_default']; + } + + /// sets the `org.matrix.msc3401.call.member` power level to users default for + /// group calls, needs permissions to change power levels + Future enableGroupCalls() async { + if (!canChangePowerLevel) return; + final currentPowerLevelsMap = getState(EventTypes.RoomPowerLevels)?.content; + if (currentPowerLevelsMap != null) { + final newPowerLevelMap = currentPowerLevelsMap; + newPowerLevelMap['events'].addAll({ + 'org.matrix.msc3401.call.member': currentPowerLevelsMap['users_default'] + }); + await client.setRoomStateWithKey( + id, + EventTypes.RoomPowerLevels, + '', + newPowerLevelMap, + ); + } + } + /// The default level required to send message events. Can be overridden by the events key. bool get canSendDefaultMessages => _hasPermissionFor('events_default') && From 29c1241359711c69de2ad4370a18d93c490edc75 Mon Sep 17 00:00:00 2001 From: Jayesh Nirve Date: Thu, 21 Jul 2022 23:16:59 +0530 Subject: [PATCH 2/2] chore: add tests for group calls --- lib/src/room.dart | 22 ++++++----- test/room_test.dart | 95 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 9 deletions(-) diff --git a/lib/src/room.dart b/lib/src/room.dart index b28bec51..c8c80437 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1593,16 +1593,14 @@ class Room { /// Returns the power level of the given user ID. int getPowerLevelByUserId(String userId) { var powerLevel = 0; - final powerLevelState = getState(EventTypes.RoomPowerLevels); - if (powerLevelState == null) return powerLevel; - if (powerLevelState.content['users_default'] is int) { - powerLevel = powerLevelState.content['users_default']; - } - if (powerLevelState.content + final powerLevelMap = getState(EventTypes.RoomPowerLevels)?.content; + if (powerLevelMap == null) return powerLevel; + powerLevel = getDefaultPowerLevel(powerLevelMap); + if (powerLevelMap .tryGet>('users') ?.tryGet(userId) != null) { - powerLevel = powerLevelState.content['users'][userId]; + powerLevel = powerLevelMap['users'][userId]; } return powerLevel; } @@ -1652,7 +1650,7 @@ class Room { final groupCallPowerLevel = powerLevelMap?.tryGetMap('events')?['org.matrix.msc3401.call.member']; return groupCallPowerLevel != null && - groupCallPowerLevel >= powerLevelMap?['users_default']; + groupCallPowerLevel <= getDefaultPowerLevel(powerLevelMap!); } /// sets the `org.matrix.msc3401.call.member` power level to users default for @@ -1663,7 +1661,8 @@ class Room { if (currentPowerLevelsMap != null) { final newPowerLevelMap = currentPowerLevelsMap; newPowerLevelMap['events'].addAll({ - 'org.matrix.msc3401.call.member': currentPowerLevelsMap['users_default'] + 'org.matrix.msc3401.call.member': + getDefaultPowerLevel(currentPowerLevelsMap) }); await client.setRoomStateWithKey( id, @@ -1674,6 +1673,11 @@ class Room { } } + /// Takes in `[m.room.power_levels].content` and returns the default power level + int getDefaultPowerLevel(Map powerLevelMap) { + return powerLevelMap.tryGet('users_default') ?? 0; + } + /// The default level required to send message events. Can be overridden by the events key. bool get canSendDefaultMessages => _hasPermissionFor('events_default') && diff --git a/test/room_test.dart b/test/room_test.dart index b723a0e9..a757b4a9 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -460,6 +460,101 @@ void main() { expect(resp, '42'); }); + test('Enabling group calls', () async { + expect(room.groupCallsEnabled, false); + room.setState( + Event( + senderId: '@test:example.com', + type: 'm.room.power_levels', + room: room, + eventId: '123a', + content: { + 'events': {'org.matrix.msc3401.call.member': 100}, + 'state_default': 50, + 'users': {'@test:fakeServer.notExisting': 100}, + 'users_default': 0 + }, + originServerTs: DateTime.now(), + stateKey: '', + ), + ); + expect(room.groupCallsEnabled, false); + room.setState( + Event( + senderId: '@test:example.com', + type: 'm.room.power_levels', + room: room, + eventId: '123a', + content: { + 'events': {'org.matrix.msc3401.call.member': 27}, + 'state_default': 50, + 'users': {'@test:fakeServer.notExisting': 100}, + 'users_default': 100 + }, + originServerTs: DateTime.now(), + stateKey: '', + ), + ); + expect(room.groupCallsEnabled, true); + room.setState( + Event( + senderId: '@test:example.com', + type: 'm.room.power_levels', + room: room, + eventId: '123', + content: { + 'events': {}, + 'state_default': 50, + 'users': {'@test:fakeServer.notExisting': 100}, + 'users_default': 0 + }, + originServerTs: DateTime.now(), + stateKey: ''), + ); + expect(room.groupCallsEnabled, false); + await room.enableGroupCalls(); + expect(room.groupCallsEnabled, true); + room.setState( + Event( + senderId: '@test:example.com', + type: 'm.room.power_levels', + room: room, + eventId: '123', + content: { + 'events': {}, + 'state_default': 50, + 'users': {'@test:fakeServer.notExisting': 100}, + }, + originServerTs: DateTime.now(), + stateKey: '', + ), + ); + await room.enableGroupCalls(); + expect(room.groupCallsEnabled, true); + room.setState( + Event( + senderId: '@test:example.com', + type: 'm.room.power_levels', + room: room, + eventId: '123abc', + content: { + 'ban': 50, + 'events': {'m.room.name': 0, 'm.room.power_levels': 100}, + 'events_default': 0, + 'invite': 50, + 'kick': 50, + 'notifications': {'room': 20}, + 'redact': 50, + 'state_default': 50, + 'users': {}, + 'users_default': 0 + }, + originServerTs: DateTime.now(), + stateKey: '', + ), + ); + }); + test('invite', () async { await room.invite('Testname'); });