Adopt room info power levels (#4245)

* Use the newly RoomInfo published PowerLevels; update permissions at the same time as the room info and avoid unnecessary async calls.

* Introduce a RoomInfoProxyProtocol and associated mock and move away from mocked SDK RoomInfos

* Bump the SDK to v25.06.23

* Expose new non-throwing methods for checking one's own user permissions

* Fix the unit and preview tests (except the TimelineMediaPreviewDetails for which simplified snapshots were generated)

* Converge on one single implementation for computing a room's avatar.

* Fix more unit tests

* Fix the TimelineMediaPreviewDetailsView snapshot tests

This reverts commit 9b6c819e611ad2fa3de2c34a4a7aa556fc9faadd.

---------

Co-authored-by: Doug <douglase@element.io>
This commit is contained in:
Stefan Ceriu
2025-06-24 19:48:00 +03:00
committed by GitHub
parent 0f9d700c99
commit 5ac6ec28d5
31 changed files with 1274 additions and 362 deletions
@@ -62,7 +62,6 @@ extension JoinedRoomProxyMock {
ownUserID = configuration.ownUserID
infoPublisher = CurrentValueSubject(.init(roomInfo: .init(configuration))).asCurrentValuePublisher()
membersPublisher = CurrentValueSubject(configuration.members).asCurrentValuePublisher()
knockRequestsStatePublisher = CurrentValueSubject(configuration.knockRequestsState).asCurrentValuePublisher()
typingMembersPublisher = CurrentValueSubject([]).asCurrentValuePublisher()
@@ -134,53 +133,52 @@ extension JoinedRoomProxyMock {
isVisibleInRoomDirectoryReturnValue = .success(configuration.isVisibleInPublicDirectory)
predecessorRoom = configuration.predecessor
let roomInfoProxyMock = RoomInfoProxyMock(configuration)
roomInfoProxyMock.powerLevels = powerLevelsProxyMock
infoPublisher = CurrentValueSubject(roomInfoProxyMock).asCurrentValuePublisher()
}
}
extension RoomInfo {
@MainActor init(_ configuration: JoinedRoomProxyMockConfiguration) {
self.init(id: configuration.id,
encryptionState: configuration.isEncrypted ? .encrypted : .notEncrypted,
creator: nil,
displayName: configuration.name,
rawName: configuration.name,
topic: configuration.topic,
avatarUrl: configuration.avatarURL?.absoluteString,
isDirect: configuration.isDirect,
isPublic: configuration.isPublic,
isSpace: configuration.isSpace,
successorRoom: configuration.successor,
isFavourite: false,
canonicalAlias: configuration.canonicalAlias,
alternativeAliases: configuration.alternativeAliases,
membership: configuration.membership,
inviter: configuration.inviter.map { RoomMember(userId: $0.userID,
displayName: $0.displayName,
avatarUrl: $0.avatarURL?.absoluteString,
membership: $0.membership,
isNameAmbiguous: false,
powerLevel: Int64($0.powerLevel),
normalizedPowerLevel: Int64($0.powerLevel),
isIgnored: $0.isIgnored,
suggestedRoleForPowerLevel: $0.role,
membershipChangeReason: $0.membershipChangeReason) },
heroes: configuration.heroes.map(RoomHero.init),
activeMembersCount: UInt64(configuration.members.filter { $0.membership == .join || $0.membership == .invite }.count),
invitedMembersCount: UInt64(configuration.members.filter { $0.membership == .invite }.count),
joinedMembersCount: UInt64(configuration.members.filter { $0.membership == .join }.count),
userPowerLevels: [:],
highlightCount: 0,
notificationCount: 0,
cachedUserDefinedNotificationMode: .allMessages,
hasRoomCall: configuration.hasOngoingCall,
activeRoomCallParticipants: [],
isMarkedUnread: false,
numUnreadMessages: 0,
numUnreadNotifications: 0,
numUnreadMentions: 0,
pinnedEventIds: Array(configuration.pinnedEventIDs),
joinRule: configuration.joinRule,
historyVisibility: .shared)
extension RoomInfoProxyMock {
@MainActor convenience init(_ configuration: JoinedRoomProxyMockConfiguration) {
self.init()
id = configuration.id
isEncrypted = configuration.isEncrypted
creator = nil
displayName = configuration.name
rawName = configuration.name
topic = configuration.topic
avatarURL = configuration.avatarURL
isDirect = configuration.isDirect
isPublic = configuration.isPublic
isSpace = configuration.isSpace
successor = configuration.successor
isFavourite = false
canonicalAlias = configuration.canonicalAlias
alternativeAliases = configuration.alternativeAliases
membership = configuration.membership
inviter = configuration.inviter
heroes = configuration.heroes.map(RoomHero.init)
activeMembersCount = configuration.members.filter { $0.membership == .join || $0.membership == .invite }.count
invitedMembersCount = configuration.members.filter { $0.membership == .invite }.count
joinedMembersCount = configuration.members.filter { $0.membership == .join }.count
highlightCount = 0
notificationCount = 0
cachedUserDefinedNotificationMode = .allMessages
hasRoomCall = configuration.hasOngoingCall
activeRoomCallParticipants = []
isMarkedUnread = false
unreadMessagesCount = 0
unreadNotificationsCount = 0
unreadMentionsCount = 0
pinnedEventIDs = configuration.pinnedEventIDs
joinRule = configuration.joinRule
historyVisibility = .shared
powerLevels = RoomPowerLevelsProxyMock(configuration: configuration.powerLevelsConfiguration)
}
}