Files
element-x-ios/ElementX/Sources/Screens/Authentication/ServerSelectionScreen/ServerSelectionScreenModels.swift
T
Doug 64aae09c6d Add an AccountProvider type and use it within the authentication flow. (#6103)
* Add an AccountProvider type and use it within AppSettings.

* Use the AccountProvider type within the Authentication flow too.

* Fix unit test compilation with Swift 6.4

* Make sure defaultAccountProvider takes allowOtherAccountProviders into account.

* Document a caveat on using AuthenticationService.homeserver.value.accountProvider.
2026-09-14 15:25:33 +01:00

133 lines
4.6 KiB
Swift

//
// Copyright 2025 Element Creations Ltd.
// Copyright 2022-2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import SwiftUI
enum ServerSelectionScreenViewModelAction {
/// Continue the flow using the provided OAuth parameters.
case continueWithOAuth(data: OAuthAuthorizationDataProxy, window: UIWindow)
/// Continue the flow using password authentication.
case continueWithPassword
}
enum ServerSelectionScreenMode: Equatable {
/// The user is confirming the displayed account provider (or can enter their own).
case userInput
/// The user is only allowed to pick from a list of account providers.
case picker([String])
}
struct ServerSelectionScreenViewState: BindableState {
/// Whether the screen is configured to confirm a single account provider or pick one from a list of many.
var mode: ServerSelectionScreenMode
/// Whether the screen is configured for registration or existing account login
var authenticationFlow: AuthenticationFlow
/// The presentation anchor used for OAuth authentication.
var window: UIWindow?
/// View state that can be bound to from SwiftUI.
var bindings: ServerSelectionScreenBindings
/// Upon introspection, this is the UITextField backing the TextField for server input
var textField: UITextField? {
get { textFieldAdapter.textField }
set { textFieldAdapter.textField = newValue }
}
/// Adapts the text field for custom functionality beyond what's available in SwiftUI
let textFieldAdapter = TextFieldAdapter()
var screenTitle: String {
switch authenticationFlow {
case .login:
L10n.screenChangeServerNavigationTitleLogin
case .register:
L10n.screenChangeServerNavigationTitleRegister
}
}
/// The header text for the screen
var screenHeader: String {
switch authenticationFlow {
case .login:
L10n.screenChangeServerTitleLogin
case .register:
L10n.screenChangeServerTitleRegister
}
}
/// The message to be shown in the text field footer when no error has occurred.
var regularFooterMessage: String {
switch authenticationFlow {
case .login:
L10n.screenChangeServerTextfieldFooterLogin
case .register:
L10n.screenChangeServerTextfieldFooterRegister
}
}
/// An error message to be shown in the text field footer.
var footerErrorMessage: String?
/// The message to show in the text field footer.
var footerMessage: String {
footerErrorMessage ?? regularFooterMessage
}
/// The text field is showing an error.
var isShowingFooterError: Bool {
footerErrorMessage != nil
}
/// Whether it is possible to continue when tapping the confirmation button.
var hasValidationError: Bool {
switch mode {
case .userInput:
bindings.serverNameOrBaseURL.isEmpty || isShowingFooterError
case .picker(let options):
!options.contains(bindings.serverNameOrBaseURL) || isShowingFooterError
}
}
}
struct ServerSelectionScreenBindings {
/// The homeserver input or chosen by the user.
var serverNameOrBaseURL: String
/// The selection range in `serverNameOrBaseURL`
var serverNameOrBaseURLSelection: TextSelection?
/// Information describing the currently displayed alert.
var alertInfo: AlertInfo<ServerSelectionScreenErrorType>?
}
enum ServerSelectionScreenViewAction {
/// Updates the window used as the OAuth presentation anchor.
case updateWindow(UIWindow)
/// Updates the textfield from introspection
case updateTextField(UITextField)
/// The user would like to use the homeserver at the input address.
case confirm
/// Clear any errors shown in the text field footer.
case clearFooterError
}
enum ServerSelectionScreenErrorType: Hashable {
/// An alert that informs the user about a bad well-known file.
case invalidWellKnownAlert(String)
/// An alert that allows the user to learn about sliding sync.
case slidingSyncAlert
/// An alert that informs the user that login isn't supported.
case loginAlert
/// An alert that informs the user that registration isn't supported.
case registrationAlert
/// An alert that informs the user that Element Pro should be used for a particular server.
case elementProAlert
/// An unknown error has occurred.
case unknownError
}