mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Refactor the JoinRoom screen to take advantage of newer APIs and support more joinRule/membership combinations (i.e. invite required, restricted, banned) (#3685)
- expose the full RoomPreview and RoomMembershipDetails through their own proxies - implement standard mocks for all the different combinations - converge on a single room info provider - rebuild all the previews - prioritise the preview data over the room one.
This commit is contained in:
@@ -516,11 +516,10 @@ class ClientProxy: ClientProxyProtocol {
|
||||
return await buildRoomForIdentifier(identifier)
|
||||
}
|
||||
|
||||
func roomPreviewForIdentifier(_ identifier: String, via: [String]) async -> Result<RoomPreviewDetails, ClientProxyError> {
|
||||
func roomPreviewForIdentifier(_ identifier: String, via: [String]) async -> Result<RoomPreviewProxyProtocol, ClientProxyError> {
|
||||
do {
|
||||
let roomPreview = try await client.getRoomPreviewFromRoomId(roomId: identifier, viaServers: via)
|
||||
let roomPreviewInfo = try roomPreview.info()
|
||||
return .success(.init(roomPreviewInfo))
|
||||
return try .success(RoomPreviewProxy(roomPreview: roomPreview))
|
||||
} catch let error as ClientError where error.code == .forbidden {
|
||||
return .failure(.roomPreviewIsPrivate)
|
||||
} catch {
|
||||
@@ -1155,40 +1154,3 @@ private class SendQueueRoomErrorListenerProxy: SendQueueRoomErrorListener {
|
||||
onErrorClosure(roomId, error)
|
||||
}
|
||||
}
|
||||
|
||||
private extension RoomPreviewDetails {
|
||||
init(_ roomPreviewInfo: RoomPreviewInfo) {
|
||||
self = RoomPreviewDetails(roomID: roomPreviewInfo.roomId,
|
||||
name: roomPreviewInfo.name,
|
||||
canonicalAlias: roomPreviewInfo.canonicalAlias,
|
||||
topic: roomPreviewInfo.topic,
|
||||
avatarURL: roomPreviewInfo.avatarUrl.flatMap(URL.init(string:)),
|
||||
memberCount: UInt(roomPreviewInfo.numJoinedMembers),
|
||||
isHistoryWorldReadable: roomPreviewInfo.isHistoryWorldReadable ?? false,
|
||||
isJoined: roomPreviewInfo.membership == .joined,
|
||||
isInvited: roomPreviewInfo.membership == .invited,
|
||||
isPublic: roomPreviewInfo.isPublic,
|
||||
canKnock: roomPreviewInfo.canKnock)
|
||||
}
|
||||
}
|
||||
|
||||
private extension RoomPreviewInfo {
|
||||
var canKnock: Bool {
|
||||
switch joinRule {
|
||||
case .knock, .knockRestricted:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var isPublic: Bool {
|
||||
switch joinRule {
|
||||
// for restricted rooms we want to show optimistically that the we may be able to join the room
|
||||
case .public, .restricted:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,20 +61,6 @@ enum SessionVerificationState {
|
||||
case unverified
|
||||
}
|
||||
|
||||
struct RoomPreviewDetails {
|
||||
let roomID: String
|
||||
let name: String?
|
||||
let canonicalAlias: String?
|
||||
let topic: String?
|
||||
let avatarURL: URL?
|
||||
let memberCount: UInt
|
||||
let isHistoryWorldReadable: Bool?
|
||||
let isJoined: Bool
|
||||
let isInvited: Bool
|
||||
let isPublic: Bool
|
||||
let canKnock: Bool
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
var actionsPublisher: AnyPublisher<ClientProxyAction, Never> { get }
|
||||
@@ -154,7 +140,7 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
|
||||
func roomForIdentifier(_ identifier: String) async -> RoomProxyType?
|
||||
|
||||
func roomPreviewForIdentifier(_ identifier: String, via: [String]) async -> Result<RoomPreviewDetails, ClientProxyError>
|
||||
func roomPreviewForIdentifier(_ identifier: String, via: [String]) async -> Result<RoomPreviewProxyProtocol, ClientProxyError>
|
||||
|
||||
@discardableResult func loadUserDisplayName() async -> Result<Void, ClientProxyError>
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
import UIKit
|
||||
|
||||
class KnockedRoomProxy: KnockedRoomProxyProtocol {
|
||||
private let roomListItem: RoomListItemProtocol
|
||||
|
||||
@@ -113,6 +113,9 @@ struct RoomPreviewInfoProxy: BaseRoomInfoProxyProtocol {
|
||||
var isSpace: Bool { roomPreviewInfo.roomType == .space }
|
||||
var activeMembersCount: Int { Int(roomPreviewInfo.numActiveMembers ?? roomPreviewInfo.numJoinedMembers) }
|
||||
|
||||
var joinRule: JoinRule { roomPreviewInfo.joinRule }
|
||||
var membership: Membership? { roomPreviewInfo.membership }
|
||||
|
||||
/// The room's avatar info for use in a ``RoomAvatarImage``.
|
||||
var avatar: RoomAvatar {
|
||||
if isDirect, avatarURL == nil {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// Copyright 2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct RoomMembershipDetailsProxy: RoomMembershipDetailsProxyProtocol {
|
||||
let ownRoomMember: RoomMemberProxyProtocol
|
||||
let senderRoomMember: RoomMemberProxyProtocol?
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright 2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol RoomMembershipDetailsProxyProtocol {
|
||||
var ownRoomMember: RoomMemberProxyProtocol { get }
|
||||
var senderRoomMember: RoomMemberProxyProtocol? { get }
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright 2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import MatrixRustSDK
|
||||
|
||||
final class RoomPreviewProxy: RoomPreviewProxyProtocol {
|
||||
private let roomPreview: RoomPreview
|
||||
|
||||
let info: RoomPreviewInfoProxy
|
||||
|
||||
init(roomPreview: RoomPreview) throws {
|
||||
self.roomPreview = roomPreview
|
||||
info = try .init(roomPreviewInfo: roomPreview.info())
|
||||
}
|
||||
|
||||
var ownMembershipDetails: RoomMembershipDetailsProxyProtocol? {
|
||||
get async {
|
||||
guard let details = await roomPreview.ownMembershipDetails() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
var senderRoomMember: RoomMemberProxy?
|
||||
if let member = details.senderRoomMember {
|
||||
senderRoomMember = .init(member: member)
|
||||
}
|
||||
|
||||
return RoomMembershipDetailsProxy(ownRoomMember: RoomMemberProxy(member: details.ownRoomMember),
|
||||
senderRoomMember: senderRoomMember)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// Copyright 2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol RoomPreviewProxyProtocol {
|
||||
var info: RoomPreviewInfoProxy { get }
|
||||
var ownMembershipDetails: RoomMembershipDetailsProxyProtocol? { get async }
|
||||
}
|
||||
Reference in New Issue
Block a user