Added the banned room proxy (#3744)

* added the banned room proxy

and a way to have a consistent loading + a retry alert

* trailing closure

* indent a comment

* push package.resolved

* updated test case
This commit is contained in:
Mauro 2025-02-06 10:15:36 +01:00 committed by GitHub
parent 3839025caa
commit f86a5a2bb9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 228 additions and 89 deletions

View File

@ -852,6 +852,8 @@
A6F345328CCC5C9B0DAE2257 /* LogViewerScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BB05221D7D941CC82DC8480 /* LogViewerScreenViewModel.swift */; }; A6F345328CCC5C9B0DAE2257 /* LogViewerScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BB05221D7D941CC82DC8480 /* LogViewerScreenViewModel.swift */; };
A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; }; A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; };
A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; }; A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; };
A74F91692D53BD95008D86A9 /* BannedRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74F91682D53BD8C008D86A9 /* BannedRoomProxy.swift */; };
A74F916B2D53BE1E008D86A9 /* BannedRoomProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A74F916A2D53BE18008D86A9 /* BannedRoomProxyMock.swift */; };
A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; };
A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; }; A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; };
A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; }; A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; };
@ -2120,6 +2122,8 @@
A6C11AD9813045E44F950410 /* ElementCallWidgetDriverProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallWidgetDriverProtocol.swift; sourceTree = "<group>"; }; A6C11AD9813045E44F950410 /* ElementCallWidgetDriverProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallWidgetDriverProtocol.swift; sourceTree = "<group>"; };
A6EA0D8B0BBD8805F7D5A133 /* TextBasedRoomTimelineViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewProtocol.swift; sourceTree = "<group>"; }; A6EA0D8B0BBD8805F7D5A133 /* TextBasedRoomTimelineViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewProtocol.swift; sourceTree = "<group>"; };
A73A07BAEDD74C48795A996A /* AsyncSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncSequence.swift; sourceTree = "<group>"; }; A73A07BAEDD74C48795A996A /* AsyncSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncSequence.swift; sourceTree = "<group>"; };
A74F91682D53BD8C008D86A9 /* BannedRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannedRoomProxy.swift; sourceTree = "<group>"; };
A74F916A2D53BE18008D86A9 /* BannedRoomProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannedRoomProxyMock.swift; sourceTree = "<group>"; };
A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationTokenTests.swift; sourceTree = "<group>"; }; A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationTokenTests.swift; sourceTree = "<group>"; };
A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; }; A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = "<group>"; };
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; }; A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
@ -3182,6 +3186,7 @@
31CE4DA53232AA534057F912 /* Mocks */ = { 31CE4DA53232AA534057F912 /* Mocks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A74F916A2D53BE18008D86A9 /* BannedRoomProxyMock.swift */,
69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */, 69CB8242D69B7E4D0B32E18D /* AggregatedReactionMock.swift */,
3BAC027034248429A438886B /* AppMediatorMock.swift */, 3BAC027034248429A438886B /* AppMediatorMock.swift */,
0554FEA301486A8CFA475D5A /* AuthenticationClientBuilderFactoryMock.swift */, 0554FEA301486A8CFA475D5A /* AuthenticationClientBuilderFactoryMock.swift */,
@ -3491,6 +3496,7 @@
40E6246F03D1FE377BC5D963 /* Room */ = { 40E6246F03D1FE377BC5D963 /* Room */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A74F91682D53BD8C008D86A9 /* BannedRoomProxy.swift */,
0E95B3BDB80531C85CD50AE6 /* InvitedRoomProxy.swift */, 0E95B3BDB80531C85CD50AE6 /* InvitedRoomProxy.swift */,
07C6B0B087FE6601C3F77816 /* JoinedRoomProxy.swift */, 07C6B0B087FE6601C3F77816 /* JoinedRoomProxy.swift */,
858DA81F2ACF484B7CAD6AE4 /* KnockedRoomProxy.swift */, 858DA81F2ACF484B7CAD6AE4 /* KnockedRoomProxy.swift */,
@ -7068,6 +7074,7 @@
77574A519A4E484880053EAD /* IdentityConfirmationScreenModels.swift in Sources */, 77574A519A4E484880053EAD /* IdentityConfirmationScreenModels.swift in Sources */,
0C346A4AD174F441EDB1414E /* IdentityConfirmationScreenViewModel.swift in Sources */, 0C346A4AD174F441EDB1414E /* IdentityConfirmationScreenViewModel.swift in Sources */,
489BB6A733D3DA0FE7062650 /* IdentityConfirmationScreenViewModelProtocol.swift in Sources */, 489BB6A733D3DA0FE7062650 /* IdentityConfirmationScreenViewModelProtocol.swift in Sources */,
A74F91692D53BD95008D86A9 /* BannedRoomProxy.swift in Sources */,
9C4EC28A921486B1775D7F8C /* IdentityConfirmedScreen.swift in Sources */, 9C4EC28A921486B1775D7F8C /* IdentityConfirmedScreen.swift in Sources */,
93AC1E8418D8C827671FB3A9 /* IdentityConfirmedScreenCoordinator.swift in Sources */, 93AC1E8418D8C827671FB3A9 /* IdentityConfirmedScreenCoordinator.swift in Sources */,
D22345698F6548C1EE960940 /* IdentityConfirmedScreenModels.swift in Sources */, D22345698F6548C1EE960940 /* IdentityConfirmedScreenModels.swift in Sources */,
@ -7193,6 +7200,7 @@
C97325EFDCCEE457432A9E82 /* MessageText.swift in Sources */, C97325EFDCCEE457432A9E82 /* MessageText.swift in Sources */,
AF2ABA2794E376B64104C964 /* MockSoftLogoutScreenState.swift in Sources */, AF2ABA2794E376B64104C964 /* MockSoftLogoutScreenState.swift in Sources */,
530C2238E40F71223327FC95 /* MockTimelineController.swift in Sources */, 530C2238E40F71223327FC95 /* MockTimelineController.swift in Sources */,
A74F916B2D53BE1E008D86A9 /* BannedRoomProxyMock.swift in Sources */,
F9842667B68DC6FA1F9ECCBB /* NSItemProvider.swift in Sources */, F9842667B68DC6FA1F9ECCBB /* NSItemProvider.swift in Sources */,
EA01A06EEDFEF4AE7652E5F3 /* NSRegularExpresion.swift in Sources */, EA01A06EEDFEF4AE7652E5F3 /* NSRegularExpresion.swift in Sources */,
FA2BBAE9FC5E2E9F960C0980 /* NavigationCoordinators.swift in Sources */, FA2BBAE9FC5E2E9F960C0980 /* NavigationCoordinators.swift in Sources */,
@ -8493,7 +8501,7 @@
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
requirement = { requirement = {
kind = exactVersion; kind = exactVersion;
version = 25.02.04; version = 25.02.05;
}; };
}; };
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {

View File

@ -149,8 +149,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/element-hq/matrix-rust-components-swift", "location" : "https://github.com/element-hq/matrix-rust-components-swift",
"state" : { "state" : {
"revision" : "ebb2456c0c91fdca9747621c13af52ca330b91e9", "revision" : "392ea9529ec51ac15f576618a2a9076819fc61d9",
"version" : "25.2.4" "version" : "25.2.5"
} }
}, },
{ {

View File

@ -0,0 +1,64 @@
//
// Copyright 2025 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 Combine
import Foundation
import MatrixRustSDK
@MainActor
struct BannedRoomProxyMockConfiguration {
var id = UUID().uuidString
var name: String?
var avatarURL: URL?
var members: [RoomMemberProxyMock] = .allMembers
}
extension BannedRoomProxyMock {
@MainActor
convenience init(_ configuration: KnockedRoomProxyMockConfiguration) {
self.init()
id = configuration.id
info = RoomInfoProxy(roomInfo: .init(configuration))
}
}
extension RoomInfo {
@MainActor init(_ configuration: BannedRoomProxyMockConfiguration) {
self.init(id: configuration.id,
creator: nil,
displayName: configuration.name,
rawName: nil,
topic: nil,
avatarUrl: configuration.avatarURL?.absoluteString,
isDirect: false,
isPublic: false,
isSpace: false,
isTombstoned: false,
isFavourite: false,
canonicalAlias: nil,
alternativeAliases: [],
membership: .knocked,
inviter: nil,
heroes: [],
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: nil,
hasRoomCall: false,
activeRoomCallParticipants: [],
isMarkedUnread: false,
numUnreadMessages: 0,
numUnreadNotifications: 0,
numUnreadMentions: 0,
pinnedEventIds: [],
joinRule: .knock,
historyVisibility: .shared)
}
}

View File

@ -2047,6 +2047,88 @@ class AuthenticationClientBuilderMock: AuthenticationClientBuilderProtocol, @unc
} }
} }
} }
class BannedRoomProxyMock: BannedRoomProxyProtocol, @unchecked Sendable {
var info: BaseRoomInfoProxyProtocol {
get { return underlyingInfo }
set(value) { underlyingInfo = value }
}
var underlyingInfo: BaseRoomInfoProxyProtocol!
var id: String {
get { return underlyingId }
set(value) { underlyingId = value }
}
var underlyingId: String!
var ownUserID: String {
get { return underlyingOwnUserID }
set(value) { underlyingOwnUserID = value }
}
var underlyingOwnUserID: String!
//MARK: - forgetRoom
var forgetRoomUnderlyingCallsCount = 0
var forgetRoomCallsCount: Int {
get {
if Thread.isMainThread {
return forgetRoomUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = forgetRoomUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
forgetRoomUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
forgetRoomUnderlyingCallsCount = newValue
}
}
}
}
var forgetRoomCalled: Bool {
return forgetRoomCallsCount > 0
}
var forgetRoomUnderlyingReturnValue: Result<Void, RoomProxyError>!
var forgetRoomReturnValue: Result<Void, RoomProxyError>! {
get {
if Thread.isMainThread {
return forgetRoomUnderlyingReturnValue
} else {
var returnValue: Result<Void, RoomProxyError>? = nil
DispatchQueue.main.sync {
returnValue = forgetRoomUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
forgetRoomUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
forgetRoomUnderlyingReturnValue = newValue
}
}
}
}
var forgetRoomClosure: (() async -> Result<Void, RoomProxyError>)?
func forgetRoom() async -> Result<Void, RoomProxyError> {
forgetRoomCallsCount += 1
if let forgetRoomClosure = forgetRoomClosure {
return await forgetRoomClosure()
} else {
return forgetRoomReturnValue
}
}
}
class BugReportServiceMock: BugReportServiceProtocol, @unchecked Sendable { class BugReportServiceMock: BugReportServiceProtocol, @unchecked Sendable {
var crashedLastRun: Bool { var crashedLastRun: Bool {
get { return underlyingCrashedLastRun } get { return underlyingCrashedLastRun }
@ -13393,70 +13475,6 @@ class RoomPreviewProxyMock: RoomPreviewProxyProtocol, @unchecked Sendable {
var underlyingOwnMembershipDetails: RoomMembershipDetailsProxyProtocol? var underlyingOwnMembershipDetails: RoomMembershipDetailsProxyProtocol?
var ownMembershipDetailsClosure: (() async -> RoomMembershipDetailsProxyProtocol?)? var ownMembershipDetailsClosure: (() async -> RoomMembershipDetailsProxyProtocol?)?
//MARK: - forgetRoom
var forgetRoomUnderlyingCallsCount = 0
var forgetRoomCallsCount: Int {
get {
if Thread.isMainThread {
return forgetRoomUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = forgetRoomUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
forgetRoomUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
forgetRoomUnderlyingCallsCount = newValue
}
}
}
}
var forgetRoomCalled: Bool {
return forgetRoomCallsCount > 0
}
var forgetRoomUnderlyingReturnValue: Result<Void, RoomProxyError>!
var forgetRoomReturnValue: Result<Void, RoomProxyError>! {
get {
if Thread.isMainThread {
return forgetRoomUnderlyingReturnValue
} else {
var returnValue: Result<Void, RoomProxyError>? = nil
DispatchQueue.main.sync {
returnValue = forgetRoomUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
forgetRoomUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
forgetRoomUnderlyingReturnValue = newValue
}
}
}
}
var forgetRoomClosure: (() async -> Result<Void, RoomProxyError>)?
func forgetRoom() async -> Result<Void, RoomProxyError> {
forgetRoomCallsCount += 1
if let forgetRoomClosure = forgetRoomClosure {
return await forgetRoomClosure()
} else {
return forgetRoomReturnValue
}
}
} }
class RoomProxyMock: RoomProxyProtocol, @unchecked Sendable { class RoomProxyMock: RoomProxyProtocol, @unchecked Sendable {
var id: String { var id: String {

View File

@ -91,6 +91,7 @@ struct JoinRoomScreenViewStateBindings {
enum JoinRoomScreenAlertType { enum JoinRoomScreenAlertType {
case declineInvite case declineInvite
case cancelKnock case cancelKnock
case loadingError
} }
enum JoinRoomScreenViewAction { enum JoinRoomScreenViewAction {

View File

@ -19,6 +19,7 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
private var roomPreview: RoomPreviewProxyProtocol? private var roomPreview: RoomPreviewProxyProtocol?
private var room: RoomProxyType? private var room: RoomProxyType?
private var isLoadingPreview = true
private var membershipStateChangeCancellable: AnyCancellable? private var membershipStateChangeCancellable: AnyCancellable?
private let actionsSubject: PassthroughSubject<JoinRoomScreenViewModelAction, Never> = .init() private let actionsSubject: PassthroughSubject<JoinRoomScreenViewModelAction, Never> = .init()
@ -81,12 +82,19 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
switch await clientProxy.roomPreviewForIdentifier(roomID, via: via) { switch await clientProxy.roomPreviewForIdentifier(roomID, via: via) {
case .success(let roomPreview): case .success(let roomPreview):
isLoadingPreview = false
self.roomPreview = roomPreview self.roomPreview = roomPreview
await updateRoomDetails() await updateRoomDetails()
case .failure(.roomPreviewIsPrivate): case .failure(.roomPreviewIsPrivate):
break // Handled by the mode, we don't need an error indicator. // Handled by the mode, we don't need an error indicator.
isLoadingPreview = false
case .failure: case .failure:
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown)) hideLoadingIndicator()
state.bindings.alertInfo = .init(id: .loadingError,
title: L10n.commonError,
message: L10n.screenJoinRoomLoadingAlertMessage,
primaryButton: .init(title: L10n.actionTryAgain) { [weak self] in Task { await self?.loadRoomDetails() }},
secondaryButton: .init(title: L10n.actionCancel, role: .cancel) { [weak self] in self?.actionsSubject.send(.dismiss) })
} }
hideLoadingIndicator() hideLoadingIndicator()
@ -131,6 +139,8 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
Task { await self?.loadRoomDetails() } Task { await self?.loadRoomDetails() }
} }
} }
case .banned(let bannedRoomProxy):
roomInfo = bannedRoomProxy.info
default: default:
break break
} }
@ -155,6 +165,11 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
} }
private func updateMode() async { private func updateMode() async {
if isLoadingPreview {
state.mode = .loading
return
}
if roomPreview == nil, room == nil { if roomPreview == nil, room == nil {
state.mode = .unknown state.mode = .unknown
return return
@ -336,12 +351,12 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
userIndicatorController.submitIndicator(UserIndicator(id: roomID, type: .modal, title: L10n.commonLoading, persistent: true)) userIndicatorController.submitIndicator(UserIndicator(id: roomID, type: .modal, title: L10n.commonLoading, persistent: true))
guard case .banned = room, let roomPreview else { guard case let .banned(roomProxy) = room else {
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown)) userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
return return
} }
let result = await roomPreview.forgetRoom() let result = await roomProxy.forgetRoom()
if case .failure = result { if case .failure = result {
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown)) userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))

