diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 3d5114fb1..2839fad60 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -869,6 +869,7 @@ D1EEF0CB0F5D9C15E224E670 /* landscape_test_video.mov in Resources */ = {isa = PBXBuildFile; fileRef = 9A2AC7BE17C05CF7D2A22338 /* landscape_test_video.mov */; }; D2048FD56760BDABA3DB5FC2 /* AppLockServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26EAAB54C6CE91D64B69A9F8 /* AppLockServiceProtocol.swift */; }; D2825E013A8ECFB66D9A1DE6 /* RoomChangeRolesScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F841F219ACDFC1D3F42FEFB /* RoomChangeRolesScreenViewModelTests.swift */; }; + D29E046C1E3045E0346C479D /* RoomRolesAndPermissionsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45571C2EBD98ED7E0CEA7AF7 /* RoomRolesAndPermissionsUITests.swift */; }; D2D70B5DB1A5E4AF0CD88330 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 033DB41C51865A2E83174E87 /* target.yml */; }; D33AC79A50DFC26D2498DD28 /* FileRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5098DA7799946A61E34A2373 /* FileRoomTimelineItem.swift */; }; D34E328E9E65904358248FDD /* GlobalSearchScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436A0D98D372B17EAE9AA999 /* GlobalSearchScreenModels.swift */; }; @@ -901,6 +902,7 @@ DC08ADC41E792086A340A8B3 /* AccessibilityIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */; }; DC1BB5EE5F4D9B6A1F98A77A /* WelcomeScreenScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC2E8E1B20BB2EA07B0B61E /* WelcomeScreenScreenViewModel.swift */; }; DC68E866D6E664B0D2B06E74 /* MockImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */; }; + DC77E9DB2CFBE84A2BDF20C5 /* RoomRolesAndPermissionsFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0833F51229E166BCA141D004 /* RoomRolesAndPermissionsFlowCoordinator.swift */; }; DDB47D29C6865669288BF87C /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; }; DDFBDEE1DC32BDD5488F898C /* ClientProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F96CCBEAAA7F2185BFA354 /* ClientProxyMock.swift */; }; DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */; }; @@ -1137,6 +1139,7 @@ 07579F9C29001E40715F3014 /* NotificationSettingsChatType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsChatType.swift; sourceTree = ""; }; 077D7C3BE199B6E5DDEC07EC /* AppCoordinatorStateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinatorStateMachine.swift; sourceTree = ""; }; 08283301736A6FE9D558B2CB /* AppLockScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenViewModelProtocol.swift; sourceTree = ""; }; + 0833F51229E166BCA141D004 /* RoomRolesAndPermissionsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomRolesAndPermissionsFlowCoordinator.swift; sourceTree = ""; }; 086B997409328F091EBA43CE /* RoomScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenUITests.swift; sourceTree = ""; }; 086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentViewModelTests.swift; sourceTree = ""; }; 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineProviderProtocol.swift; sourceTree = ""; }; @@ -1381,6 +1384,7 @@ 4525E8C0FBDD27D1ACE90952 /* SecureBackupKeyBackupScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenViewModelProtocol.swift; sourceTree = ""; }; 4549FCB53F43DB0B278374BC /* TemplateScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreen.swift; sourceTree = ""; }; 4552D3466B1453F287223ADA /* SwipeRightAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeRightAction.swift; sourceTree = ""; }; + 45571C2EBD98ED7E0CEA7AF7 /* RoomRolesAndPermissionsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomRolesAndPermissionsUITests.swift; sourceTree = ""; }; 45CDF9A107BFE6C79B58D6B5 /* RoomMembersListScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenViewModelProtocol.swift; sourceTree = ""; }; 45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationCenterProtocol.swift; sourceTree = ""; }; 466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenModels.swift; sourceTree = ""; }; @@ -3167,6 +3171,7 @@ 0DBB08A95EFA668F2CF27211 /* AppLockSetupFlowCoordinator.swift */, 7367B3B9A8CAF902220F31D1 /* BugReportFlowCoordinator.swift */, 9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */, + 0833F51229E166BCA141D004 /* RoomRolesAndPermissionsFlowCoordinator.swift */, D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */, C99FDEEB71173C4C6FA2734C /* UserSessionFlowCoordinator.swift */, E8774CF614849664B5B3C2A1 /* UserSessionFlowCoordinatorStateMachine.swift */, @@ -3986,6 +3991,7 @@ C5B7A755E985FA14469E86B2 /* RoomMembersListScreenUITests.swift */, 66901977F6469D03C333DF32 /* RoomNotificationSettingsScreenUITests.swift */, 0D147EB979902DBBE452EADC /* RoomPollsHistoryScreenUITests.swift */, + 45571C2EBD98ED7E0CEA7AF7 /* RoomRolesAndPermissionsUITests.swift */, 086B997409328F091EBA43CE /* RoomScreenUITests.swift */, 58DCB219D7B7B0299358FF81 /* SecureBackupKeyBackupScreenUITests.swift */, 1CC09F30B0E1010951952BDC /* SecureBackupLogoutConfirmationScreenUITests.swift */, @@ -6112,6 +6118,7 @@ 4FC1EFE4968A259CBBACFAFB /* RoomProxy.swift in Sources */, BD203FC6A7AE7637EA003643 /* RoomProxyMock.swift in Sources */, FA9C427FFB11B1AA2DCC5602 /* RoomProxyProtocol.swift in Sources */, + DC77E9DB2CFBE84A2BDF20C5 /* RoomRolesAndPermissionsFlowCoordinator.swift in Sources */, D10BA4F041DC58580A440A32 /* RoomRolesAndPermissionsScreen.swift in Sources */, B13774779EA19FDD7A35A4A8 /* RoomRolesAndPermissionsScreenCoordinator.swift in Sources */, 8358D145F9BF94F412BEDCA8 /* RoomRolesAndPermissionsScreenModels.swift in Sources */, @@ -6386,6 +6393,7 @@ 44121202B4A260C98BF615A7 /* RoomMembersListScreenUITests.swift in Sources */, 06AA515C7053FD7E17A5CF81 /* RoomNotificationSettingsScreenUITests.swift in Sources */, 835B7AD20407F766C747BEC5 /* RoomPollsHistoryScreenUITests.swift in Sources */, + D29E046C1E3045E0346C479D /* RoomRolesAndPermissionsUITests.swift in Sources */, 2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */, A743841F91B62B0E56217B04 /* SecureBackupKeyBackupScreenUITests.swift in Sources */, F421FD5979EF53C8204BDC77 /* SecureBackupLogoutConfirmationScreenUITests.swift in Sources */, diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index ea3f41e31..8e12456f5 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -50,6 +50,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { private let analytics: AnalyticsService private let userIndicatorController: UserIndicatorControllerProtocol + private var rolesAndPermissionsFlowCoordinator: RoomRolesAndPermissionsFlowCoordinator? + private let stateMachine: StateMachine = .init(state: .initial) private var cancellables = Set() @@ -225,6 +227,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case (.pollsHistoryForm(let roomID), .dismissPollForm): return .pollsHistory(roomID: roomID) + case (.roomDetails(let roomID, _), .presentRolesAndPermissionsScreen): + return .rolesAndPermissions(roomID: roomID) + case (.rolesAndPermissions(let roomID), .dismissRolesAndPermissionsScreen): + return .roomDetails(roomID: roomID, isRoot: false) + default: return nil } @@ -343,6 +350,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case (.pollsHistoryForm, .dismissPollForm, .pollsHistory): break + case (.roomDetails, .presentRolesAndPermissionsScreen, .rolesAndPermissions): + presentRolesAndPermissionsScreen() + case (.rolesAndPermissions, .dismissRolesAndPermissionsScreen, .roomDetails): + break + default: fatalError("Unknown transition: \(context)") } @@ -527,7 +539,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { userIndicatorController: userIndicatorController, notificationSettings: userSession.clientProxy.notificationSettings, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: appSettings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: appSettings) let coordinator = RoomDetailsScreenCoordinator(parameters: params) coordinator.actions.sink { [weak self] action in guard let self else { return } @@ -545,6 +558,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { stateMachine.tryEvent(.presentInviteUsersScreen) case .presentPollsHistory: stateMachine.tryEvent(.presentPollsHistory) + case .presentRolesAndPermissionsScreen: + stateMachine.tryEvent(.presentRolesAndPermissionsScreen) } } .store(in: &cancellables) @@ -1155,6 +1170,25 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { message: L10n.commonUnableToInviteMessage) } } + + private func presentRolesAndPermissionsScreen() { + guard let roomProxy else { fatalError() } + + let parameters = RoomRolesAndPermissionsFlowCoordinatorParameters(roomProxy: roomProxy, + navigationStackCoordinator: navigationStackCoordinator, + userIndicatorController: userIndicatorController) + let coordinator = RoomRolesAndPermissionsFlowCoordinator(parameters: parameters) + coordinator.actionsPublisher.sink { [weak self] action in + switch action { + case .complete: + self?.rolesAndPermissionsFlowCoordinator = nil + } + } + .store(in: &cancellables) + + rolesAndPermissionsFlowCoordinator = coordinator + coordinator.start() + } } private extension RoomFlowCoordinator { @@ -1189,6 +1223,7 @@ private extension RoomFlowCoordinator { case pollForm(roomID: String) case pollsHistory(roomID: String) case pollsHistoryForm(roomID: String) + case rolesAndPermissions(roomID: String) } struct EventUserInfo { @@ -1244,6 +1279,9 @@ private extension RoomFlowCoordinator { case presentPollsHistory case dismissPollsHistory + + case presentRolesAndPermissionsScreen + case dismissRolesAndPermissionsScreen } } diff --git a/ElementX/Sources/FlowCoordinators/RoomRolesAndPermissionsFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomRolesAndPermissionsFlowCoordinator.swift new file mode 100644 index 000000000..f52d105dc --- /dev/null +++ b/ElementX/Sources/FlowCoordinators/RoomRolesAndPermissionsFlowCoordinator.swift @@ -0,0 +1,190 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Combine +import Foundation +import SwiftState + +enum RoomRolesAndPermissionsFlowCoordinatorAction: Equatable { + /// The flow is complete. + case complete +} + +struct RoomRolesAndPermissionsFlowCoordinatorParameters { + let roomProxy: RoomProxyProtocol + let navigationStackCoordinator: NavigationStackCoordinator + let userIndicatorController: UserIndicatorControllerProtocol +} + +class RoomRolesAndPermissionsFlowCoordinator: FlowCoordinatorProtocol { + private let roomProxy: RoomProxyProtocol + private let navigationStackCoordinator: NavigationStackCoordinator + private let userIndicatorController: UserIndicatorControllerProtocol + + enum State: StateType { + /// The state machine hasn't started. + case initial + /// The root screen for this flow. + case rolesAndPermissionsScreen + /// Changing member roles. + case changingRoles + /// Changing room permissions. + case changingPermissions + } + + enum Event: EventType { + /// The flow is being started. + case start + /// The user would like to change member roles. + case changeRoles + /// The user finished changing member roles. + case finishedChangingRoles + /// The user would like to change room permissions. + case changePermissions + /// The user finished changing room permissions + case finishedChangingPermissions + } + + private let stateMachine: StateMachine + private var cancellables: Set = [] + + private let actionsSubject: PassthroughSubject = .init() + var actionsPublisher: AnyPublisher { + actionsSubject.eraseToAnyPublisher() + } + + init(parameters: RoomRolesAndPermissionsFlowCoordinatorParameters) { + roomProxy = parameters.roomProxy + navigationStackCoordinator = parameters.navigationStackCoordinator + userIndicatorController = parameters.userIndicatorController + + stateMachine = .init(state: .initial) + configureStateMachine() + } + + func start() { + stateMachine.tryEvent(.start) + } + + func handleAppRoute(_ appRoute: AppRoute, animated: Bool) { + // There aren't any routes to this screen, so always clear the stack. + clearRoute(animated: animated) + } + + func clearRoute(animated: Bool) { + // As we push screens on top of an existing stack, popping to root wouldn't be safe. + switch stateMachine.state { + case .initial: + break + case .rolesAndPermissionsScreen: + navigationStackCoordinator.pop(animated: animated) + case .changingRoles, .changingPermissions: + navigationStackCoordinator.pop(animated: animated) // ChangeRoles or ChangePermissions screen. + navigationStackCoordinator.pop(animated: animated) // RolesAndPermissions screen. + } + } + + // MARK: - Private + + private func configureStateMachine() { + stateMachine.addRoutes(event: .start, transitions: [.initial => .rolesAndPermissionsScreen]) { [weak self] _ in + self?.presentRolesAndPermissionsScreen() + } + + stateMachine.addRoutes(event: .changeRoles, transitions: [.rolesAndPermissionsScreen => .changingRoles]) { [weak self] context in + guard let role = context.userInfo as? RoomRolesAndPermissionsScreenRole else { fatalError("Expected a role") } + self?.presentChangeRolesScreen(role: role) + } + stateMachine.addRoutes(event: .finishedChangingRoles, transitions: [.changingRoles => .rolesAndPermissionsScreen]) + + stateMachine.addRoutes(event: .changePermissions, transitions: [.rolesAndPermissionsScreen => .changingPermissions]) { [weak self] context in + guard let (group, permissions) = context.userInfo as? (RoomRolesAndPermissionsScreenPermissionsGroup, RoomPermissions) else { + fatalError("Expected a group and the current permissions") + } + self?.presentChangePermissionsScreen(permissions: permissions, group: group) + } + stateMachine.addRoutes(event: .finishedChangingPermissions, transitions: [.changingPermissions => .rolesAndPermissionsScreen]) + + stateMachine.addErrorHandler { context in + fatalError("Unexpected transition: \(context)") + } + } + + private func presentRolesAndPermissionsScreen() { + let parameters = RoomRolesAndPermissionsScreenCoordinatorParameters(roomProxy: roomProxy) + let coordinator = RoomRolesAndPermissionsScreenCoordinator(parameters: parameters) + coordinator.actions.sink { [stateMachine] action in + switch action { + case .editRoles(let role): + stateMachine.tryEvent(.changeRoles, userInfo: role) + case .editPermissions(let group): + stateMachine.tryEvent(.changePermissions, userInfo: (group, RoomPermissions.default)) + } + } + .store(in: &cancellables) + + navigationStackCoordinator.push(coordinator) { [weak self] in + self?.actionsSubject.send(.complete) + } + } + + private func presentChangeRolesScreen(role: RoomRolesAndPermissionsScreenRole) { + let mode = switch role { + case .administrators: RoomMemberDetails.Role.administrator + case .moderators: RoomMemberDetails.Role.moderator + } + + let parameters = RoomChangeRolesScreenCoordinatorParameters(mode: mode, + roomProxy: roomProxy, + userIndicatorController: userIndicatorController) + let coordinator = RoomChangeRolesScreenCoordinator(parameters: parameters) + coordinator.actionsPublisher.sink { [weak self] action in + guard let self else { return } + switch action { + case .done: + // When discarding changes is finalised, either use an event or remove this action. + navigationStackCoordinator.pop() + } + } + .store(in: &cancellables) + + navigationStackCoordinator.push(coordinator) { [stateMachine] in + stateMachine.tryEvent(.finishedChangingRoles) + } + } + + private func presentChangePermissionsScreen(permissions: RoomPermissions, group: RoomRolesAndPermissionsScreenPermissionsGroup) { + let parameters = RoomChangePermissionsScreenCoordinatorParameters(permissions: permissions, + permissionsGroup: group, + roomProxy: roomProxy, + userIndicatorController: userIndicatorController) + let coordinator = RoomChangePermissionsScreenCoordinator(parameters: parameters) + coordinator.actionsPublisher.sink { [weak self] action in + guard let self else { return } + + switch action { + case .cancel: + // When discarding changes is finalised, either use an event or remove this action. + navigationStackCoordinator.pop() + } + } + .store(in: &cancellables) + + navigationStackCoordinator.push(coordinator) { [stateMachine] in + stateMachine.tryEvent(.finishedChangingPermissions) + } + } +} diff --git a/ElementX/Sources/Other/AccessibilityIdentifiers.swift b/ElementX/Sources/Other/AccessibilityIdentifiers.swift index 2dec3ab73..5029744f2 100644 --- a/ElementX/Sources/Other/AccessibilityIdentifiers.swift +++ b/ElementX/Sources/Other/AccessibilityIdentifiers.swift @@ -32,6 +32,7 @@ enum A11yIdentifiers { static let roomScreen = RoomScreen() static let roomDetailsScreen = RoomDetailsScreen() static let roomNotificationSettingsScreen = RoomNotificationSettingsScreen() + static let roomRolesAndPermissionsScreen = RoomRolesAndPermissionsScreen() static let serverConfirmationScreen = ServerConfirmationScreen() static let sessionVerificationScreen = SessionVerificationScreen() static let settingsScreen = SettingsScreen() @@ -185,6 +186,14 @@ enum A11yIdentifiers { let allowCustomSetting = "room_notification_settings-allow_custom" } + struct RoomRolesAndPermissionsScreen { + let administrators = "room_roles_and_permissions-administrators" + let moderators = "room_roles_and_permissions-moderators" + let roomDetails = "room_roles_and_permissions-room_details" + let messagesAndContent = "room_roles_and_permissions-messages_and_content" + let memberModeration = "room_roles_and_permissions-member_moderation" + } + struct ServerConfirmationScreen { let `continue` = "server_confirmation-continue" let changeServer = "server_confirmation-change_server" diff --git a/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenCoordinator.swift b/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenCoordinator.swift index 0e1bcda37..e20800868 100644 --- a/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenCoordinator.swift @@ -33,10 +33,10 @@ enum RoomChangePermissionsScreenCoordinatorAction { final class RoomChangePermissionsScreenCoordinator: CoordinatorProtocol { private let parameters: RoomChangePermissionsScreenCoordinatorParameters private var viewModel: RoomChangePermissionsScreenViewModelProtocol - private let actionsSubject: PassthroughSubject = .init() private var cancellables = Set() - var actions: AnyPublisher { + private let actionsSubject: PassthroughSubject = .init() + var actionsPublisher: AnyPublisher { actionsSubject.eraseToAnyPublisher() } @@ -50,7 +50,7 @@ final class RoomChangePermissionsScreenCoordinator: CoordinatorProtocol { } func start() { - viewModel.actions.sink { [weak self] action in + viewModel.actionsPublisher.sink { [weak self] action in MXLog.info("Coordinator: received view model action: \(action)") guard let self else { return } diff --git a/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModel.swift b/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModel.swift index a1a06def5..1469bf7ec 100644 --- a/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModel.swift @@ -24,7 +24,7 @@ class RoomChangePermissionsScreenViewModel: RoomChangePermissionsScreenViewModel let userIndicatorController: UserIndicatorControllerProtocol private var actionsSubject: PassthroughSubject = .init() - var actions: AnyPublisher { + var actionsPublisher: AnyPublisher { actionsSubject.eraseToAnyPublisher() } diff --git a/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModelProtocol.swift b/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModelProtocol.swift index 3882f6222..33c6cf6bd 100644 --- a/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModelProtocol.swift +++ b/ElementX/Sources/Screens/RoomChangePermissionsScreen/RoomChangePermissionsScreenViewModelProtocol.swift @@ -18,6 +18,6 @@ import Combine @MainActor protocol RoomChangePermissionsScreenViewModelProtocol { - var actions: AnyPublisher { get } + var actionsPublisher: AnyPublisher { get } var context: RoomChangePermissionsScreenViewModelType.Context { get } } diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift index b26fb2b66..60b18400c 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift @@ -25,6 +25,7 @@ struct RoomDetailsScreenCoordinatorParameters { let userIndicatorController: UserIndicatorControllerProtocol let notificationSettings: NotificationSettingsProxyProtocol let attributedStringBuilder: AttributedStringBuilderProtocol + let appSettings: AppSettings } enum RoomDetailsScreenCoordinatorAction { @@ -34,6 +35,7 @@ enum RoomDetailsScreenCoordinatorAction { case presentNotificationSettingsScreen case presentInviteUsersScreen case presentPollsHistory + case presentRolesAndPermissionsScreen } final class RoomDetailsScreenCoordinator: CoordinatorProtocol { @@ -53,7 +55,8 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol { analyticsService: parameters.analyticsService, userIndicatorController: parameters.userIndicatorController, notificationSettingsProxy: parameters.notificationSettings, - attributedStringBuilder: parameters.attributedStringBuilder) + attributedStringBuilder: parameters.attributedStringBuilder, + appSettings: parameters.appSettings) } // MARK: - Public @@ -76,6 +79,8 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.presentNotificationSettingsScreen) case .requestPollsHistoryPresentation: actionsSubject.send(.presentPollsHistory) + case .requestRolesAndPermissionsPresentation: + actionsSubject.send(.presentRolesAndPermissionsScreen) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift index 17f904662..177150bf0 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift @@ -28,6 +28,7 @@ enum RoomDetailsScreenViewModelAction { case leftRoom case requestEditDetailsPresentation case requestPollsHistoryPresentation + case requestRolesAndPermissionsPresentation } // MARK: View @@ -47,6 +48,7 @@ struct RoomDetailsScreenViewState: BindableState { var canEditRoomName = false var canEditRoomTopic = false var canEditRoomAvatar = false + var canEditRolesOrPermissions = false var notificationSettingsState: RoomDetailsNotificationSettingsState = .loading var canEdit: Bool { @@ -177,10 +179,11 @@ enum RoomDetailsScreenViewAction { case ignoreConfirmed case unignoreConfirmed case processTapNotifications - case processToogleMuteNotifications + case processToggleMuteNotifications case displayAvatar case processTapPolls case toggleFavourite(isFavourite: Bool) + case processTapRolesAndPermissions } enum RoomDetailsScreenViewShortcut { diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift index 812b391a1..705d02761 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift @@ -27,6 +27,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr private let userIndicatorController: UserIndicatorControllerProtocol private let notificationSettingsProxy: NotificationSettingsProxyProtocol private let attributedStringBuilder: AttributedStringBuilderProtocol + private let appSettings: AppSettings private var dmRecipient: RoomMemberProxyProtocol? @@ -42,7 +43,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr analyticsService: AnalyticsService, userIndicatorController: UserIndicatorControllerProtocol, notificationSettingsProxy: NotificationSettingsProxyProtocol, - attributedStringBuilder: AttributedStringBuilderProtocol) { + attributedStringBuilder: AttributedStringBuilderProtocol, + appSettings: AppSettings) { self.roomProxy = roomProxy self.clientProxy = clientProxy self.mediaProvider = mediaProvider @@ -50,6 +52,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr self.userIndicatorController = userIndicatorController self.notificationSettingsProxy = notificationSettingsProxy self.attributedStringBuilder = attributedStringBuilder + self.appSettings = appSettings let topic = attributedStringBuilder.fromPlain(roomProxy.topic) @@ -111,7 +114,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr } else { actionsSubject.send(.requestNotificationSettingsPresentation) } - case .processToogleMuteNotifications: + case .processToggleMuteNotifications: Task { await toggleMuteNotifications() } case .displayAvatar: displayFullScreenAvatar() @@ -119,6 +122,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr actionsSubject.send(.requestPollsHistoryPresentation) case .toggleFavourite(let isFavourite): Task { await toggleFavourite(isFavourite) } + case .processTapRolesAndPermissions: + actionsSubject.send(.requestRolesAndPermissionsPresentation) } } @@ -172,6 +177,9 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr state.canEditRoomName = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName) == .success(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 { + state.canEditRolesOrPermissions = await roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomPowerLevels) == .success(true) + } state.canInviteUsers = await canInviteUsers } diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift index 2e8fb33a6..76e3e09d4 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift @@ -32,7 +32,7 @@ struct RoomDetailsScreen: View { topicSection - notificationSection + configurationSection aboutSection @@ -169,7 +169,7 @@ struct RoomDetailsScreen: View { } } - private var notificationSection: some View { + private var configurationSection: some View { Section { ListRow(label: .default(title: L10n.screenRoomDetailsNotificationTitle, icon: \.notifications), @@ -188,13 +188,21 @@ struct RoomDetailsScreen: View { .onChange(of: context.isFavourite) { newValue in context.send(viewAction: .toggleFavourite(isFavourite: newValue)) } + + if context.viewState.canEditRolesOrPermissions, context.viewState.dmRecipient == nil { + ListRow(label: .default(title: L10n.screenRoomDetailsRolesAndPermissions, + icon: \.admin), + kind: .navigationLink { + context.send(viewAction: .processTapRolesAndPermissions) + }) + } } .disabled(context.viewState.notificationSettingsState.isLoading) } private var toggleMuteButton: some View { Button { - context.send(viewAction: .processToogleMuteNotifications) + context.send(viewAction: .processToggleMuteNotifications) } label: { if context.viewState.isProcessingMuteToggleAction { ProgressView() @@ -311,7 +319,8 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: notificationSettingsProxy, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) }() static let dmRoomViewModel = { @@ -337,7 +346,8 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: notificationSettingsProxy, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) }() static let simpleRoomViewModel = { @@ -362,7 +372,8 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: notificationSettingsProxy, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: .userDirectory, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) }() static var previews: some View { diff --git a/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenModels.swift b/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenModels.swift index ab94bc926..6c24538a7 100644 --- a/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenModels.swift +++ b/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenModels.swift @@ -28,6 +28,7 @@ struct RoomRolesAndPermissionsScreenViewState: BindableState { enum RoomRolesAndPermissionsScreenViewAction { case editRoles(RoomRolesAndPermissionsScreenRole) + case editOwnUserRole case editPermissions(RoomRolesAndPermissionsScreenPermissionsGroup) case reset } diff --git a/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenViewModel.swift b/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenViewModel.swift index 722e4c3ab..41da99382 100644 --- a/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/RoomRolesAndPermissionsScreenViewModel.swift @@ -47,6 +47,8 @@ class RoomRolesAndPermissionsScreenViewModel: RoomRolesAndPermissionsScreenViewM switch viewAction { case .editRoles(let role): actionsSubject.send(.editRoles(role)) + case .editOwnUserRole: + break case .editPermissions(let permissionsGroup): actionsSubject.send(.editPermissions(permissionsGroup)) case .reset: diff --git a/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/View/RoomRolesAndPermissionsScreen.swift b/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/View/RoomRolesAndPermissionsScreen.swift index 7f73826b4..ab9adbd07 100644 --- a/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/View/RoomRolesAndPermissionsScreen.swift +++ b/ElementX/Sources/Screens/RoomRolesAndPermissionsScreen/View/RoomRolesAndPermissionsScreen.swift @@ -40,6 +40,7 @@ struct RoomRolesAndPermissionsScreen: View { kind: .navigationLink { context.send(viewAction: .editRoles(.administrators)) }) + .accessibilityIdentifier(A11yIdentifiers.roomRolesAndPermissionsScreen.administrators) ListRow(label: .default(title: L10n.screenRoomRolesAndPermissionsModerators, icon: \.chatProblem), @@ -47,6 +48,13 @@ struct RoomRolesAndPermissionsScreen: View { kind: .navigationLink { context.send(viewAction: .editRoles(.moderators)) }) + .accessibilityIdentifier(A11yIdentifiers.roomRolesAndPermissionsScreen.moderators) + + ListRow(label: .default(title: L10n.screenRoomRolesAndPermissionsChangeMyRole, + icon: \.edit), + kind: .button { + context.send(viewAction: .editOwnUserRole) + }) } header: { Text(L10n.screenRoomRolesAndPermissionsRolesHeader) .compoundListSectionHeader() @@ -76,18 +84,21 @@ struct RoomRolesAndPermissionsScreen: View { kind: .navigationLink { context.send(viewAction: .editPermissions(.roomDetails)) }) + .accessibilityIdentifier(A11yIdentifiers.roomRolesAndPermissionsScreen.roomDetails) ListRow(label: .default(title: L10n.screenRoomRolesAndPermissionsMessagesAndContent, icon: \.chat), kind: .navigationLink { context.send(viewAction: .editPermissions(.messagesAndContent)) }) + .accessibilityIdentifier(A11yIdentifiers.roomRolesAndPermissionsScreen.messagesAndContent) ListRow(label: .default(title: L10n.screenRoomRolesAndPermissionsMemberModeration, icon: \.user), kind: .navigationLink { context.send(viewAction: .editPermissions(.memberModeration)) }) + .accessibilityIdentifier(A11yIdentifiers.roomRolesAndPermissionsScreen.memberModeration) } header: { Text(L10n.screenRoomRolesAndPermissionsPermissionsHeader) .compoundListSectionHeader() diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 860f33296..00d47eb51 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -595,7 +595,8 @@ class MockScreen: Identifiable { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettings: NotificationSettingsProxyMock(with: .init()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder()))) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenWithRoomAvatar: @@ -617,7 +618,8 @@ class MockScreen: Identifiable { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettings: NotificationSettingsProxyMock(with: .init()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder()))) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenWithEmptyTopic: @@ -640,7 +642,8 @@ class MockScreen: Identifiable { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettings: NotificationSettingsProxyMock(with: .init()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder()))) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenWithInvite: @@ -660,7 +663,8 @@ class MockScreen: Identifiable { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettings: NotificationSettingsProxyMock(with: .init()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder()))) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomDetailsScreenDmDetails: @@ -681,7 +685,8 @@ class MockScreen: Identifiable { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettings: NotificationSettingsProxyMock(with: .init()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder()))) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomEditDetails, .roomEditDetailsReadOnly: @@ -733,6 +738,15 @@ class MockScreen: Identifiable { displayAsUserDefinedRoomSettings: false)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator + case .roomRolesAndPermissionsFlow: + let navigationStackCoordinator = NavigationStackCoordinator() + navigationStackCoordinator.setRootCoordinator(BlankFormCoordinator()) + let coordinator = RoomRolesAndPermissionsFlowCoordinator(parameters: .init(roomProxy: RoomProxyMock(with: .init(members: .allMembersAsAdmin)), + navigationStackCoordinator: navigationStackCoordinator, + userIndicatorController: ServiceLocator.shared.userIndicatorController)) + retainedState.append(coordinator) + coordinator.start() + return navigationStackCoordinator case .reportContent: let navigationStackCoordinator = NavigationStackCoordinator() let coordinator = ReportContentScreenCoordinator(parameters: .init(eventID: "test", diff --git a/ElementX/Sources/UITests/UITestsScreenIdentifier.swift b/ElementX/Sources/UITests/UITestsScreenIdentifier.swift index bd9537d61..85d413410 100644 --- a/ElementX/Sources/UITests/UITestsScreenIdentifier.swift +++ b/ElementX/Sources/UITests/UITestsScreenIdentifier.swift @@ -73,6 +73,7 @@ enum UITestsScreenIdentifier: String { case roomMemberDetailsIgnoredUser case roomNotificationSettingsDefaultSetting case roomNotificationSettingsCustomSetting + case roomRolesAndPermissionsFlow case reportContent case startChat case startChatWithSearchResults diff --git a/PreviewTests/__Snapshots__/PreviewTests/test_roomRolesAndPermissionsScreen.1.png b/PreviewTests/__Snapshots__/PreviewTests/test_roomRolesAndPermissionsScreen.1.png index 9e0dab3c4..9a14fe3b5 100644 --- a/PreviewTests/__Snapshots__/PreviewTests/test_roomRolesAndPermissionsScreen.1.png +++ b/PreviewTests/__Snapshots__/PreviewTests/test_roomRolesAndPermissionsScreen.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb68d85ebb6e0b8300d0c6a2b99c2fdbefc56a4ff68d93c17705b675626c1f49 -size 135130 +oid sha256:8a15dfc94badf24dd06ab3ca1430d4e908b80366a786a4dfae02b2370c24136b +size 144793 diff --git a/UITests/Sources/RoomRolesAndPermissionsUITests.swift b/UITests/Sources/RoomRolesAndPermissionsUITests.swift new file mode 100644 index 000000000..38be24ed8 --- /dev/null +++ b/UITests/Sources/RoomRolesAndPermissionsUITests.swift @@ -0,0 +1,56 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +@MainActor +class RoomRolesAndPermissionsUITests: XCTestCase { + var app: XCUIApplication! + + @MainActor enum Step { + static let rolesAndPermissions = 0 + static let administratorsRole = 1 + static let moderatorsRole = 2 + static let roomDetailsPermissions = 3 + static let messagesAndContentPermissions = 4 + static let memberModerationPermissions = 5 + } + + func testFlow() async throws { + app = Application.launch(.roomRolesAndPermissionsFlow) + + try await app.assertScreenshot(.roomRolesAndPermissionsFlow, step: Step.rolesAndPermissions) + + app.buttons[A11yIdentifiers.roomRolesAndPermissionsScreen.administrators].tap() + try await app.assertScreenshot(.roomRolesAndPermissionsFlow, step: Step.administratorsRole) + app.navigationBars.buttons.element(boundBy: 0).tap() + + app.buttons[A11yIdentifiers.roomRolesAndPermissionsScreen.moderators].tap() + try await app.assertScreenshot(.roomRolesAndPermissionsFlow, step: Step.moderatorsRole) + app.navigationBars.buttons.element(boundBy: 0).tap() + + app.buttons[A11yIdentifiers.roomRolesAndPermissionsScreen.roomDetails].tap() + try await app.assertScreenshot(.roomRolesAndPermissionsFlow, step: Step.roomDetailsPermissions) + app.navigationBars.buttons.element(boundBy: 0).tap() + + app.buttons[A11yIdentifiers.roomRolesAndPermissionsScreen.messagesAndContent].tap() + try await app.assertScreenshot(.roomRolesAndPermissionsFlow, step: Step.messagesAndContentPermissions) + app.navigationBars.buttons.element(boundBy: 0).tap() + + app.buttons[A11yIdentifiers.roomRolesAndPermissionsScreen.memberModeration].tap() + try await app.assertScreenshot(.roomRolesAndPermissionsFlow, step: Step.memberModerationPermissions) + } +} diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-0.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-0.png new file mode 100644 index 000000000..45158ef3e --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56cf7b98d83fd41c0748a7ceff82b3bd39c766fa1a03e5eb3a1ad5c154f3569e +size 107293 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-1.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-1.png new file mode 100644 index 000000000..fa4fc134a --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c308bcee54de0745343888fbba4a3e81191210b9f94bd2321e078e6254f66ea +size 139455 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-2.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-2.png new file mode 100644 index 000000000..b6c1a4f44 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e6d8f7ec2e54e6a0e902fb6e8de29bce6f44466bd1c3ca184e628637d60d791 +size 141623 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-3.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-3.png new file mode 100644 index 000000000..652cff3e5 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9edb60aa8fe4f07da5e7ca1f44d5c461ec52e9c29b98b78a9abd9a01c2c89405 +size 112872 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-4.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-4.png new file mode 100644 index 000000000..0d9c8c0c5 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c25af572834b339745080f03d4ce2318a30f5f79ad37144b522aaa2b32d6833 +size 95336 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-5.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-5.png new file mode 100644 index 000000000..1ecb0e9bc --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomRolesAndPermissionsFlow-5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ce42b2995c72025759021035f7db3295adab3fe3a0c7b90e6e794cbf3ed8280 +size 108328 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-0.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-0.png new file mode 100644 index 000000000..b41e5b732 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e187115b066f0942cae48f685c0dc5d2cdc53e994cd1aef297d77db8c2a631c0 +size 131763 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-1.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-1.png new file mode 100644 index 000000000..eff258fe8 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f089620ba53ff2ca82906f3e0fb48e10d30c1361bf4fccfcd39da2ef94c39779 +size 166898 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-2.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-2.png new file mode 100644 index 000000000..c8a415d73 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:145d34a90da16c1832a0969c8ac5b3e5b0b7d4ece6f7ad9458f8130013c5122b +size 170216 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-3.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-3.png new file mode 100644 index 000000000..bf2864a25 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bfa92fc9e3318bde12337702904c8b5231daa362d810bc9623bb297990dbf02 +size 135469 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-4.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-4.png new file mode 100644 index 000000000..07e24afe0 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be5ada770c951e7483f2b1c101774e7e2077cc844eaf2013f2113ee3f3cab558 +size 109500 diff --git a/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-5.png b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-5.png new file mode 100644 index 000000000..e0d85cb53 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomRolesAndPermissionsFlow-5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae777a41147832977a16110115a37d6a9fd22105f8c9b0324fdb1c1ad27a37e9 +size 129864 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-0.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-0.png new file mode 100644 index 000000000..812c38724 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86357579aa94aac5c1d8843b06d9287b2aab0b758d6605d92a2c181f4805ac6b +size 116079 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-1.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-1.png new file mode 100644 index 000000000..688686887 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab199d1b69f3731c67f43a9b9bc54cbc00a31f41d084383de618e276eb8844e4 +size 140934 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-2.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-2.png new file mode 100644 index 000000000..b6efdcfc2 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e1dba096d136d86b03205791fd1a6fa5512d8eb05a4f794360dd7e82ce2f3a8 +size 143435 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-3.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-3.png new file mode 100644 index 000000000..8ae0779c2 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6b24eab850b3703a9dee828b7aa5fc5e458c3998889d4efea0dc043da63b7dc +size 125320 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-4.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-4.png new file mode 100644 index 000000000..6481c860e --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37640f16e3b52c138bffd571ef0567d673384131cc9c2a7a3fa703662b9dc58e +size 99735 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-5.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-5.png new file mode 100644 index 000000000..716f16018 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomRolesAndPermissionsFlow-5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39c2108b87d28348ccd596adb2cb36ef546f9bc785d7c1a3c321d236da6cdbdf +size 115426 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-0.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-0.png new file mode 100644 index 000000000..da14ac1f3 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31774d04e9f5e39f2d930e064e38cc1d0d258516104687e456b81755e06d02a2 +size 153398 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-1.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-1.png new file mode 100644 index 000000000..1424f1189 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1da36569570dcaa2aaf3fa00d1f9f4bd22e7bdf5dfb253c959b96064d21dd80e +size 169036 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-2.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-2.png new file mode 100644 index 000000000..5e5f26c0d --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:623c1782386ae300a2dc7f33d5c1480e84a947875a5c0af1d217b6098efa135c +size 172592 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-3.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-3.png new file mode 100644 index 000000000..6ec1f3cb7 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8013a8cb823b9c56e8fed84971e25ca21f9f31785e138b7e0d9767f81b29e936 +size 160126 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-4.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-4.png new file mode 100644 index 000000000..f79d815fe --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ddce2faa0548cb422fa3204725e96fbc1414f065e1b444fcf8cdac1e6df02c2 +size 124452 diff --git a/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-5.png b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-5.png new file mode 100644 index 000000000..dd4d2cb18 --- /dev/null +++ b/UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomRolesAndPermissionsFlow-5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8f4bab98b03214787e139597f3b255ee5abe9320035e0168ff12ab6927925e9 +size 152549 diff --git a/UnitTests/Sources/RoomDetailsViewModelTests.swift b/UnitTests/Sources/RoomDetailsViewModelTests.swift index 085d1d98d..0b21fdac8 100644 --- a/UnitTests/Sources/RoomDetailsViewModelTests.swift +++ b/UnitTests/Sources/RoomDetailsViewModelTests.swift @@ -40,7 +40,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: notificationSettingsProxyMock, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) AppSettings.reset() } @@ -55,7 +56,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) let deferred = deferFulfillment(context.$viewState) { state in state.bindings.leaveRoomAlertItem != nil } @@ -77,7 +79,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) let deferred = deferFulfillment(context.$viewState) { state in state.bindings.leaveRoomAlertItem != nil } @@ -100,7 +103,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) context.send(viewAction: .processTapLeave) XCTAssertEqual(context.leaveRoomAlertItem?.state, .empty) @@ -153,7 +157,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) let deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -176,7 +181,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -210,7 +216,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -243,7 +250,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -277,7 +285,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) var deferred = deferFulfillment(viewModel.context.$viewState) { state in state.dmRecipient != nil @@ -312,7 +321,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -329,7 +339,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -365,7 +376,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -388,7 +400,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -411,7 +424,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -431,7 +445,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -451,7 +466,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()), attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) _ = await context.$viewState.debounce(for: .milliseconds(100), scheduler: DispatchQueue.main).values.first() @@ -469,7 +485,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase { userIndicatorController: ServiceLocator.shared.userIndicatorController, notificationSettingsProxy: notificationSettingsProxyMock, attributedStringBuilder: AttributedStringBuilder(permalinkBaseURL: ServiceLocator.shared.settings.permalinkBaseURL, - mentionBuilder: MentionBuilder())) + mentionBuilder: MentionBuilder()), + appSettings: ServiceLocator.shared.settings) var deferred = deferFulfillment(context.$viewState) { state in state.notificationSettingsState.isError @@ -559,7 +576,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase { } throw NotificationSettingsError.Generic(msg: "unmute error") } - context.send(viewAction: .processToogleMuteNotifications) + context.send(viewAction: .processToggleMuteNotifications) await fulfillment(of: [expectation]) XCTAssertFalse(context.viewState.isProcessingMuteToggleAction) @@ -584,7 +601,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase { } throw NotificationSettingsError.Generic(msg: "mute error") } - context.send(viewAction: .processToogleMuteNotifications) + context.send(viewAction: .processToggleMuteNotifications) await fulfillment(of: [expectation]) XCTAssertFalse(context.viewState.isProcessingMuteToggleAction) @@ -607,7 +624,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase { notificationSettingsProxyMock?.getNotificationSettingsRoomIdIsEncryptedIsOneToOneReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: mode, isDefault: false)) expectation.fulfill() } - context.send(viewAction: .processToogleMuteNotifications) + context.send(viewAction: .processToggleMuteNotifications) await fulfillment(of: [expectation]) XCTAssertFalse(context.viewState.isProcessingMuteToggleAction) @@ -640,7 +657,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase { notificationSettingsProxyMock?.getNotificationSettingsRoomIdIsEncryptedIsOneToOneReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .allMessages, isDefault: false)) expectation.fulfill() } - context.send(viewAction: .processToogleMuteNotifications) + context.send(viewAction: .processToggleMuteNotifications) await fulfillment(of: [expectation]) XCTAssertFalse(context.viewState.isProcessingMuteToggleAction)