mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Add some new space properties. (#4544)
* Use the via property on SpaceRoom. * Fall back to the canonical alias as a space room name if needs be. * Use SpaceRoom.isDirect for computing the name/avatar. * Pass in the parent space as a workaround for no restricted join rules.
This commit is contained in:
@@ -21,11 +21,12 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
private let paginationStateHandle: TaskHandle
|
||||
let paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never>
|
||||
|
||||
init(_ spaceRoomList: SpaceRoomListProtocol) throws {
|
||||
// Parent is temporary until we get the restricted AllowRules from the server.
|
||||
init(_ spaceRoomList: SpaceRoomListProtocol, parent: SpaceRoomProxyProtocol?) throws {
|
||||
guard let spaceRoom = spaceRoomList.space() else { throw SpaceRoomListProxyError.missingSpace }
|
||||
|
||||
self.spaceRoomList = spaceRoomList
|
||||
spaceRoomProxy = SpaceRoomProxy(spaceRoom: spaceRoom)
|
||||
spaceRoomProxy = SpaceRoomProxy(spaceRoom: spaceRoom, parent: parent)
|
||||
|
||||
let paginationStateSubject = CurrentValueSubject<SpaceRoomListPaginationState, Never>(spaceRoomList.paginationState())
|
||||
paginationStatePublisher = paginationStateSubject.asCurrentValuePublisher()
|
||||
@@ -55,27 +56,27 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
for update in updates {
|
||||
switch update {
|
||||
case .append(let spaceRooms):
|
||||
rooms.append(contentsOf: spaceRooms.map(SpaceRoomProxy.init))
|
||||
rooms.append(contentsOf: spaceRooms.map { SpaceRoomProxy(spaceRoom: $0, parent: spaceRoomProxy) })
|
||||
case .clear:
|
||||
rooms.removeAll()
|
||||
case .pushFront(let spaceRoom):
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0)
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom, parent: spaceRoomProxy), at: 0)
|
||||
case .pushBack(let spaceRoom):
|
||||
rooms.append(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
rooms.append(SpaceRoomProxy(spaceRoom: spaceRoom, parent: spaceRoomProxy))
|
||||
case .popFront:
|
||||
rooms.removeFirst()
|
||||
case .popBack:
|
||||
rooms.removeLast()
|
||||
case .insert(let index, let spaceRoom):
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index))
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom, parent: spaceRoomProxy), at: Int(index))
|
||||
case .set(let index, let spaceRoom):
|
||||
rooms[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom)
|
||||
rooms[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom, parent: spaceRoomProxy)
|
||||
case .remove(let index):
|
||||
rooms.remove(at: Int(index))
|
||||
case .truncate(let length):
|
||||
rooms.removeSubrange(Int(length)..<rooms.count)
|
||||
case .reset(let spaceRooms):
|
||||
rooms = spaceRooms.map(SpaceRoomProxy.init)
|
||||
rooms = spaceRooms.map { SpaceRoomProxy(spaceRoom: $0, parent: spaceRoomProxy) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,15 @@ import MatrixRustSDK
|
||||
|
||||
class SpaceRoomProxy: SpaceRoomProxyProtocol {
|
||||
private let spaceRoom: SpaceRoom
|
||||
let parent: SpaceRoomProxyProtocol?
|
||||
|
||||
init(spaceRoom: SpaceRoom) {
|
||||
/// Proxies a `SpaceRoom` from the Rust SDK.
|
||||
/// - Parameters:
|
||||
/// - spaceRoom: The `SpaceRoom` to proxy.
|
||||
/// - parent: A temporary parameter until we get the `AllowRule`s from the server.
|
||||
init(spaceRoom: SpaceRoom, parent: SpaceRoomProxyProtocol?) {
|
||||
self.spaceRoom = spaceRoom
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
lazy var id = spaceRoom.roomId
|
||||
@@ -20,6 +26,7 @@ class SpaceRoomProxy: SpaceRoomProxyProtocol {
|
||||
var avatarURL: URL? { spaceRoom.avatarUrl.flatMap(URL.init) }
|
||||
|
||||
var isSpace: Bool { spaceRoom.roomType == .space }
|
||||
var isDirect: Bool? { spaceRoom.isDirect }
|
||||
var childrenCount: Int { Int(spaceRoom.childrenCount) }
|
||||
|
||||
var joinedMembersCount: Int { Int(spaceRoom.numJoinedMembers) }
|
||||
@@ -31,4 +38,5 @@ class SpaceRoomProxy: SpaceRoomProxyProtocol {
|
||||
var worldReadable: Bool? { spaceRoom.worldReadable }
|
||||
var guestCanJoin: Bool { spaceRoom.guestCanJoin }
|
||||
var state: Membership? { spaceRoom.state }
|
||||
var via: [String] { spaceRoom.via }
|
||||
}
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum SpaceRoomProxyVisibility: Equatable {
|
||||
case `public`
|
||||
case `private`
|
||||
case restricted(parentName: String)
|
||||
// We can add the external case in here eventually.
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol SpaceRoomProxyProtocol {
|
||||
var id: String { get }
|
||||
@@ -15,6 +22,9 @@ protocol SpaceRoomProxyProtocol {
|
||||
var avatarURL: URL? { get }
|
||||
|
||||
var isSpace: Bool { get }
|
||||
var isDirect: Bool? { get }
|
||||
/// A temporary property until we get the `AllowRule`s from the server.
|
||||
var parent: SpaceRoomProxyProtocol? { get }
|
||||
var childrenCount: Int { get }
|
||||
|
||||
var joinedMembersCount: Int { get }
|
||||
@@ -26,14 +36,43 @@ protocol SpaceRoomProxyProtocol {
|
||||
var worldReadable: Bool? { get }
|
||||
var guestCanJoin: Bool { get }
|
||||
var state: Membership? { get }
|
||||
var via: [String] { get }
|
||||
}
|
||||
|
||||
extension SpaceRoomProxyProtocol {
|
||||
var avatar: RoomAvatar {
|
||||
if isSpace {
|
||||
.space(id: id, name: name, avatarURL: avatarURL)
|
||||
} else { // We don't need to check for heroes, we only do that for DMs.
|
||||
} else if isDirect == true, avatarURL == nil, heroes.count == 1 {
|
||||
.heroes(heroes)
|
||||
} else {
|
||||
.room(id: id, name: name, avatarURL: avatarURL)
|
||||
}
|
||||
}
|
||||
|
||||
var computedName: String {
|
||||
if !isSpace, isDirect == true, name == nil, heroes.count == 1, let dmRecipient = heroes.first {
|
||||
dmRecipient.displayName ?? dmRecipient.id
|
||||
} else {
|
||||
name ?? canonicalAlias ?? id
|
||||
}
|
||||
}
|
||||
|
||||
var visibility: SpaceRoomProxyVisibility? {
|
||||
switch joinRule {
|
||||
case .public:
|
||||
.public
|
||||
case .restricted, .knockRestricted:
|
||||
// Temporary solution until the server includes the `AllowRule` values (they're always empty right now).
|
||||
if let parent {
|
||||
.restricted(parentName: parent.computedName)
|
||||
} else {
|
||||
.private
|
||||
}
|
||||
case .invite, .knock, .private, .custom:
|
||||
.private
|
||||
case .none:
|
||||
.none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,10 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
})
|
||||
}
|
||||
|
||||
func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError> {
|
||||
// The parent here is temporary until we get the restricted AllowRules from the server.
|
||||
func spaceRoomList(spaceID: String, parent: SpaceRoomProxyProtocol?) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(SpaceRoomListProxy(spaceService.spaceRoomList(spaceId: spaceID)))
|
||||
return try await .success(SpaceRoomListProxy(spaceService.spaceRoomList(spaceId: spaceID), parent: parent))
|
||||
} catch {
|
||||
MXLog.error("Failed creating space room list for \(spaceID): \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
@@ -47,27 +48,27 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
for update in updates {
|
||||
switch update {
|
||||
case .append(let spaceRooms):
|
||||
spaces.append(contentsOf: spaceRooms.map(SpaceRoomProxy.init))
|
||||
spaces.append(contentsOf: spaceRooms.map { SpaceRoomProxy(spaceRoom: $0, parent: nil) })
|
||||
case .clear:
|
||||
spaces.removeAll()
|
||||
case .pushFront(let spaceRoom):
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0)
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil), at: 0)
|
||||
case .pushBack(let spaceRoom):
|
||||
spaces.append(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
spaces.append(SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil))
|
||||
case .popFront:
|
||||
spaces.removeFirst()
|
||||
case .popBack:
|
||||
spaces.removeLast()
|
||||
case .insert(let index, let spaceRoom):
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index))
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil), at: Int(index))
|
||||
case .set(let index, let spaceRoom):
|
||||
spaces[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom)
|
||||
spaces[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil)
|
||||
case .remove(let index):
|
||||
spaces.remove(at: Int(index))
|
||||
case .truncate(let length):
|
||||
spaces.removeSubrange(Int(length)..<spaces.count)
|
||||
case .reset(let spaceRooms):
|
||||
spaces = spaceRooms.map(SpaceRoomProxy.init)
|
||||
spaces = spaceRooms.map { SpaceRoomProxy(spaceRoom: $0, parent: nil) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,5 +16,5 @@ enum SpaceServiceProxyError: Error {
|
||||
protocol SpaceServiceProxyProtocol {
|
||||
var joinedSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get }
|
||||
|
||||
func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
func spaceRoomList(spaceID: String, parent: SpaceRoomProxyProtocol?) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user