View File

@ -330,7 +330,7 @@ struct JoinRoomScreen_Previews: PreviewProvider, TestablePreview {
switch mode { switch mode {
case .unknown: case .unknown:
clientProxy.roomPreviewForIdentifierViaReturnValue = .failure(.sdkError(ClientProxyMockError.generic)) clientProxy.roomPreviewForIdentifierViaReturnValue = .failure(.roomPreviewIsPrivate)
clientProxy.roomForIdentifierReturnValue = nil clientProxy.roomForIdentifierReturnValue = nil
case .joinable: case .joinable:
clientProxy.roomPreviewForIdentifierViaReturnValue = .success(RoomPreviewProxyMock.joinable) clientProxy.roomPreviewForIdentifierViaReturnValue = .success(RoomPreviewProxyMock.joinable)
@ -364,7 +364,7 @@ struct JoinRoomScreen_Previews: PreviewProvider, TestablePreview {
case .banned: case .banned:
clientProxy.roomPreviewForIdentifierViaReturnValue = .success(RoomPreviewProxyMock.banned) clientProxy.roomPreviewForIdentifierViaReturnValue = .success(RoomPreviewProxyMock.banned)
clientProxy.roomForIdentifierClosure = { _ in clientProxy.roomForIdentifierClosure = { _ in
.banned .banned(BannedRoomProxyMock(.init(avatarURL: .mockMXCAvatar)))
} }
case .forbidden: case .forbidden:
clientProxy.roomPreviewForIdentifierViaReturnValue = .success(RoomPreviewProxyMock.restricted) clientProxy.roomPreviewForIdentifierViaReturnValue = .success(RoomPreviewProxyMock.restricted)

View File

@ -943,7 +943,9 @@ class ClientProxy: ClientProxyProtocol {
case .left: case .left:
return .left return .left
case .banned: case .banned:
return .banned return try await .banned(BannedRoomProxy(roomListItem: roomListItem,
roomPreview: roomListItem.previewRoom(via: []),
ownUserID: userID))
} }
} catch { } catch {
MXLog.error("Failed retrieving room: \(roomID), with error: \(error)") MXLog.error("Failed retrieving room: \(roomID), with error: \(error)")

View File

@ -0,0 +1,38 @@
//
// Copyright 2025 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
import MatrixRustSDK
class BannedRoomProxy: BannedRoomProxyProtocol {
private let roomListItem: RoomListItemProtocol
private let roomPreview: RoomPreviewProtocol
let info: BaseRoomInfoProxyProtocol
let ownUserID: String
// A room identifier is constant and lazy stops it from being fetched
// multiple times over FFI
lazy var id = info.id
init(roomListItem: RoomListItemProtocol,
roomPreview: RoomPreviewProtocol,
ownUserID: String) throws {
self.roomListItem = roomListItem
self.roomPreview = roomPreview
self.ownUserID = ownUserID
info = try RoomPreviewInfoProxy(roomPreviewInfo: roomPreview.info())
}
func forgetRoom() async -> Result<Void, RoomProxyError> {
do {
return try await .success(roomPreview.forget())
} catch {
MXLog.error("Failed forgetting the room with error: \(error)")
return .failure(.sdkError(error))
}
}
}

View File

@ -32,14 +32,4 @@ final class RoomPreviewProxy: RoomPreviewProxyProtocol {
senderRoomMember: senderRoomMember) senderRoomMember: senderRoomMember)
} }
} }
func forgetRoom() async -> Result<Void, RoomProxyError> {
do {
try await roomPreview.forget()
return .success(())
} catch {
MXLog.error("Failed forgetting the room with error: \(error)")
return .failure(.sdkError(error))
}
}
} }

