diff --git a/lib/src/room.dart b/lib/src/room.dart index 47df513a..207c6be5 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -1610,16 +1610,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; } @@ -1662,6 +1660,41 @@ 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 <= getDefaultPowerLevel(powerLevelMap!); + } + + /// 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': + getDefaultPowerLevel(currentPowerLevelsMap) + }); + await client.setRoomStateWithKey( + id, + EventTypes.RoomPowerLevels, + '', + newPowerLevelMap, + ); + } + } + + /// 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 f6bb0481..a466ad22 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -459,6 +459,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'); });