diff --git a/ElementX/Sources/Application/AppCoordinator.swift b/ElementX/Sources/Application/AppCoordinator.swift index 670bdf5b9..ba6f2f5fe 100644 --- a/ElementX/Sources/Application/AppCoordinator.swift +++ b/ElementX/Sources/Application/AppCoordinator.swift @@ -220,18 +220,18 @@ class AppCoordinator: AppCoordinatorProtocol { displayName = name } - let credentials = SoftLogoutCredentials(userId: userSession.userID, - homeserverName: userSession.homeserver, - userDisplayName: displayName, - deviceId: userSession.deviceID) + let credentials = SoftLogoutScreenCredentials(userId: userSession.userID, + homeserverName: userSession.homeserver, + userDisplayName: displayName, + deviceId: userSession.deviceID) let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore) _ = await authenticationService.configure(for: userSession.homeserver) - let parameters = SoftLogoutCoordinatorParameters(authenticationService: authenticationService, - credentials: credentials, - keyBackupNeeded: false) - let coordinator = SoftLogoutCoordinator(parameters: parameters) + let parameters = SoftLogoutScreenCoordinatorParameters(authenticationService: authenticationService, + credentials: credentials, + keyBackupNeeded: false) + let coordinator = SoftLogoutScreenCoordinator(parameters: parameters) coordinator.callback = { result in switch result { case .signedIn(let session): diff --git a/ElementX/Sources/Screens/Authentication/AuthenticationCoordinator.swift b/ElementX/Sources/Screens/Authentication/AuthenticationCoordinator.swift index 3b6a877d5..c1a083d15 100644 --- a/ElementX/Sources/Screens/Authentication/AuthenticationCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/AuthenticationCoordinator.swift @@ -72,10 +72,10 @@ class AuthenticationCoordinator: CoordinatorProtocol { } private func showServerSelectionScreen() { - let parameters = ServerSelectionCoordinatorParameters(authenticationService: authenticationService, - userIndicatorController: ServiceLocator.shared.userIndicatorController, - isModallyPresented: false) - let coordinator = ServerSelectionCoordinator(parameters: parameters) + let parameters = ServerSelectionScreenCoordinatorParameters(authenticationService: authenticationService, + userIndicatorController: ServiceLocator.shared.userIndicatorController, + isModallyPresented: false) + let coordinator = ServerSelectionScreenCoordinator(parameters: parameters) coordinator.callback = { [weak self] action in guard let self else { return } @@ -92,10 +92,10 @@ class AuthenticationCoordinator: CoordinatorProtocol { } private func showLoginScreen() { - let parameters = LoginCoordinatorParameters(authenticationService: authenticationService, - navigationStackCoordinator: navigationStackCoordinator) - let coordinator = LoginCoordinator(parameters: parameters) - + let parameters = LoginScreenCoordinatorParameters(authenticationService: authenticationService, + navigationStackCoordinator: navigationStackCoordinator) + let coordinator = LoginScreenCoordinator(parameters: parameters) + coordinator.callback = { [weak self] action in guard let self else { return } diff --git a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginCoordinator.swift b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenCoordinator.swift similarity index 88% rename from ElementX/Sources/Screens/Authentication/LoginScreen/LoginCoordinator.swift rename to ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenCoordinator.swift index e4f4770eb..cae2a931c 100644 --- a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenCoordinator.swift @@ -17,21 +17,21 @@ import AppAuth import SwiftUI -struct LoginCoordinatorParameters { +struct LoginScreenCoordinatorParameters { /// The service used to authenticate the user. let authenticationService: AuthenticationServiceProxyProtocol /// The navigation router used to present the server selection screen. let navigationStackCoordinator: NavigationStackCoordinator } -enum LoginCoordinatorAction { +enum LoginScreenCoordinatorAction { /// Login was successful. case signedIn(UserSessionProtocol) } -final class LoginCoordinator: CoordinatorProtocol { - private let parameters: LoginCoordinatorParameters - private var viewModel: LoginViewModelProtocol +final class LoginScreenCoordinator: CoordinatorProtocol { + private let parameters: LoginScreenCoordinatorParameters + private var viewModel: LoginScreenViewModelProtocol private let hostingController: UIViewController /// Passed to the OIDC service to provide a view controller from which to present the authentication session. private let oidcUserAgent: OIDExternalUserAgentIOS? @@ -45,14 +45,14 @@ final class LoginCoordinator: CoordinatorProtocol { private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService } private var navigationStackCoordinator: NavigationStackCoordinator { parameters.navigationStackCoordinator } - var callback: (@MainActor (LoginCoordinatorAction) -> Void)? + var callback: (@MainActor (LoginScreenCoordinatorAction) -> Void)? // MARK: - Setup - init(parameters: LoginCoordinatorParameters) { + init(parameters: LoginScreenCoordinatorParameters) { self.parameters = parameters - viewModel = LoginViewModel(homeserver: parameters.authenticationService.homeserver) + viewModel = LoginScreenViewModel(homeserver: parameters.authenticationService.homeserver) hostingController = UIHostingController(rootView: LoginScreen(context: viewModel.context)) oidcUserAgent = OIDExternalUserAgentIOS(presenting: hostingController) @@ -199,11 +199,11 @@ final class LoginCoordinator: CoordinatorProtocol { /// Presents the server selection screen as a modal. private func presentServerSelectionScreen() { - let parameters = ServerSelectionCoordinatorParameters(authenticationService: authenticationService, - userIndicatorController: ServiceLocator.shared.userIndicatorController, - isModallyPresented: false) + let parameters = ServerSelectionScreenCoordinatorParameters(authenticationService: authenticationService, + userIndicatorController: ServiceLocator.shared.userIndicatorController, + isModallyPresented: false) - let coordinator = ServerSelectionCoordinator(parameters: parameters) + let coordinator = ServerSelectionScreenCoordinator(parameters: parameters) coordinator.callback = { [weak self, weak coordinator] action in guard let self, let coordinator else { return } self.serverSelectionCoordinator(coordinator, didCompleteWith: action) @@ -213,8 +213,8 @@ final class LoginCoordinator: CoordinatorProtocol { } /// Handles the result from the server selection modal, dismissing it after updating the view. - private func serverSelectionCoordinator(_ coordinator: ServerSelectionCoordinator, - didCompleteWith action: ServerSelectionCoordinatorAction) { + private func serverSelectionCoordinator(_ coordinator: ServerSelectionScreenCoordinator, + didCompleteWith action: ServerSelectionScreenCoordinatorAction) { if action == .updated { updateViewModel() } diff --git a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginModels.swift b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenModels.swift similarity index 91% rename from ElementX/Sources/Screens/Authentication/LoginScreen/LoginModels.swift rename to ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenModels.swift index bb286c010..140974880 100644 --- a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginModels.swift +++ b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenModels.swift @@ -16,7 +16,7 @@ import Foundation -enum LoginViewModelAction: CustomStringConvertible { +enum LoginScreenViewModelAction: CustomStringConvertible { /// The user would like to select another server. case selectServer /// Parse the username and update the homeserver if included. @@ -45,13 +45,13 @@ enum LoginViewModelAction: CustomStringConvertible { } } -struct LoginViewState: BindableState { +struct LoginScreenViewState: BindableState { /// Data about the selected homeserver. var homeserver: LoginHomeserver /// Whether a new homeserver is currently being loaded. var isLoading = false /// View state that can be bound to from SwiftUI. - var bindings: LoginBindings + var bindings: LoginScreenBindings /// The types of login supported by the homeserver. var loginMode: LoginMode { homeserver.loginMode } @@ -67,16 +67,16 @@ struct LoginViewState: BindableState { } } -struct LoginBindings { +struct LoginScreenBindings { /// The username input by the user. var username = "" /// The password input by the user. var password = "" /// Information describing the currently displayed alert. - var alertInfo: AlertInfo? + var alertInfo: AlertInfo? } -enum LoginViewAction { +enum LoginScreenViewAction { /// The user would like to select another server. case selectServer /// Parse the username to detect if a homeserver is included. @@ -89,7 +89,7 @@ enum LoginViewAction { case continueWithOIDC } -enum LoginErrorType: Hashable { +enum LoginScreenErrorType: Hashable { /// A specific error message shown in an alert. case alert(String) /// Looking up the homeserver from the username failed. diff --git a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginViewModel.swift b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenViewModel.swift similarity index 84% rename from ElementX/Sources/Screens/Authentication/LoginScreen/LoginViewModel.swift rename to ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenViewModel.swift index 5a2668633..d327491e2 100644 --- a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginViewModel.swift +++ b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenViewModel.swift @@ -16,19 +16,19 @@ import SwiftUI -typealias LoginViewModelType = StateStoreViewModel +typealias LoginScreenViewModelType = StateStoreViewModel -class LoginViewModel: LoginViewModelType, LoginViewModelProtocol { - var callback: (@MainActor (LoginViewModelAction) -> Void)? +class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtocol { + var callback: (@MainActor (LoginScreenViewModelAction) -> Void)? init(homeserver: LoginHomeserver) { - let bindings = LoginBindings() - let viewState = LoginViewState(homeserver: homeserver, bindings: bindings) + let bindings = LoginScreenBindings() + let viewState = LoginScreenViewState(homeserver: homeserver, bindings: bindings) super.init(initialViewState: viewState) } - override func process(viewAction: LoginViewAction) { + override func process(viewAction: LoginScreenViewAction) { switch viewAction { case .selectServer: callback?(.selectServer) @@ -52,7 +52,7 @@ class LoginViewModel: LoginViewModelType, LoginViewModelProtocol { state.homeserver = homeserver } - func displayError(_ type: LoginErrorType) { + func displayError(_ type: LoginScreenErrorType) { switch type { case .alert(let message): state.bindings.alertInfo = AlertInfo(id: type, diff --git a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginViewModelProtocol.swift b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenViewModelProtocol.swift similarity index 83% rename from ElementX/Sources/Screens/Authentication/LoginScreen/LoginViewModelProtocol.swift rename to ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenViewModelProtocol.swift index 0143c8579..de61f098f 100644 --- a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginViewModelProtocol.swift +++ b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginScreenViewModelProtocol.swift @@ -17,9 +17,9 @@ import Foundation @MainActor -protocol LoginViewModelProtocol { - var callback: (@MainActor (LoginViewModelAction) -> Void)? { get set } - var context: LoginViewModelType.Context { get } +protocol LoginScreenViewModelProtocol { + var callback: (@MainActor (LoginScreenViewModelAction) -> Void)? { get set } + var context: LoginScreenViewModelType.Context { get } /// Update the view to reflect that a new homeserver is being loaded. /// - Parameter isLoading: Whether or not the homeserver is being loaded. @@ -31,5 +31,5 @@ protocol LoginViewModelProtocol { /// Display an error to the user. /// - Parameter type: The type of error to be displayed. - func displayError(_ type: LoginErrorType) + func displayError(_ type: LoginScreenErrorType) } diff --git a/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift b/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift index c9fa5c938..f6cc41e58 100644 --- a/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift +++ b/ElementX/Sources/Screens/Authentication/LoginScreen/View/LoginScreen.swift @@ -22,7 +22,7 @@ struct LoginScreen: View { /// The focus state of the password text field. @FocusState private var isPasswordFocused: Bool - @ObservedObject var context: LoginViewModel.Context + @ObservedObject var context: LoginScreenViewModel.Context var body: some View { ScrollView { @@ -146,26 +146,26 @@ struct LoginScreen: View { // MARK: - Previews -struct Login_Previews: PreviewProvider { - static let credentialsViewModel: LoginViewModel = { - let viewModel = LoginViewModel(homeserver: .mockMatrixDotOrg) +struct LoginScreen_Previews: PreviewProvider { + static let credentialsViewModel: LoginScreenViewModel = { + let viewModel = LoginScreenViewModel(homeserver: .mockMatrixDotOrg) viewModel.context.username = "alice" viewModel.context.password = "password" return viewModel }() static var previews: some View { - screen(for: LoginViewModel(homeserver: .mockMatrixDotOrg)) + screen(for: LoginScreenViewModel(homeserver: .mockMatrixDotOrg)) .previewDisplayName("matrix.org") screen(for: credentialsViewModel) .previewDisplayName("Credentials Entered") - screen(for: LoginViewModel(homeserver: .mockOIDC)) + screen(for: LoginScreenViewModel(homeserver: .mockOIDC)) .previewDisplayName("OIDC") - screen(for: LoginViewModel(homeserver: .mockUnsupported)) + screen(for: LoginScreenViewModel(homeserver: .mockUnsupported)) .previewDisplayName("Unsupported") } - static func screen(for viewModel: LoginViewModel) -> some View { + static func screen(for viewModel: LoginScreenViewModel) -> some View { NavigationStack { LoginScreen(context: viewModel.context) .navigationBarTitleDisplayMode(.inline) diff --git a/ElementX/Sources/Screens/Authentication/ServerSelection/MockServerSelectionScreenState.swift b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/MockServerSelectionScreenState.swift similarity index 59% rename from ElementX/Sources/Screens/Authentication/ServerSelection/MockServerSelectionScreenState.swift rename to ElementX/Sources/Screens/Authentication/ServerSelectionScreen/MockServerSelectionScreenState.swift index 60e53f4f7..e43a8a25e 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelection/MockServerSelectionScreenState.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/MockServerSelectionScreenState.swift @@ -23,22 +23,22 @@ enum MockServerSelectionScreenState: CaseIterable { case nonModal /// Generate the view struct for the screen state. - @MainActor var viewModel: ServerSelectionViewModel { + @MainActor var viewModel: ServerSelectionScreenViewModel { switch self { case .matrix: - return ServerSelectionViewModel(homeserverAddress: "https://matrix.org", - isModallyPresented: true) + return ServerSelectionScreenViewModel(homeserverAddress: "https://matrix.org", + isModallyPresented: true) case .emptyAddress: - return ServerSelectionViewModel(homeserverAddress: "", - isModallyPresented: true) + return ServerSelectionScreenViewModel(homeserverAddress: "", + isModallyPresented: true) case .invalidAddress: - let viewModel = ServerSelectionViewModel(homeserverAddress: "thisisbad", - isModallyPresented: true) + let viewModel = ServerSelectionScreenViewModel(homeserverAddress: "thisisbad", + isModallyPresented: true) viewModel.displayError(.footerMessage(L10n.errorUnknown)) return viewModel case .nonModal: - return ServerSelectionViewModel(homeserverAddress: "https://matrix.org", - isModallyPresented: false) + return ServerSelectionScreenViewModel(homeserverAddress: "https://matrix.org", + isModallyPresented: false) } } } diff --git a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionCoordinator.swift b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenCoordinator.swift similarity index 83% rename from ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionCoordinator.swift rename to ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenCoordinator.swift index 7ac923d23..801c58377 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenCoordinator.swift @@ -16,7 +16,7 @@ import SwiftUI -struct ServerSelectionCoordinatorParameters { +struct ServerSelectionScreenCoordinatorParameters { /// The service used to authenticate the user. let authenticationService: AuthenticationServiceProxyProtocol let userIndicatorController: UserIndicatorControllerProtocol @@ -24,23 +24,23 @@ struct ServerSelectionCoordinatorParameters { let isModallyPresented: Bool } -enum ServerSelectionCoordinatorAction { +enum ServerSelectionScreenCoordinatorAction { case updated case dismiss } -final class ServerSelectionCoordinator: CoordinatorProtocol { - private let parameters: ServerSelectionCoordinatorParameters +final class ServerSelectionScreenCoordinator: CoordinatorProtocol { + private let parameters: ServerSelectionScreenCoordinatorParameters private let userIndicatorController: UserIndicatorControllerProtocol - private var viewModel: ServerSelectionViewModelProtocol + private var viewModel: ServerSelectionScreenViewModelProtocol private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService } - var callback: (@MainActor (ServerSelectionCoordinatorAction) -> Void)? + var callback: (@MainActor (ServerSelectionScreenCoordinatorAction) -> Void)? - init(parameters: ServerSelectionCoordinatorParameters) { + init(parameters: ServerSelectionScreenCoordinatorParameters) { self.parameters = parameters - viewModel = ServerSelectionViewModel(homeserverAddress: parameters.authenticationService.homeserver.address, - isModallyPresented: parameters.isModallyPresented) + viewModel = ServerSelectionScreenViewModel(homeserverAddress: parameters.authenticationService.homeserver.address, + isModallyPresented: parameters.isModallyPresented) userIndicatorController = parameters.userIndicatorController } diff --git a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionModels.swift b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenModels.swift similarity index 89% rename from ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionModels.swift rename to ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenModels.swift index d02d45072..53ccb6ac5 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionModels.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenModels.swift @@ -16,14 +16,14 @@ import Foundation -enum ServerSelectionViewModelAction { +enum ServerSelectionScreenViewModelAction { /// The user would like to use the homeserver at the given address. case confirm(homeserverAddress: String) /// Dismiss the view without using the entered address. case dismiss } -struct ServerSelectionViewState: BindableState { +struct ServerSelectionScreenViewState: BindableState { /// The message to be shown in the text field footer when no error has occurred. private let regularFooterMessage = { let linkPlaceholder = "{link}" @@ -35,7 +35,7 @@ struct ServerSelectionViewState: BindableState { }() /// View state that can be bound to from SwiftUI. - var bindings: ServerSelectionBindings + var bindings: ServerSelectionScreenBindings /// An error message to be shown in the text field footer. var footerErrorMessage: String? /// Whether the screen is presented modally or within a navigation stack. @@ -62,14 +62,14 @@ struct ServerSelectionViewState: BindableState { } } -struct ServerSelectionBindings { +struct ServerSelectionScreenBindings { /// The homeserver address input by the user. var homeserverAddress: String /// Information describing the currently displayed alert. - var alertInfo: AlertInfo? + var alertInfo: AlertInfo? } -enum ServerSelectionViewAction { +enum ServerSelectionScreenViewAction { /// The user would like to use the homeserver at the input address. case confirm /// Dismiss the view without using the entered address. @@ -78,7 +78,7 @@ enum ServerSelectionViewAction { case clearFooterError } -enum ServerSelectionErrorType: Hashable { +enum ServerSelectionScreenErrorType: Hashable { /// An error message to be shown in the text field footer. case footerMessage(String) /// An alert that allows the user to learn about sliding sync. diff --git a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionViewModel.swift b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenViewModel.swift similarity index 73% rename from ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionViewModel.swift rename to ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenViewModel.swift index 0e96e9409..52866713e 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionViewModel.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenViewModel.swift @@ -16,19 +16,19 @@ import SwiftUI -typealias ServerSelectionViewModelType = StateStoreViewModel +typealias ServerSelectionScreenViewModelType = StateStoreViewModel -class ServerSelectionViewModel: ServerSelectionViewModelType, ServerSelectionViewModelProtocol { - var callback: (@MainActor (ServerSelectionViewModelAction) -> Void)? +class ServerSelectionScreenViewModel: ServerSelectionScreenViewModelType, ServerSelectionScreenViewModelProtocol { + var callback: (@MainActor (ServerSelectionScreenViewModelAction) -> Void)? init(homeserverAddress: String, isModallyPresented: Bool) { - let bindings = ServerSelectionBindings(homeserverAddress: homeserverAddress) + let bindings = ServerSelectionScreenBindings(homeserverAddress: homeserverAddress) - super.init(initialViewState: ServerSelectionViewState(bindings: bindings, - isModallyPresented: isModallyPresented)) + super.init(initialViewState: ServerSelectionScreenViewState(bindings: bindings, + isModallyPresented: isModallyPresented)) } - - override func process(viewAction: ServerSelectionViewAction) { + + override func process(viewAction: ServerSelectionScreenViewAction) { switch viewAction { case .confirm: callback?(.confirm(homeserverAddress: state.bindings.homeserverAddress)) @@ -39,7 +39,7 @@ class ServerSelectionViewModel: ServerSelectionViewModelType, ServerSelectionVie } } - func displayError(_ type: ServerSelectionErrorType) { + func displayError(_ type: ServerSelectionScreenErrorType) { switch type { case .footerMessage(let message): withElementAnimation { diff --git a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionViewModelProtocol.swift b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenViewModelProtocol.swift similarity index 71% rename from ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionViewModelProtocol.swift rename to ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenViewModelProtocol.swift index 999b18dd9..320b6f3da 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionViewModelProtocol.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenViewModelProtocol.swift @@ -17,10 +17,10 @@ import Foundation @MainActor -protocol ServerSelectionViewModelProtocol { - var callback: (@MainActor (ServerSelectionViewModelAction) -> Void)? { get set } - var context: ServerSelectionViewModelType.Context { get } +protocol ServerSelectionScreenViewModelProtocol { + var callback: (@MainActor (ServerSelectionScreenViewModelAction) -> Void)? { get set } + var context: ServerSelectionScreenViewModelType.Context { get } /// Displays an error to the user. - func displayError(_ type: ServerSelectionErrorType) + func displayError(_ type: ServerSelectionScreenErrorType) } diff --git a/ElementX/Sources/Screens/Authentication/ServerSelection/View/ServerSelectionScreen.swift b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/View/ServerSelectionScreen.swift similarity index 98% rename from ElementX/Sources/Screens/Authentication/ServerSelection/View/ServerSelectionScreen.swift rename to ElementX/Sources/Screens/Authentication/ServerSelectionScreen/View/ServerSelectionScreen.swift index 9702c4408..deaa86446 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelection/View/ServerSelectionScreen.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/View/ServerSelectionScreen.swift @@ -17,7 +17,7 @@ import SwiftUI struct ServerSelectionScreen: View { - @ObservedObject var context: ServerSelectionViewModel.Context + @ObservedObject var context: ServerSelectionScreenViewModel.Context var body: some View { ScrollView { diff --git a/ElementX/Sources/Screens/Authentication/SoftLogout/MockSoftLogoutScreenState.swift b/ElementX/Sources/Screens/Authentication/SoftLogout/MockSoftLogoutScreenState.swift deleted file mode 100644 index f4d5a7d88..000000000 --- a/ElementX/Sources/Screens/Authentication/SoftLogout/MockSoftLogoutScreenState.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2022 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 Foundation -import SwiftUI - -/// Using an enum for the screen allows you define the different state cases with -/// the relevant associated data for each case. -enum MockSoftLogoutScreenState: String, CaseIterable { - // A case for each state you want to represent - // with specific, minimal associated data that will allow you - // mock that screen. - case emptyPassword - case enteredPassword - case oidc - case unsupported - case keyBackupNeeded - - /// Generate the view struct for the screen state. - @MainActor var viewModel: SoftLogoutViewModel { - let credentials = SoftLogoutCredentials(userId: "@mock:matrix.org", - homeserverName: "matrix.org", - userDisplayName: "mock", - deviceId: nil) - switch self { - case .emptyPassword: - return SoftLogoutViewModel(credentials: credentials, - homeserver: .mockMatrixDotOrg, - keyBackupNeeded: false) - case .enteredPassword: - return SoftLogoutViewModel(credentials: credentials, - homeserver: .mockMatrixDotOrg, - keyBackupNeeded: false, - password: "12345678") - case .oidc: - return SoftLogoutViewModel(credentials: credentials, - homeserver: .mockOIDC, - keyBackupNeeded: false) - case .unsupported: - return SoftLogoutViewModel(credentials: credentials, - homeserver: .mockUnsupported, - keyBackupNeeded: false) - case .keyBackupNeeded: - return SoftLogoutViewModel(credentials: credentials, - homeserver: .mockMatrixDotOrg, - keyBackupNeeded: true) - } - } -} - -extension MockSoftLogoutScreenState: Identifiable { - var id: String { - rawValue - } -} diff --git a/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/MockSoftLogoutScreenState.swift b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/MockSoftLogoutScreenState.swift new file mode 100644 index 000000000..334aedb48 --- /dev/null +++ b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/MockSoftLogoutScreenState.swift @@ -0,0 +1,68 @@ +// +// Copyright 2022 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 Foundation +import SwiftUI + +/// Using an enum for the screen allows you define the different state cases with +/// the relevant associated data for each case. +enum MockSoftLogoutScreenState: String, CaseIterable { + // A case for each state you want to represent + // with specific, minimal associated data that will allow you + // mock that screen. + case emptyPassword + case enteredPassword + case oidc + case unsupported + case keyBackupNeeded + + /// Generate the view struct for the screen state. + @MainActor var viewModel: SoftLogoutScreenViewModel { + let credentials = SoftLogoutScreenCredentials(userId: "@mock:matrix.org", + homeserverName: "matrix.org", + userDisplayName: "mock", + deviceId: nil) + switch self { + case .emptyPassword: + return SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockMatrixDotOrg, + keyBackupNeeded: false) + case .enteredPassword: + return SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockMatrixDotOrg, + keyBackupNeeded: false, + password: "12345678") + case .oidc: + return SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockOIDC, + keyBackupNeeded: false) + case .unsupported: + return SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockUnsupported, + keyBackupNeeded: false) + case .keyBackupNeeded: + return SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockMatrixDotOrg, + keyBackupNeeded: true) + } + } +} + +extension MockSoftLogoutScreenState: Identifiable { + var id: String { + rawValue + } +} diff --git a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutCoordinator.swift b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenCoordinator.swift similarity index 88% rename from ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutCoordinator.swift rename to ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenCoordinator.swift index 9756790c9..668fafde0 100644 --- a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenCoordinator.swift @@ -17,13 +17,13 @@ import AppAuth import SwiftUI -struct SoftLogoutCoordinatorParameters { +struct SoftLogoutScreenCoordinatorParameters { let authenticationService: AuthenticationServiceProxyProtocol - let credentials: SoftLogoutCredentials + let credentials: SoftLogoutScreenCredentials let keyBackupNeeded: Bool } -enum SoftLogoutCoordinatorResult: CustomStringConvertible { +enum SoftLogoutScreenCoordinatorResult: CustomStringConvertible { /// Login was successful. case signedIn(UserSessionProtocol) /// Clear all user data @@ -40,26 +40,26 @@ enum SoftLogoutCoordinatorResult: CustomStringConvertible { } } -final class SoftLogoutCoordinator: CoordinatorProtocol { - private let parameters: SoftLogoutCoordinatorParameters - private var viewModel: SoftLogoutViewModelProtocol +final class SoftLogoutScreenCoordinator: CoordinatorProtocol { + private let parameters: SoftLogoutScreenCoordinatorParameters + private var viewModel: SoftLogoutScreenViewModelProtocol private let hostingController: UIViewController /// Passed to the OIDC service to provide a view controller from which to present the authentication session. private let oidcUserAgent: OIDExternalUserAgentIOS? /// The wizard used to handle the registration flow. private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService } - - var callback: (@MainActor (SoftLogoutCoordinatorResult) -> Void)? - @MainActor init(parameters: SoftLogoutCoordinatorParameters) { + var callback: (@MainActor (SoftLogoutScreenCoordinatorResult) -> Void)? + + @MainActor init(parameters: SoftLogoutScreenCoordinatorParameters) { self.parameters = parameters - + let homeserver = parameters.authenticationService.homeserver - viewModel = SoftLogoutViewModel(credentials: parameters.credentials, - homeserver: homeserver, - keyBackupNeeded: parameters.keyBackupNeeded) + viewModel = SoftLogoutScreenViewModel(credentials: parameters.credentials, + homeserver: homeserver, + keyBackupNeeded: parameters.keyBackupNeeded) hostingController = UIHostingController(rootView: SoftLogoutScreen(context: viewModel.context)) oidcUserAgent = OIDExternalUserAgentIOS(presenting: hostingController) diff --git a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutModels.swift b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenModels.swift similarity index 85% rename from ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutModels.swift rename to ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenModels.swift index 0c5c84518..2edddf7a5 100644 --- a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutModels.swift +++ b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenModels.swift @@ -16,14 +16,14 @@ import SwiftUI -struct SoftLogoutCredentials { +struct SoftLogoutScreenCredentials { let userId: String let homeserverName: String let userDisplayName: String let deviceId: String? } -enum SoftLogoutViewModelAction: CustomStringConvertible { +enum SoftLogoutScreenViewModelAction: CustomStringConvertible { /// Login with password case login(String) /// Forgot password @@ -48,9 +48,9 @@ enum SoftLogoutViewModelAction: CustomStringConvertible { } } -struct SoftLogoutViewState: BindableState { +struct SoftLogoutScreenViewState: BindableState { /// Soft logout credentials - var credentials: SoftLogoutCredentials + var credentials: SoftLogoutScreenCredentials /// Data about the selected homeserver. var homeserver: LoginHomeserver @@ -59,7 +59,7 @@ struct SoftLogoutViewState: BindableState { var keyBackupNeeded: Bool /// View state that can be bound to from SwiftUI. - var bindings: SoftLogoutBindings + var bindings: SoftLogoutScreenBindings /// The types of login supported by the homeserver. var loginMode: LoginMode { homeserver.loginMode } @@ -75,14 +75,14 @@ struct SoftLogoutViewState: BindableState { } } -struct SoftLogoutBindings { +struct SoftLogoutScreenBindings { /// The password input by the user. var password: String /// Information describing the currently displayed alert. - var alertInfo: AlertInfo? + var alertInfo: AlertInfo? } -enum SoftLogoutViewAction { +enum SoftLogoutScreenViewAction { /// Login. case login /// Forgot password @@ -93,7 +93,7 @@ enum SoftLogoutViewAction { case continueWithOIDC } -enum SoftLogoutErrorType: Hashable { +enum SoftLogoutScreenErrorType: Hashable { /// A specific error message shown in an alert. case alert(String) /// An unknown error occurred. diff --git a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutViewModel.swift b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenViewModel.swift similarity index 63% rename from ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutViewModel.swift rename to ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenViewModel.swift index bac33b985..e9f7730c7 100644 --- a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutViewModel.swift +++ b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenViewModel.swift @@ -16,24 +16,24 @@ import SwiftUI -typealias SoftLogoutViewModelType = StateStoreViewModel +typealias SoftLogoutScreenViewModelType = StateStoreViewModel -class SoftLogoutViewModel: SoftLogoutViewModelType, SoftLogoutViewModelProtocol { - var callback: (@MainActor (SoftLogoutViewModelAction) -> Void)? +class SoftLogoutScreenViewModel: SoftLogoutScreenViewModelType, SoftLogoutScreenViewModelProtocol { + var callback: (@MainActor (SoftLogoutScreenViewModelAction) -> Void)? - init(credentials: SoftLogoutCredentials, + init(credentials: SoftLogoutScreenCredentials, homeserver: LoginHomeserver, keyBackupNeeded: Bool, password: String = "") { - let bindings = SoftLogoutBindings(password: password) - let viewState = SoftLogoutViewState(credentials: credentials, - homeserver: homeserver, - keyBackupNeeded: keyBackupNeeded, - bindings: bindings) + let bindings = SoftLogoutScreenBindings(password: password) + let viewState = SoftLogoutScreenViewState(credentials: credentials, + homeserver: homeserver, + keyBackupNeeded: keyBackupNeeded, + bindings: bindings) super.init(initialViewState: viewState) } - override func process(viewAction: SoftLogoutViewAction) { + override func process(viewAction: SoftLogoutScreenViewAction) { switch viewAction { case .login: callback?(.login(state.bindings.password)) @@ -46,7 +46,7 @@ class SoftLogoutViewModel: SoftLogoutViewModelType, SoftLogoutViewModelProtocol } } - @MainActor func displayError(_ type: SoftLogoutErrorType) { + @MainActor func displayError(_ type: SoftLogoutScreenErrorType) { switch type { case .alert(let message): state.bindings.alertInfo = AlertInfo(id: type, diff --git a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutViewModelProtocol.swift b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenViewModelProtocol.swift similarity index 71% rename from ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutViewModelProtocol.swift rename to ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenViewModelProtocol.swift index 9d8632bf3..ed1a442c0 100644 --- a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutViewModelProtocol.swift +++ b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenViewModelProtocol.swift @@ -16,10 +16,10 @@ import Foundation -protocol SoftLogoutViewModelProtocol { - var callback: (@MainActor (SoftLogoutViewModelAction) -> Void)? { get set } - var context: SoftLogoutViewModelType.Context { get } +protocol SoftLogoutScreenViewModelProtocol { + var callback: (@MainActor (SoftLogoutScreenViewModelAction) -> Void)? { get set } + var context: SoftLogoutScreenViewModelType.Context { get } /// Display an error to the user. - @MainActor func displayError(_ type: SoftLogoutErrorType) + @MainActor func displayError(_ type: SoftLogoutScreenErrorType) } diff --git a/ElementX/Sources/Screens/Authentication/SoftLogout/View/SoftLogoutScreen.swift b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/View/SoftLogoutScreen.swift similarity index 97% rename from ElementX/Sources/Screens/Authentication/SoftLogout/View/SoftLogoutScreen.swift rename to ElementX/Sources/Screens/Authentication/SoftLogoutScreen/View/SoftLogoutScreen.swift index 1bc0b103a..becb584d7 100644 --- a/ElementX/Sources/Screens/Authentication/SoftLogout/View/SoftLogoutScreen.swift +++ b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/View/SoftLogoutScreen.swift @@ -22,7 +22,7 @@ struct SoftLogoutScreen: View { /// The focus state of the password text field. @FocusState private var isPasswordFocused: Bool - @ObservedObject var context: SoftLogoutViewModel.Context + @ObservedObject var context: SoftLogoutScreenViewModel.Context var body: some View { ScrollView { @@ -171,14 +171,14 @@ struct SoftLogoutScreen: View { // MARK: - Previews -struct SoftLogout_Previews: PreviewProvider { +struct SoftLogoutScreen_Previews: PreviewProvider { static var previews: some View { ForEach(MockSoftLogoutScreenState.allCases) { state in screen(for: state.viewModel) } } - static func screen(for viewModel: SoftLogoutViewModel) -> some View { + static func screen(for viewModel: SoftLogoutScreenViewModel) -> some View { NavigationStack { SoftLogoutScreen(context: viewModel.context) .navigationBarTitleDisplayMode(.inline) diff --git a/ElementX/Sources/Screens/StartChat/StartChatCoordinator.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift similarity index 77% rename from ElementX/Sources/Screens/StartChat/StartChatCoordinator.swift rename to ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift index ea896e991..df84999f4 100644 --- a/ElementX/Sources/Screens/StartChat/StartChatCoordinator.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift @@ -17,32 +17,32 @@ import Combine import SwiftUI -struct StartChatCoordinatorParameters { +struct StartChatScreenCoordinatorParameters { let userSession: UserSessionProtocol weak var userIndicatorController: UserIndicatorControllerProtocol? let navigationStackCoordinator: NavigationStackCoordinator? let userDiscoveryService: UserDiscoveryServiceProtocol } -enum StartChatCoordinatorAction { +enum StartChatScreenCoordinatorAction { case close case openRoom(withIdentifier: String) } -final class StartChatCoordinator: CoordinatorProtocol { - private let parameters: StartChatCoordinatorParameters - private var viewModel: StartChatViewModelProtocol - private let actionsSubject: PassthroughSubject = .init() +final class StartChatScreenCoordinator: CoordinatorProtocol { + private let parameters: StartChatScreenCoordinatorParameters + private var viewModel: StartChatScreenViewModelProtocol + private let actionsSubject: PassthroughSubject = .init() private var cancellables: Set = .init() - var actions: AnyPublisher { + var actions: AnyPublisher { actionsSubject.eraseToAnyPublisher() } - init(parameters: StartChatCoordinatorParameters) { + init(parameters: StartChatScreenCoordinatorParameters) { self.parameters = parameters - viewModel = StartChatViewModel(userSession: parameters.userSession, userIndicatorController: parameters.userIndicatorController, userDiscoveryService: parameters.userDiscoveryService) + viewModel = StartChatScreenViewModel(userSession: parameters.userSession, userIndicatorController: parameters.userIndicatorController, userDiscoveryService: parameters.userDiscoveryService) } func start() { diff --git a/ElementX/Sources/Screens/StartChat/StartChatModels.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenModels.swift similarity index 85% rename from ElementX/Sources/Screens/StartChat/StartChatModels.swift rename to ElementX/Sources/Screens/StartChatScreen/StartChatScreenModels.swift index 223735a3c..41f92a2bf 100644 --- a/ElementX/Sources/Screens/StartChat/StartChatModels.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenModels.swift @@ -16,18 +16,18 @@ import Foundation -enum StartChatErrorType: Error { +enum StartChatScreenErrorType: Error { case failedCreatingRoom case unknown } -enum StartChatViewModelAction { +enum StartChatScreenViewModelAction { case close case createRoom case openRoom(withIdentifier: String) } -struct StartChatViewState: BindableState { +struct StartChatScreenViewState: BindableState { var bindings = StartChatScreenViewStateBindings() var usersSection: UserDiscoverySection = .init(type: .suggestions, users: []) @@ -44,10 +44,10 @@ struct StartChatScreenViewStateBindings { var searchQuery = "" /// Information describing the currently displayed alert. - var alertInfo: AlertInfo? + var alertInfo: AlertInfo? } -enum StartChatViewAction { +enum StartChatScreenViewAction { case close case createRoom case inviteFriends diff --git a/ElementX/Sources/Screens/StartChat/StartChatViewModel.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift similarity index 90% rename from ElementX/Sources/Screens/StartChat/StartChatViewModel.swift rename to ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift index c5cbeaa80..b938eed3a 100644 --- a/ElementX/Sources/Screens/StartChat/StartChatViewModel.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift @@ -17,14 +17,14 @@ import Combine import SwiftUI -typealias StartChatViewModelType = StateStoreViewModel +typealias StartChatScreenViewModelType = StateStoreViewModel -class StartChatViewModel: StartChatViewModelType, StartChatViewModelProtocol { +class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenViewModelProtocol { private let userSession: UserSessionProtocol - private let actionsSubject: PassthroughSubject = .init() + private let actionsSubject: PassthroughSubject = .init() private let userDiscoveryService: UserDiscoveryServiceProtocol - var actions: AnyPublisher { + var actions: AnyPublisher { actionsSubject.eraseToAnyPublisher() } @@ -34,14 +34,14 @@ class StartChatViewModel: StartChatViewModelType, StartChatViewModelProtocol { self.userSession = userSession self.userIndicatorController = userIndicatorController self.userDiscoveryService = userDiscoveryService - super.init(initialViewState: StartChatViewState(), imageProvider: userSession.mediaProvider) + super.init(initialViewState: StartChatScreenViewState(), imageProvider: userSession.mediaProvider) setupBindings() } // MARK: - Public - override func process(viewAction: StartChatViewAction) { + override func process(viewAction: StartChatScreenViewAction) { switch viewAction { case .close: actionsSubject.send(.close) diff --git a/ElementX/Sources/Screens/StartChat/StartChatViewModelProtocol.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModelProtocol.swift similarity index 77% rename from ElementX/Sources/Screens/StartChat/StartChatViewModelProtocol.swift rename to ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModelProtocol.swift index 0052841b4..86210a5fd 100644 --- a/ElementX/Sources/Screens/StartChat/StartChatViewModelProtocol.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModelProtocol.swift @@ -17,7 +17,7 @@ import Combine @MainActor -protocol StartChatViewModelProtocol { - var actions: AnyPublisher { get } - var context: StartChatViewModelType.Context { get } +protocol StartChatScreenViewModelProtocol { + var actions: AnyPublisher { get } + var context: StartChatScreenViewModelType.Context { get } } diff --git a/ElementX/Sources/Screens/StartChat/View/StartChatScreen.swift b/ElementX/Sources/Screens/StartChatScreen/View/StartChatScreen.swift similarity index 94% rename from ElementX/Sources/Screens/StartChat/View/StartChatScreen.swift rename to ElementX/Sources/Screens/StartChatScreen/View/StartChatScreen.swift index 790d5b86b..9329ba1d1 100644 --- a/ElementX/Sources/Screens/StartChat/View/StartChatScreen.swift +++ b/ElementX/Sources/Screens/StartChatScreen/View/StartChatScreen.swift @@ -17,7 +17,7 @@ import SwiftUI struct StartChatScreen: View { - @ObservedObject var context: StartChatViewModel.Context + @ObservedObject var context: StartChatScreenViewModel.Context var body: some View { Form { @@ -130,14 +130,14 @@ struct StartChatScreen: View { // MARK: - Previews -struct StartChat_Previews: PreviewProvider { +struct StartChatScreen_Previews: PreviewProvider { static let viewModel = { let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "@userid:example.com"), mediaProvider: MockMediaProvider()) let userDiscoveryService = UserDiscoveryServiceMock() userDiscoveryService.fetchSuggestionsReturnValue = .success([.mockAlice]) userDiscoveryService.searchProfilesWithReturnValue = .success([.mockAlice]) - let viewModel = StartChatViewModel(userSession: userSession, userIndicatorController: nil, userDiscoveryService: userDiscoveryService) + let viewModel = StartChatScreenViewModel(userSession: userSession, userIndicatorController: nil, userDiscoveryService: userDiscoveryService) return viewModel }() diff --git a/ElementX/Sources/Services/UserSession/UserSessionFlowCoordinator.swift b/ElementX/Sources/Services/UserSession/UserSessionFlowCoordinator.swift index 0f837229d..05a7a2f54 100644 --- a/ElementX/Sources/Services/UserSession/UserSessionFlowCoordinator.swift +++ b/ElementX/Sources/Services/UserSession/UserSessionFlowCoordinator.swift @@ -289,8 +289,8 @@ class UserSessionFlowCoordinator: CoordinatorProtocol { let userIndicatorController = UserIndicatorController(rootCoordinator: startChatNavigationStackCoordinator) let userDiscoveryService = UserDiscoveryService(clientProxy: userSession.clientProxy) - let parameters = StartChatCoordinatorParameters(userSession: userSession, userIndicatorController: userIndicatorController, navigationStackCoordinator: startChatNavigationStackCoordinator, userDiscoveryService: userDiscoveryService) - let coordinator = StartChatCoordinator(parameters: parameters) + let parameters = StartChatScreenCoordinatorParameters(userSession: userSession, userIndicatorController: userIndicatorController, navigationStackCoordinator: startChatNavigationStackCoordinator, userDiscoveryService: userDiscoveryService) + let coordinator = StartChatScreenCoordinator(parameters: parameters) coordinator.actions.sink { [weak self] action in guard let self else { return } switch action { diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 5dd0f61e5..34e7d2805 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -62,21 +62,21 @@ class MockScreen: Identifiable { switch id { case .login: let navigationStackCoordinator = NavigationStackCoordinator() - let coordinator = LoginCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), - navigationStackCoordinator: navigationStackCoordinator)) + let coordinator = LoginScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), + navigationStackCoordinator: navigationStackCoordinator)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .serverSelection: let navigationStackCoordinator = NavigationStackCoordinator() - let coordinator = ServerSelectionCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), - userIndicatorController: MockUserIndicatorController(), - isModallyPresented: true)) + let coordinator = ServerSelectionScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), + userIndicatorController: MockUserIndicatorController(), + isModallyPresented: true)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .serverSelectionNonModal: - return ServerSelectionCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), - userIndicatorController: MockUserIndicatorController(), - isModallyPresented: false)) + return ServerSelectionScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), + userIndicatorController: MockUserIndicatorController(), + isModallyPresented: false)) case .analyticsPrompt: return AnalyticsPromptScreenCoordinator() case .analyticsSettingsScreen: @@ -92,13 +92,13 @@ class MockScreen: Identifiable { navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .softLogout: - let credentials = SoftLogoutCredentials(userId: "@mock:matrix.org", - homeserverName: "matrix.org", - userDisplayName: "mock", - deviceId: "ABCDEFGH") - return SoftLogoutCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), - credentials: credentials, - keyBackupNeeded: false)) + let credentials = SoftLogoutScreenCredentials(userId: "@mock:matrix.org", + homeserverName: "matrix.org", + userDisplayName: "mock", + deviceId: "ABCDEFGH") + return SoftLogoutScreenCoordinator(parameters: .init(authenticationService: MockAuthenticationServiceProxy(), + credentials: credentials, + keyBackupNeeded: false)) case .simpleRegular: return TemplateScreenCoordinator(parameters: .init(promptType: .regular)) case .simpleUpgrade: @@ -321,8 +321,8 @@ class MockScreen: Identifiable { userDiscoveryMock.fetchSuggestionsReturnValue = .success([.mockAlice, .mockBob, .mockCharlie]) userDiscoveryMock.searchProfilesWithReturnValue = .success([]) let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "@mock:client.com"), mediaProvider: MockMediaProvider()) - let parameters: StartChatCoordinatorParameters = .init(userSession: userSession, navigationStackCoordinator: navigationStackCoordinator, userDiscoveryService: userDiscoveryMock) - let coordinator = StartChatCoordinator(parameters: parameters) + let parameters: StartChatScreenCoordinatorParameters = .init(userSession: userSession, navigationStackCoordinator: navigationStackCoordinator, userDiscoveryService: userDiscoveryMock) + let coordinator = StartChatScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .startChatWithSearchResults: @@ -332,7 +332,7 @@ class MockScreen: Identifiable { userDiscoveryMock.fetchSuggestionsReturnValue = .success([]) userDiscoveryMock.searchProfilesWithReturnValue = .success([.mockBob, .mockBobby]) let userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider()) - let coordinator = StartChatCoordinator(parameters: .init(userSession: userSession, navigationStackCoordinator: navigationStackCoordinator, userDiscoveryService: userDiscoveryMock)) + let coordinator = StartChatScreenCoordinator(parameters: .init(userSession: userSession, navigationStackCoordinator: navigationStackCoordinator, userDiscoveryService: userDiscoveryMock)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .roomMemberDetailsAccountOwner: diff --git a/UnitTests/Sources/LoginViewModelTests.swift b/UnitTests/Sources/LoginViewModelTests.swift index a213d4f84..b2286e0b7 100644 --- a/UnitTests/Sources/LoginViewModelTests.swift +++ b/UnitTests/Sources/LoginViewModelTests.swift @@ -21,11 +21,11 @@ import XCTest @MainActor class LoginViewModelTests: XCTestCase { let defaultHomeserver = LoginHomeserver.mockMatrixDotOrg - var viewModel: LoginViewModelProtocol! - var context: LoginViewModelType.Context! + var viewModel: LoginScreenViewModelProtocol! + var context: LoginScreenViewModelType.Context! @MainActor override func setUp() async throws { - viewModel = LoginViewModel(homeserver: defaultHomeserver) + viewModel = LoginScreenViewModel(homeserver: defaultHomeserver) context = viewModel.context } @@ -135,7 +135,7 @@ class LoginViewModelTests: XCTestCase { func testLogsForPassword() { // Given the coordinator and view model results that contain passwords. let password = "supersecretpassword" - let viewModelAction: LoginViewModelAction = .login(username: "Alice", password: password) + let viewModelAction: LoginScreenViewModelAction = .login(username: "Alice", password: password) // When creating a string representation of those results (e.g. for logging). let viewModelActionString = "\(viewModelAction)" diff --git a/UnitTests/Sources/ServerSelectionViewModelTests.swift b/UnitTests/Sources/ServerSelectionViewModelTests.swift index 43409313e..5964f88ee 100644 --- a/UnitTests/Sources/ServerSelectionViewModelTests.swift +++ b/UnitTests/Sources/ServerSelectionViewModelTests.swift @@ -24,11 +24,11 @@ class ServerSelectionViewModelTests: XCTestCase { static let counterInitialValue = 0 } - var viewModel: ServerSelectionViewModelProtocol! - var context: ServerSelectionViewModelType.Context! + var viewModel: ServerSelectionScreenViewModelProtocol! + var context: ServerSelectionScreenViewModelType.Context! @MainActor override func setUp() { - viewModel = ServerSelectionViewModel(homeserverAddress: "", isModallyPresented: true) + viewModel = ServerSelectionScreenViewModel(homeserverAddress: "", isModallyPresented: true) context = viewModel.context } diff --git a/UnitTests/Sources/SoftLogoutViewModelTests.swift b/UnitTests/Sources/SoftLogoutViewModelTests.swift index 212458a4b..1a802752e 100644 --- a/UnitTests/Sources/SoftLogoutViewModelTests.swift +++ b/UnitTests/Sources/SoftLogoutViewModelTests.swift @@ -19,17 +19,17 @@ import XCTest @testable import ElementX class SoftLogoutViewModelTests: XCTestCase { - let credentials = SoftLogoutCredentials(userId: "mock_user_id", - homeserverName: "https://matrix.org", - userDisplayName: "mock_username", - deviceId: "ABCDEFGH") - + let credentials = SoftLogoutScreenCredentials(userId: "mock_user_id", + homeserverName: "https://matrix.org", + userDisplayName: "mock_username", + deviceId: "ABCDEFGH") + @MainActor func testInitialStateForMatrixOrg() { - let viewModel = SoftLogoutViewModel(credentials: credentials, - homeserver: .mockMatrixDotOrg, - keyBackupNeeded: true) + let viewModel = SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockMatrixDotOrg, + keyBackupNeeded: true) let context = viewModel.context - + // Given a view model where the user hasn't yet sent the verification email. XCTAssert(context.password.isEmpty, "The view model should start with an empty password.") XCTAssertFalse(context.viewState.canSubmit, "The view model should start with an invalid password.") @@ -38,10 +38,10 @@ class SoftLogoutViewModelTests: XCTestCase { } @MainActor func testInitialStateForMatrixOrgPasswordEntered() { - let viewModel = SoftLogoutViewModel(credentials: credentials, - homeserver: .mockMatrixDotOrg, - keyBackupNeeded: true, - password: "12345678") + let viewModel = SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockMatrixDotOrg, + keyBackupNeeded: true, + password: "12345678") let context = viewModel.context // Given a view model where the user hasn't yet sent the verification email. @@ -49,13 +49,13 @@ class SoftLogoutViewModelTests: XCTestCase { XCTAssertEqual(context.viewState.loginMode, .password, "The view model should show login form for the given homeserver.") XCTAssert(context.viewState.showRecoverEncryptionKeysMessage, "The view model should show recover encryption keys message.") } - + @MainActor func testInitialStateForBasicServer() { - let viewModel = SoftLogoutViewModel(credentials: credentials, - homeserver: .mockBasicServer, - keyBackupNeeded: false) + let viewModel = SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockBasicServer, + keyBackupNeeded: false) let context = viewModel.context - + // Given a view model where the user hasn't yet sent the verification email. XCTAssert(context.password.isEmpty, "The view model should start with an empty password.") XCTAssertFalse(context.viewState.canSubmit, "The view model should start with an invalid password.") @@ -64,22 +64,22 @@ class SoftLogoutViewModelTests: XCTestCase { } @MainActor func testInitialStateForOIDC() { - let viewModel = SoftLogoutViewModel(credentials: credentials, - homeserver: .mockOIDC, - keyBackupNeeded: false) + let viewModel = SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockOIDC, + keyBackupNeeded: false) let context = viewModel.context - + // Given a view model where the user hasn't yet sent the verification email. XCTAssert(context.password.isEmpty, "The view model should start with an empty password.") XCTAssertFalse(context.viewState.canSubmit, "The view model should start with an invalid password.") XCTAssertTrue(context.viewState.loginMode.supportsOIDCFlow, "The view model should show OIDC button for the given homeserver.") XCTAssertFalse(context.viewState.showRecoverEncryptionKeysMessage, "The view model should not show recover encryption keys message.") } - + @MainActor func testInitialStateForUnsupported() { - let viewModel = SoftLogoutViewModel(credentials: credentials, - homeserver: .mockUnsupported, - keyBackupNeeded: false) + let viewModel = SoftLogoutScreenViewModel(credentials: credentials, + homeserver: .mockUnsupported, + keyBackupNeeded: false) let context = viewModel.context // Given a view model where the user hasn't yet sent the verification email. diff --git a/UnitTests/Sources/StartChatViewModelTests.swift b/UnitTests/Sources/StartChatViewModelTests.swift index fa16de7e8..32b8ea02b 100644 --- a/UnitTests/Sources/StartChatViewModelTests.swift +++ b/UnitTests/Sources/StartChatViewModelTests.swift @@ -20,11 +20,11 @@ import XCTest @MainActor class StartChatScreenViewModelTests: XCTestCase { - var viewModel: StartChatViewModelProtocol! + var viewModel: StartChatScreenViewModelProtocol! var clientProxy: MockClientProxy! var userDiscoveryService: UserDiscoveryServiceMock! - var context: StartChatViewModel.Context { + var context: StartChatScreenViewModel.Context { viewModel.context } @@ -34,7 +34,7 @@ class StartChatScreenViewModelTests: XCTestCase { userDiscoveryService.fetchSuggestionsReturnValue = .success([]) userDiscoveryService.searchProfilesWithReturnValue = .success([]) let userSession = MockUserSession(clientProxy: clientProxy, mediaProvider: MockMediaProvider()) - viewModel = StartChatViewModel(userSession: userSession, userIndicatorController: nil, userDiscoveryService: userDiscoveryService) + viewModel = StartChatScreenViewModel(userSession: userSession, userIndicatorController: nil, userDiscoveryService: userDiscoveryService) setupAppSettings() ServiceLocator.shared.settings.startChatUserSuggestionsEnabled = true @@ -65,7 +65,7 @@ class StartChatScreenViewModelTests: XCTestCase { } @discardableResult - private func search(query: String) async -> StartChatViewState? { + private func search(query: String) async -> StartChatScreenViewState? { viewModel.context.searchQuery = query return await context.$viewState.nextValue }