mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Cleanup proxy errors
- proxy errors have been getting repetitive and not particularly useful - differentiate between sdk and client errors and keep what provides value - add error logs everywhere a failure occurs
This commit is contained in:
committed by
Stefan Ceriu
parent
3418d24557
commit
c85c1593ee
@@ -24,6 +24,10 @@ struct ClientProxyMockConfiguration {
|
|||||||
var roomDirectorySearchProxy: RoomDirectorySearchProxyProtocol?
|
var roomDirectorySearchProxy: RoomDirectorySearchProxyProtocol?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ClientProxyMockError: Error {
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|
||||||
extension ClientProxyMock {
|
extension ClientProxyMock {
|
||||||
convenience init(_ configuration: ClientProxyMockConfiguration) {
|
convenience init(_ configuration: ClientProxyMockConfiguration) {
|
||||||
self.init()
|
self.init()
|
||||||
@@ -53,25 +57,25 @@ extension ClientProxyMock {
|
|||||||
|
|
||||||
isOnlyDeviceLeftReturnValue = .success(false)
|
isOnlyDeviceLeftReturnValue = .success(false)
|
||||||
accountURLActionReturnValue = "https://matrix.org/account"
|
accountURLActionReturnValue = "https://matrix.org/account"
|
||||||
directRoomForUserIDReturnValue = .failure(.failedRetrievingDirectRoom)
|
directRoomForUserIDReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
createDirectRoomWithExpectedRoomNameReturnValue = .failure(.failedCreatingRoom)
|
createDirectRoomWithExpectedRoomNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReturnValue = .failure(.failedCreatingRoom)
|
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
uploadMediaReturnValue = .failure(.failedUploadingMedia(.unknown))
|
uploadMediaReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
loadUserDisplayNameReturnValue = .failure(.failedRetrievingUserDisplayName)
|
loadUserDisplayNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
setUserDisplayNameReturnValue = .failure(.failedSettingUserDisplayName)
|
setUserDisplayNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
loadUserAvatarURLReturnValue = .failure(.failedRetrievingUserAvatarURL)
|
loadUserAvatarURLReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
setUserAvatarMediaReturnValue = .failure(.failedSettingUserAvatar)
|
setUserAvatarMediaReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
removeUserAvatarReturnValue = .failure(.failedSettingUserAvatar)
|
removeUserAvatarReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
logoutReturnValue = nil
|
logoutReturnValue = nil
|
||||||
searchUsersSearchTermLimitReturnValue = .success(.init(results: [], limited: false))
|
searchUsersSearchTermLimitReturnValue = .success(.init(results: [], limited: false))
|
||||||
profileForReturnValue = .success(.init(userID: "@a:b.com", displayName: "Some user"))
|
profileForReturnValue = .success(.init(userID: "@a:b.com", displayName: "Some user"))
|
||||||
sessionVerificationControllerProxyReturnValue = .failure(.failedRetrievingSessionVerificationController)
|
sessionVerificationControllerProxyReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
ignoreUserReturnValue = .success(())
|
ignoreUserReturnValue = .success(())
|
||||||
unignoreUserReturnValue = .success(())
|
unignoreUserReturnValue = .success(())
|
||||||
|
|
||||||
loadMediaContentForSourceThrowableError = ClientProxyError.failedLoadingMedia
|
loadMediaContentForSourceThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic)
|
||||||
loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.failedLoadingMedia
|
loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic)
|
||||||
loadMediaFileForSourceBodyThrowableError = ClientProxyError.failedLoadingMedia
|
loadMediaFileForSourceBodyThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic)
|
||||||
|
|
||||||
secureBackupController = {
|
secureBackupController = {
|
||||||
let secureBackupController = SecureBackupControllerMock()
|
let secureBackupController = SecureBackupControllerMock()
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ struct RoomProxyMockConfiguration {
|
|||||||
var canUserJoinCall = true
|
var canUserJoinCall = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum RoomProxyMockError: Error {
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|
||||||
extension RoomProxyMock {
|
extension RoomProxyMock {
|
||||||
@MainActor
|
@MainActor
|
||||||
convenience init(with configuration: RoomProxyMockConfiguration) {
|
convenience init(with configuration: RoomProxyMockConfiguration) {
|
||||||
@@ -83,7 +87,7 @@ extension RoomProxyMock {
|
|||||||
setTopicClosure = { _ in .success(()) }
|
setTopicClosure = { _ in .success(()) }
|
||||||
getMemberUserIDClosure = { [weak self] userID in
|
getMemberUserIDClosure = { [weak self] userID in
|
||||||
guard let member = self?.membersPublisher.value.first(where: { $0.userID == userID }) else {
|
guard let member = self?.membersPublisher.value.first(where: { $0.userID == userID }) else {
|
||||||
return .failure(.failedRetrievingMember)
|
return .failure(.sdkError(RoomProxyMockError.generic))
|
||||||
}
|
}
|
||||||
return .success(member)
|
return .success(member)
|
||||||
}
|
}
|
||||||
@@ -98,7 +102,7 @@ extension RoomProxyMock {
|
|||||||
resetPowerLevelsReturnValue = .success(.mock)
|
resetPowerLevelsReturnValue = .success(.mock)
|
||||||
suggestedRoleForClosure = { [weak self] userID in
|
suggestedRoleForClosure = { [weak self] userID in
|
||||||
guard case .success(let member) = await self?.getMember(userID: userID) else {
|
guard case .success(let member) = await self?.getMember(userID: userID) else {
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(RoomProxyMockError.generic))
|
||||||
}
|
}
|
||||||
return .success(member.role)
|
return .success(member.role)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,33 +110,6 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
|
|||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func displayError(_ type: ClientProxyError) {
|
|
||||||
switch type {
|
|
||||||
case .failedCreatingRoom:
|
|
||||||
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
|
||||||
title: L10n.commonError,
|
|
||||||
message: L10n.screenStartChatErrorStartingChat)
|
|
||||||
case .failedSearchingUsers:
|
|
||||||
state.bindings.alertInfo = AlertInfo(id: .unknown)
|
|
||||||
case .failedUploadingMedia(let matrixError):
|
|
||||||
switch matrixError {
|
|
||||||
case .fileTooLarge:
|
|
||||||
// waiting for proper copy
|
|
||||||
state.bindings.alertInfo = AlertInfo(id: .fileTooLarge)
|
|
||||||
default:
|
|
||||||
state.bindings.alertInfo = AlertInfo(id: .failedUploadingMedia)
|
|
||||||
}
|
|
||||||
case .mediaFileError:
|
|
||||||
state.bindings.alertInfo = AlertInfo(id: .mediaFileError)
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var clientProxy: ClientProxyProtocol {
|
|
||||||
userSession.clientProxy
|
|
||||||
}
|
|
||||||
|
|
||||||
private func createRoom() async {
|
private func createRoom() async {
|
||||||
defer {
|
defer {
|
||||||
hideLoadingIndicator()
|
hideLoadingIndicator()
|
||||||
@@ -145,27 +118,42 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
|
|||||||
|
|
||||||
let avatarURL: URL?
|
let avatarURL: URL?
|
||||||
if let media = createRoomParameters.avatarImageMedia {
|
if let media = createRoomParameters.avatarImageMedia {
|
||||||
switch await clientProxy.uploadMedia(media) {
|
switch await userSession.clientProxy.uploadMedia(media) {
|
||||||
case .success(let url):
|
case .success(let url):
|
||||||
avatarURL = URL(string: url)
|
avatarURL = URL(string: url)
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
displayError(error)
|
switch error {
|
||||||
|
case .failedUploadingMedia(_, let errorCode):
|
||||||
|
switch errorCode {
|
||||||
|
case .fileTooLarge:
|
||||||
|
state.bindings.alertInfo = AlertInfo(id: .fileTooLarge)
|
||||||
|
default:
|
||||||
|
state.bindings.alertInfo = AlertInfo(id: .failedUploadingMedia)
|
||||||
|
}
|
||||||
|
case .invalidMedia:
|
||||||
|
state.bindings.alertInfo = AlertInfo(id: .mediaFileError)
|
||||||
|
default:
|
||||||
|
state.bindings.alertInfo = AlertInfo(id: .unknown)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
avatarURL = nil
|
avatarURL = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch await clientProxy.createRoom(name: createRoomParameters.name,
|
switch await userSession.clientProxy.createRoom(name: createRoomParameters.name,
|
||||||
topic: createRoomParameters.topic,
|
topic: createRoomParameters.topic,
|
||||||
isRoomPrivate: createRoomParameters.isRoomPrivate,
|
isRoomPrivate: createRoomParameters.isRoomPrivate,
|
||||||
userIDs: state.selectedUsers.map(\.userID),
|
userIDs: state.selectedUsers.map(\.userID),
|
||||||
avatarURL: avatarURL) {
|
avatarURL: avatarURL) {
|
||||||
case .success(let roomId):
|
case .success(let roomId):
|
||||||
analytics.trackCreatedRoom(isDM: false)
|
analytics.trackCreatedRoom(isDM: false)
|
||||||
actionsSubject.send(.openRoom(withIdentifier: roomId))
|
actionsSubject.send(.openRoom(withIdentifier: roomId))
|
||||||
case .failure(let failure):
|
case .failure:
|
||||||
displayError(failure)
|
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
||||||
|
title: L10n.commonError,
|
||||||
|
message: L10n.screenStartChatErrorStartingChat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
|
|||||||
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 let roomProxy = await clientProxy.roomForIdentifier(roomID) else {
|
guard let roomProxy = await clientProxy.roomForIdentifier(roomID) else {
|
||||||
displayError(.failedAcceptingInvite)
|
displayError()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,8 +127,8 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
|
|||||||
case .success:
|
case .success:
|
||||||
actionsSubject.send(.openRoom(withIdentifier: roomID))
|
actionsSubject.send(.openRoom(withIdentifier: roomID))
|
||||||
analytics.trackJoinedRoom(isDM: roomProxy.isDirect, isSpace: roomProxy.isSpace, activeMemberCount: UInt(roomProxy.activeMembersCount))
|
analytics.trackJoinedRoom(isDM: roomProxy.isDirect, isSpace: roomProxy.isSpace, activeMemberCount: UInt(roomProxy.activeMembersCount))
|
||||||
case .failure(let error):
|
case .failure:
|
||||||
displayError(error)
|
displayError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,20 +143,19 @@ class InvitesScreenViewModel: InvitesScreenViewModelType, InvitesScreenViewModel
|
|||||||
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 let roomProxy = await clientProxy.roomForIdentifier(roomID) else {
|
guard let roomProxy = await clientProxy.roomForIdentifier(roomID) else {
|
||||||
displayError(.failedRejectingInvite)
|
displayError()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = await roomProxy.rejectInvitation()
|
let result = await roomProxy.rejectInvitation()
|
||||||
|
|
||||||
if case .failure(let error) = result {
|
if case .failure = result {
|
||||||
displayError(error)
|
displayError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func displayError(_ error: RoomProxyError) {
|
private func displayError() {
|
||||||
MXLog.error("Failed to accept/decline invite: \(error)")
|
|
||||||
state.bindings.alertInfo = .init(id: true,
|
state.bindings.alertInfo = .init(id: true,
|
||||||
title: L10n.commonError,
|
title: L10n.commonError,
|
||||||
message: L10n.errorUnknown)
|
message: L10n.errorUnknown)
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
|
|||||||
|
|
||||||
Task {
|
Task {
|
||||||
// Can't use async let because the mocks aren't thread safe when calling the same method 🤦♂️
|
// Can't use async let because the mocks aren't thread safe when calling the same method 🤦♂️
|
||||||
state.canEditAvatar = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar) == .success(true)
|
state.canEditAvatar = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar).get()) == .some(true)
|
||||||
state.canEditName = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName) == .success(true)
|
state.canEditName = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName).get()) == .some(true)
|
||||||
state.canEditTopic = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic) == .success(true)
|
state.canEditTopic = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic).get()) == .some(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -178,15 +178,15 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func updatePowerLevelPermissions() async {
|
private func updatePowerLevelPermissions() async {
|
||||||
async let canInviteUsers = roomProxy.canUserInvite(userID: roomProxy.ownUserID) == .success(true)
|
state.canEditRoomName = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName).get()) == true
|
||||||
// Can't use async let because the mocks aren't thread safe when calling the same method 🤦♂️
|
state.canEditRoomTopic = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic).get()) == true
|
||||||
state.canEditRoomName = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName) == .success(true)
|
state.canEditRoomAvatar = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar).get()) == true
|
||||||
state.canEditRoomTopic = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic) == .success(true)
|
|
||||||
state.canEditRoomAvatar = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomAvatar) == .success(true)
|
|
||||||
if appSettings.roomModerationEnabled {
|
if appSettings.roomModerationEnabled {
|
||||||
state.canEditRolesOrPermissions = await roomProxy.suggestedRole(for: roomProxy.ownUserID) == .success(.administrator)
|
state.canEditRolesOrPermissions = await (try? roomProxy.suggestedRole(for: roomProxy.ownUserID).get()) == .administrator
|
||||||
}
|
}
|
||||||
state.canInviteUsers = await canInviteUsers
|
|
||||||
|
state.canInviteUsers = await (try? roomProxy.canUserInvite(userID: roomProxy.ownUserID).get()) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupNotificationSettingsSubscription() {
|
private func setupNotificationSettingsSubscription() {
|
||||||
|
|||||||
@@ -110,12 +110,9 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
|
|||||||
bannedMembers: roomMembersDetails.bannedMembers,
|
bannedMembers: roomMembersDetails.bannedMembers,
|
||||||
bindings: state.bindings)
|
bindings: state.bindings)
|
||||||
|
|
||||||
async let canInviteUsers = roomProxy.canUserInvite(userID: roomProxy.ownUserID)
|
self.state.canInviteUsers = await (try? roomProxy.canUserInvite(userID: roomProxy.ownUserID).get()) == true
|
||||||
async let canKickUsers = roomProxy.canUserKick(userID: roomProxy.ownUserID)
|
self.state.canKickUsers = await (try? roomProxy.canUserKick(userID: roomProxy.ownUserID).get()) == true
|
||||||
async let canBanUsers = roomProxy.canUserBan(userID: roomProxy.ownUserID)
|
self.state.canBanUsers = await (try? roomProxy.canUserBan(userID: roomProxy.ownUserID).get()) == true
|
||||||
self.state.canInviteUsers = await canInviteUsers == .success(true)
|
|
||||||
self.state.canKickUsers = await canKickUsers == .success(true)
|
|
||||||
self.state.canBanUsers = await canBanUsers == .success(true)
|
|
||||||
|
|
||||||
hideLoader()
|
hideLoader()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,16 +56,16 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
case .selectUser(let user):
|
case .selectUser(let user):
|
||||||
showLoadingIndicator()
|
showLoadingIndicator()
|
||||||
Task {
|
Task {
|
||||||
let currentDirectRoom = await clientProxy.directRoomForUserID(user.userID)
|
let currentDirectRoom = await userSession.clientProxy.directRoomForUserID(user.userID)
|
||||||
switch currentDirectRoom {
|
switch currentDirectRoom {
|
||||||
case .success(.some(let roomId)):
|
case .success(.some(let roomId)):
|
||||||
self.hideLoadingIndicator()
|
self.hideLoadingIndicator()
|
||||||
self.actionsSubject.send(.openRoom(withIdentifier: roomId))
|
self.actionsSubject.send(.openRoom(withIdentifier: roomId))
|
||||||
case .success(nil):
|
case .success:
|
||||||
await self.createDirectRoom(with: user)
|
await self.createDirectRoom(with: user)
|
||||||
case .failure(let failure):
|
case .failure:
|
||||||
self.hideLoadingIndicator()
|
self.hideLoadingIndicator()
|
||||||
self.displayError(failure)
|
self.displayError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,19 +73,6 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func displayError(_ type: ClientProxyError) {
|
|
||||||
switch type {
|
|
||||||
case .failedCreatingRoom, .failedRetrievingDirectRoom:
|
|
||||||
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
|
||||||
title: L10n.commonError,
|
|
||||||
message: L10n.screenStartChatErrorStartingChat)
|
|
||||||
case .failedSearchingUsers:
|
|
||||||
state.bindings.alertInfo = AlertInfo(id: .unknown)
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setupBindings() {
|
private func setupBindings() {
|
||||||
context.$viewState
|
context.$viewState
|
||||||
.map(\.bindings.searchQuery)
|
.map(\.bindings.searchQuery)
|
||||||
@@ -101,12 +88,12 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
private var fetchUsersTask: Task<Void, Never>?
|
private var fetchUsersTask: Task<Void, Never>?
|
||||||
|
|
||||||
private func fetchUsers() {
|
private func fetchUsers() {
|
||||||
guard searchQuery.count >= 3 else {
|
guard context.searchQuery.count >= 3 else {
|
||||||
state.usersSection = .init(type: .suggestions, users: [])
|
state.usersSection = .init(type: .suggestions, users: [])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fetchUsersTask = Task {
|
fetchUsersTask = Task {
|
||||||
let result = await userDiscoveryService.searchProfiles(with: searchQuery)
|
let result = await userDiscoveryService.searchProfiles(with: context.searchQuery)
|
||||||
guard !Task.isCancelled else { return }
|
guard !Task.isCancelled else { return }
|
||||||
handleResult(for: .searchResult, result: result)
|
handleResult(for: .searchResult, result: result)
|
||||||
}
|
}
|
||||||
@@ -117,7 +104,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
case .success(let users):
|
case .success(let users):
|
||||||
state.usersSection = .init(type: sectionType, users: users)
|
state.usersSection = .init(type: sectionType, users: users)
|
||||||
case .failure:
|
case .failure:
|
||||||
break
|
state.bindings.alertInfo = AlertInfo(id: .unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,23 +113,21 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
|||||||
hideLoadingIndicator()
|
hideLoadingIndicator()
|
||||||
}
|
}
|
||||||
showLoadingIndicator()
|
showLoadingIndicator()
|
||||||
switch await clientProxy.createDirectRoom(with: user.userID, expectedRoomName: user.displayName) {
|
switch await userSession.clientProxy.createDirectRoom(with: user.userID, expectedRoomName: user.displayName) {
|
||||||
case .success(let roomId):
|
case .success(let roomId):
|
||||||
analytics.trackCreatedRoom(isDM: true)
|
analytics.trackCreatedRoom(isDM: true)
|
||||||
actionsSubject.send(.openRoom(withIdentifier: roomId))
|
actionsSubject.send(.openRoom(withIdentifier: roomId))
|
||||||
case .failure(let failure):
|
case .failure:
|
||||||
displayError(failure)
|
displayError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var clientProxy: ClientProxyProtocol {
|
private func displayError() {
|
||||||
userSession.clientProxy
|
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
||||||
|
title: L10n.commonError,
|
||||||
|
message: L10n.screenStartChatErrorStartingChat)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var searchQuery: String {
|
|
||||||
context.searchQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Loading indicator
|
// MARK: Loading indicator
|
||||||
|
|
||||||
private static let loadingIndicatorIdentifier = "\(StartChatScreenViewModel.self)-Loading"
|
private static let loadingIndicatorIdentifier = "\(StartChatScreenViewModel.self)-Loading"
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
return .success(result)
|
return .success(result)
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking isLastDevice with error: \(error)")
|
MXLog.error("Failed checking isLastDevice with error: \(error)")
|
||||||
return .failure(.failedCheckingIsLastDevice(error))
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +293,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
let roomID = try self.client.getDmRoom(userId: userID)?.id()
|
let roomID = try self.client.getDmRoom(userId: userID)?.id()
|
||||||
return .success(roomID)
|
return .success(roomID)
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingDirectRoom)
|
MXLog.error("Failed retrieving direct room for userID: \(userID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,7 +314,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
let result = try self.client.createRoom(request: parameters)
|
let result = try self.client.createRoom(request: parameters)
|
||||||
return .success(result)
|
return .success(result)
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedCreatingRoom)
|
MXLog.error("Failed creating direct room for userID: \(userID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +337,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
let roomID = try self.client.createRoom(request: parameters)
|
let roomID = try self.client.createRoom(request: parameters)
|
||||||
return .success(roomID)
|
return .success(roomID)
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedCreatingRoom)
|
MXLog.error("Failed creating room with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,20 +354,27 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedJoiningRoom)
|
MXLog.error("Failed joining roomID: \(roomID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func uploadMedia(_ media: MediaInfo) async -> Result<String, ClientProxyError> {
|
func uploadMedia(_ media: MediaInfo) async -> Result<String, ClientProxyError> {
|
||||||
guard let mimeType = media.mimeType else { return .failure(ClientProxyError.mediaFileError) }
|
guard let mimeType = media.mimeType else {
|
||||||
|
MXLog.error("Failed uploading media, invalid mime type: \(media)")
|
||||||
|
return .failure(ClientProxyError.invalidMedia)
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let data = try Data(contentsOf: media.url)
|
let data = try Data(contentsOf: media.url)
|
||||||
let matrixUrl = try await client.uploadMedia(mimeType: mimeType, data: data, progressWatcher: nil)
|
let matrixUrl = try await client.uploadMedia(mimeType: mimeType, data: data, progressWatcher: nil)
|
||||||
return .success(matrixUrl)
|
return .success(matrixUrl)
|
||||||
} catch let error as ClientError {
|
} catch let error as ClientError {
|
||||||
return .failure(ClientProxyError.failedUploadingMedia(error.code))
|
MXLog.error("Failed uploading media with error: \(error)")
|
||||||
|
return .failure(ClientProxyError.failedUploadingMedia(error, error.code))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(ClientProxyError.mediaFileError)
|
MXLog.error("Failed uploading media with error: \(error)")
|
||||||
|
return .failure(ClientProxyError.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,7 +445,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
self.userDisplayNameSubject.send(displayName)
|
self.userDisplayNameSubject.send(displayName)
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingUserDisplayName)
|
MXLog.error("Failed loading user display name with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,7 +460,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedSettingUserDisplayName)
|
MXLog.error("Failed setting user display name with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -462,7 +474,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
self.userAvatarURLSubject.send(urlString.flatMap(URL.init))
|
self.userAvatarURLSubject.send(urlString.flatMap(URL.init))
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingUserAvatarURL)
|
MXLog.error("Failed loading user avatar URL with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -470,7 +483,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
func setUserAvatar(media: MediaInfo) async -> Result<Void, ClientProxyError> {
|
func setUserAvatar(media: MediaInfo) async -> Result<Void, ClientProxyError> {
|
||||||
await Task.dispatch(on: .global()) {
|
await Task.dispatch(on: .global()) {
|
||||||
guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else {
|
guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else {
|
||||||
return .failure(.failedSettingUserAvatar)
|
MXLog.error("Failed uploading, invalid media: \(media)")
|
||||||
|
return .failure(.invalidMedia)
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -481,7 +495,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedSettingUserAvatar)
|
MXLog.error("Failed setting user avatar with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,7 +510,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedSettingUserAvatar)
|
MXLog.error("Failed removing user avatar with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -506,7 +522,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
let sessionVerificationController = try self.client.getSessionVerificationController()
|
let sessionVerificationController = try self.client.getSessionVerificationController()
|
||||||
return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController))
|
return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingSessionVerificationController)
|
MXLog.error("Failed retrieving session verification controller proxy with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -536,7 +553,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
return try .success(.init(sdkResults: self.client.searchUsers(searchTerm: searchTerm, limit: UInt64(limit))))
|
return try .success(.init(sdkResults: self.client.searchUsers(searchTerm: searchTerm, limit: UInt64(limit))))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedSearchingUsers)
|
MXLog.error("Failed searching users with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -546,7 +564,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
return try .success(.init(sdkUserProfile: self.client.getProfile(userId: userID)))
|
return try .success(.init(sdkUserProfile: self.client.getProfile(userId: userID)))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedGettingUserProfile)
|
MXLog.error("Failed retrieving profile for userID: \(userID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -563,7 +582,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed ignoring user with error: \(error)")
|
MXLog.error("Failed ignoring user with error: \(error)")
|
||||||
return .failure(.failedIgnoringUser)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,7 +592,7 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed unignoring user with error: \(error)")
|
MXLog.error("Failed unignoring user with error: \(error)")
|
||||||
return .failure(.failedUnignoringUser)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,22 +38,9 @@ enum ClientProxyLoadingState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ClientProxyError: Error {
|
enum ClientProxyError: Error {
|
||||||
case failedCreatingRoom
|
case sdkError(Error)
|
||||||
case failedRetrievingDirectRoom
|
case invalidMedia
|
||||||
case failedRetrievingUserDisplayName
|
case failedUploadingMedia(Error, MatrixErrorCode)
|
||||||
case failedRetrievingUserAvatarURL
|
|
||||||
case failedSettingUserDisplayName
|
|
||||||
case failedRetrievingSessionVerificationController
|
|
||||||
case failedLoadingMedia
|
|
||||||
case mediaFileError
|
|
||||||
case failedUploadingMedia(MatrixErrorCode)
|
|
||||||
case failedSearchingUsers
|
|
||||||
case failedGettingUserProfile
|
|
||||||
case failedSettingUserAvatar
|
|
||||||
case failedCheckingIsLastDevice(Error?)
|
|
||||||
case failedIgnoringUser
|
|
||||||
case failedUnignoringUser
|
|
||||||
case failedJoiningRoom
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SlidingSyncConstants {
|
enum SlidingSyncConstants {
|
||||||
|
|||||||
@@ -168,7 +168,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
try self.room.redact(eventId: eventID, reason: nil)
|
try self.room.redact(eventId: eventID, reason: nil)
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRedactingEvent)
|
MXLog.error("Failed redacting eventID: \(eventID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +185,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
try self.room.reportContent(eventId: eventID, score: nil, reason: reason)
|
try self.room.reportContent(eventId: eventID, score: nil, reason: reason)
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedReportingContent)
|
MXLog.error("Failed reporting eventID: \(eventID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,7 +200,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
membersSubject.value = members.map(RoomMemberProxy.init)
|
membersSubject.value = members.map(RoomMemberProxy.init)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("[RoomProxy] Failed to update members using no sync API: \(error)")
|
MXLog.error("[RoomProxy] Failed updating members using no sync API: \(error)")
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -208,7 +210,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
membersSubject.value = members.map(RoomMemberProxy.init)
|
membersSubject.value = members.map(RoomMemberProxy.init)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("[RoomProxy] Failed to update members using sync API: \(error)")
|
MXLog.error("[RoomProxy] Failed updating members using sync API: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +228,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
let member = try await room.member(userId: userID)
|
let member = try await room.member(userId: userID)
|
||||||
return .success(RoomMemberProxy(member: member))
|
return .success(RoomMemberProxy(member: member))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingMember)
|
MXLog.error("Failed retrieving member \(userID) with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,8 +244,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
try self.room.leave()
|
try self.room.leave()
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed to leave the room: \(error)")
|
MXLog.error("Failed leaving room with error: \(error)")
|
||||||
return .failure(.failedLeavingRoom)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,7 +255,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
return try .success(self.room.leave())
|
return try .success(self.room.leave())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRejectingInvite)
|
MXLog.error("Failed rejecting invitiation with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,7 +267,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
try self.room.join()
|
try self.room.join()
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedAcceptingInvite)
|
MXLog.error("Failed accepting invitation with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,7 +280,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try .success(self.room.inviteUserById(userId: userID))
|
return try .success(self.room.inviteUserById(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed inviting user \(userID) with error: \(error)")
|
MXLog.error("Failed inviting user \(userID) with error: \(error)")
|
||||||
return .failure(.failedInvitingUser)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -285,7 +290,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
return try .success(self.room.setName(name: name))
|
return try .success(self.room.setName(name: name))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedSettingRoomName)
|
MXLog.error("Failed setting name with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,7 +301,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
return try .success(self.room.setTopic(topic: topic))
|
return try .success(self.room.setTopic(topic: topic))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedSettingRoomTopic)
|
MXLog.error("Failed setting topic with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +312,8 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
return try .success(self.room.removeAvatar())
|
return try .success(self.room.removeAvatar())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRemovingAvatar)
|
MXLog.error("Failed removing avatar with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,14 +321,16 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
func uploadAvatar(media: MediaInfo) async -> Result<Void, RoomProxyError> {
|
func uploadAvatar(media: MediaInfo) async -> Result<Void, RoomProxyError> {
|
||||||
await Task.dispatch(on: .global()) {
|
await Task.dispatch(on: .global()) {
|
||||||
guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else {
|
guard case let .image(imageURL, _, _) = media, let mimeType = media.mimeType else {
|
||||||
return .failure(.failedUploadingAvatar)
|
MXLog.error("Failed uploading avatar, invalid media: \(media)")
|
||||||
|
return .failure(.invalidMedia)
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let data = try Data(contentsOf: imageURL)
|
let data = try Data(contentsOf: imageURL)
|
||||||
return try .success(self.room.uploadAvatar(mimeType: mimeType, data: data, mediaInfo: nil))
|
return try .success(self.room.uploadAvatar(mimeType: mimeType, data: data, mediaInfo: nil))
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedUploadingAvatar)
|
MXLog.error("Failed uploading avatar with error: \(error)")
|
||||||
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,7 +341,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed marking room \(id) as read with error: \(error)")
|
MXLog.error("Failed marking room \(id) as read with error: \(error)")
|
||||||
return .failure(.failedMarkingAsRead)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +353,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed sending typing notice with error: \(error)")
|
MXLog.error("Failed sending typing notice with error: \(error)")
|
||||||
return .failure(.failedSendingTypingNotice)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +367,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed marking room \(id) as unread: \(isUnread) with error: \(error)")
|
MXLog.error("Failed marking room \(id) as unread: \(isUnread) with error: \(error)")
|
||||||
return .failure(.failedFlaggingAsUnread)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +377,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed flagging room \(id) as favourite with error: \(error)")
|
MXLog.error("Failed flagging room \(id) as favourite with error: \(error)")
|
||||||
return .failure(.failedFlaggingAsFavourite)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,7 +388,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.getPowerLevels())
|
return try await .success(room.getPowerLevels())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed building the current power level settings: \(error)")
|
MXLog.error("Failed building the current power level settings: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +397,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.applyPowerLevelChanges(changes: changes))
|
return try await .success(room.applyPowerLevelChanges(changes: changes))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed applying the power level changes: \(error)")
|
MXLog.error("Failed applying the power level changes: \(error)")
|
||||||
return .failure(.failedSettingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,7 +406,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.resetPowerLevels())
|
return try await .success(room.resetPowerLevels())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed resetting the power levels: \(error)")
|
MXLog.error("Failed resetting the power levels: \(error)")
|
||||||
return .failure(.failedSettingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,7 +415,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.suggestedRoleForUser(userId: userID))
|
return try await .success(room.suggestedRoleForUser(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed getting a user's role: \(error)")
|
MXLog.error("Failed getting a user's role: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +425,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.updatePowerLevelsForUsers(updates: updates))
|
return try await .success(room.updatePowerLevelsForUsers(updates: updates))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed updating user power levels changes: \(error)")
|
MXLog.error("Failed updating user power levels changes: \(error)")
|
||||||
return .failure(.failedSettingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,7 +434,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserSendState(userId: userID, stateEvent: event))
|
return try await .success(room.canUserSendState(userId: userID, stateEvent: event))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can send \(event) with error: \(error)")
|
MXLog.error("Failed checking if the user can send \(event) with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +443,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserInvite(userId: userID))
|
return try await .success(room.canUserInvite(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can invite with error: \(error)")
|
MXLog.error("Failed checking if the user can invite with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +452,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserRedactOther(userId: userID))
|
return try await .success(room.canUserRedactOther(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can redact others with error: \(error)")
|
MXLog.error("Failed checking if the user can redact others with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,7 +461,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserRedactOwn(userId: userID))
|
return try await .success(room.canUserRedactOwn(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can redact self with error: \(error)")
|
MXLog.error("Failed checking if the user can redact self with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,7 +470,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserKick(userId: userID))
|
return try await .success(room.canUserKick(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can kick with error: \(error)")
|
MXLog.error("Failed checking if the user can kick with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +479,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserBan(userId: userID))
|
return try await .success(room.canUserBan(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can ban with error: \(error)")
|
MXLog.error("Failed checking if the user can ban with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,7 +488,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserTriggerRoomNotification(userId: userID))
|
return try await .success(room.canUserTriggerRoomNotification(userId: userID))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
|
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,7 +500,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed kicking \(userID) with error: \(error)")
|
MXLog.error("Failed kicking \(userID) with error: \(error)")
|
||||||
return .failure(.failedModeration)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,7 +510,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed banning \(userID) with error: \(error)")
|
MXLog.error("Failed banning \(userID) with error: \(error)")
|
||||||
return .failure(.failedModeration)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,7 +520,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed unbanning \(userID) with error: \(error)")
|
MXLog.error("Failed unbanning \(userID) with error: \(error)")
|
||||||
return .failure(.failedModeration)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +531,7 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return try await .success(room.canUserSendState(userId: userID, stateEvent: .callMember))
|
return try await .success(room.canUserSendState(userId: userID, stateEvent: .callMember))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
|
MXLog.error("Failed checking if the user can trigger room notification with error: \(error)")
|
||||||
return .failure(.failedCheckingPermission)
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,14 +546,14 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
let urlString = try await room.matrixToPermalink()
|
let urlString = try await room.matrixToPermalink()
|
||||||
|
|
||||||
guard let url = URL(string: urlString) else {
|
guard let url = URL(string: urlString) else {
|
||||||
MXLog.error("Invalid permalink URL string: \(urlString)")
|
MXLog.error("Failed creating permalink for roomID: \(id), invalid permalink URL string: \(urlString)")
|
||||||
return .failure(.generic("Invalid permalink URL string: \(urlString)"))
|
return .failure(.invalidURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .success(url)
|
return .success(url)
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed creating permalink for roomID: \(id) with error: \(error)")
|
MXLog.error("Failed creating permalink for roomID: \(id) with error: \(error)")
|
||||||
return .failure(.generic(error.localizedDescription))
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,14 +562,14 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
let urlString = try await room.matrixToEventPermalink(eventId: eventID)
|
let urlString = try await room.matrixToEventPermalink(eventId: eventID)
|
||||||
|
|
||||||
guard let url = URL(string: urlString) else {
|
guard let url = URL(string: urlString) else {
|
||||||
MXLog.error("Invalid permalink URL string: \(urlString)")
|
MXLog.error("Failed creating permalink for eventID: \(eventID), invalid permalink URL string: \(urlString)")
|
||||||
return .failure(.generic("Invalid permalink URL string: \(urlString)"))
|
return .failure(.invalidURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .success(url)
|
return .success(url)
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed creating permalink for eventID: \(eventID) with error: \(error)")
|
MXLog.error("Failed creating permalink for eventID: \(eventID) with error: \(error)")
|
||||||
return .failure(.generic(error.localizedDescription))
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,26 +18,11 @@ import Combine
|
|||||||
import Foundation
|
import Foundation
|
||||||
import MatrixRustSDK
|
import MatrixRustSDK
|
||||||
|
|
||||||
enum RoomProxyError: Error, Equatable {
|
enum RoomProxyError: Error {
|
||||||
case generic(String?)
|
case sdkError(Error)
|
||||||
case failedRedactingEvent
|
|
||||||
case failedReportingContent
|
case invalidURL
|
||||||
case failedRetrievingMember
|
case invalidMedia
|
||||||
case failedLeavingRoom
|
|
||||||
case failedAcceptingInvite
|
|
||||||
case failedRejectingInvite
|
|
||||||
case failedInvitingUser
|
|
||||||
case failedSettingRoomName
|
|
||||||
case failedSettingRoomTopic
|
|
||||||
case failedRemovingAvatar
|
|
||||||
case failedUploadingAvatar
|
|
||||||
case failedCheckingPermission
|
|
||||||
case failedSettingPermission
|
|
||||||
case failedFlaggingAsUnread
|
|
||||||
case failedMarkingAsRead
|
|
||||||
case failedSendingTypingNotice
|
|
||||||
case failedFlaggingAsFavourite
|
|
||||||
case failedModeration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RoomProxyAction {
|
enum RoomProxyAction {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
func testLeaveRoomError() async throws {
|
func testLeaveRoomError() async throws {
|
||||||
let mockRoomId = "1"
|
let mockRoomId = "1"
|
||||||
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, name: "Some room"))
|
let room: RoomProxyMock = .init(with: .init(id: mockRoomId, name: "Some room"))
|
||||||
room.leaveRoomClosure = { .failure(.failedLeavingRoom) }
|
room.leaveRoomClosure = { .failure(.sdkError(ClientProxyMockError.generic)) }
|
||||||
|
|
||||||
clientProxy.roomForIdentifierClosure = { _ in room }
|
clientProxy.roomForIdentifierClosure = { _ in room }
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
defer {
|
defer {
|
||||||
expectation.fulfill()
|
expectation.fulfill()
|
||||||
}
|
}
|
||||||
return .failure(.failedLeavingRoom)
|
return .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
}
|
}
|
||||||
context.send(viewAction: .confirmLeave)
|
context.send(viewAction: .confirmLeave)
|
||||||
await fulfillment(of: [expectation])
|
await fulfillment(of: [expectation])
|
||||||
@@ -207,7 +207,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
let recipient = RoomMemberProxyMock.mockDan
|
let recipient = RoomMemberProxyMock.mockDan
|
||||||
let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient]
|
let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient]
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.ignoreUserReturnValue = .failure(.failedIgnoringUser)
|
clientProxy.ignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
||||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||||
clientProxy: clientProxy,
|
clientProxy: clientProxy,
|
||||||
@@ -276,7 +276,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
|||||||
let recipient = RoomMemberProxyMock.mockIgnored
|
let recipient = RoomMemberProxyMock.mockIgnored
|
||||||
let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient]
|
let mockedMembers: [RoomMemberProxyMock] = [.mockMe, recipient]
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.unignoreUserReturnValue = .failure(.failedUnignoringUser)
|
clientProxy.unignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
roomProxyMock = RoomProxyMock(with: .init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
||||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||||
clientProxy: clientProxy,
|
clientProxy: clientProxy,
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class RoomMemberDetailsViewModelTests: XCTestCase {
|
|||||||
func testIgnoreFailure() async throws {
|
func testIgnoreFailure() async throws {
|
||||||
roomMemberProxyMock = RoomMemberProxyMock.mockAlice
|
roomMemberProxyMock = RoomMemberProxyMock.mockAlice
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.ignoreUserReturnValue = .failure(.failedIgnoringUser)
|
clientProxy.ignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID,
|
viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID,
|
||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
clientProxy: clientProxy,
|
clientProxy: clientProxy,
|
||||||
@@ -158,7 +158,7 @@ class RoomMemberDetailsViewModelTests: XCTestCase {
|
|||||||
func testUnignoreFailure() async throws {
|
func testUnignoreFailure() async throws {
|
||||||
roomMemberProxyMock = RoomMemberProxyMock.mockIgnored
|
roomMemberProxyMock = RoomMemberProxyMock.mockIgnored
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.unignoreUserReturnValue = .failure(.failedUnignoringUser)
|
clientProxy.unignoreUserReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID,
|
viewModel = RoomMemberDetailsScreenViewModel(userID: roomMemberProxyMock.userID,
|
||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
clientProxy: clientProxy,
|
clientProxy: clientProxy,
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class UserDiscoveryServiceTest: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testLocalResultShowsOnSearchError() async {
|
func testLocalResultShowsOnSearchError() async {
|
||||||
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.failedSearchingUsers)
|
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
|
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
|
||||||
|
|
||||||
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
||||||
@@ -81,7 +81,7 @@ class UserDiscoveryServiceTest: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testSearchErrorTriggers() async {
|
func testSearchErrorTriggers() async {
|
||||||
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.failedSearchingUsers)
|
clientProxy.searchUsersSearchTermLimitReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
|
clientProxy.profileForReturnValue = .success(.init(userID: "@some:matrix.org"))
|
||||||
|
|
||||||
switch await search(query: "some query") {
|
switch await search(query: "some query") {
|
||||||
@@ -108,7 +108,7 @@ class UserDiscoveryServiceTest: XCTestCase {
|
|||||||
|
|
||||||
func testSearchResultsShowWhenGetProfileFails() async {
|
func testSearchResultsShowWhenGetProfileFails() async {
|
||||||
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
|
clientProxy.searchUsersSearchTermLimitReturnValue = .success(.init(results: searchResults, limited: true))
|
||||||
clientProxy.profileForReturnValue = .failure(.failedGettingUserProfile)
|
clientProxy.profileForReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||||
|
|
||||||
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
let results = await (try? search(query: "@a:b.com").get()) ?? []
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user