View File

@ -11,7 +11,4 @@ import Foundation
protocol RoomPreviewProxyProtocol { protocol RoomPreviewProxyProtocol {
var info: RoomPreviewInfoProxy { get } var info: RoomPreviewInfoProxy { get }
var ownMembershipDetails: RoomMembershipDetailsProxyProtocol? { get async } var ownMembershipDetails: RoomMembershipDetailsProxyProtocol? { get async }
/// Use this function to forget the room, should only be used if the current user membership is `banned`
func forgetRoom() async -> Result<Void, RoomProxyError>
} }

View File

@ -22,7 +22,7 @@ enum RoomProxyType {
case joined(JoinedRoomProxyProtocol) case joined(JoinedRoomProxyProtocol)
case invited(InvitedRoomProxyProtocol) case invited(InvitedRoomProxyProtocol)
case knocked(KnockedRoomProxyProtocol) case knocked(KnockedRoomProxyProtocol)
case banned case banned(BannedRoomProxyProtocol)
case left case left
} }
@ -45,6 +45,12 @@ protocol KnockedRoomProxyProtocol: RoomProxyProtocol {
func cancelKnock() async -> Result<Void, RoomProxyError> func cancelKnock() async -> Result<Void, RoomProxyError>
} }
// sourcery: AutoMockable
protocol BannedRoomProxyProtocol: RoomProxyProtocol {
var info: BaseRoomInfoProxyProtocol { get }
func forgetRoom() async -> Result<Void, RoomProxyError>
}
enum JoinedRoomProxyAction: Equatable { enum JoinedRoomProxyAction: Equatable {
case roomInfoUpdate case roomInfoUpdate
} }

View File

@ -61,7 +61,7 @@ packages:
# Element/Matrix dependencies # Element/Matrix dependencies
MatrixRustSDK: MatrixRustSDK:
url: https://github.com/element-hq/matrix-rust-components-swift url: https://github.com/element-hq/matrix-rust-components-swift
exactVersion: 25.02.04 exactVersion: 25.02.05
# path: ../matrix-rust-sdk # path: ../matrix-rust-sdk
Compound: Compound:
url: https://github.com/element-hq/compound-ios url: https://github.com/element-hq/compound-ios