mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Combine the Server Selection screen into the Server Confirmation screen and add autocompletion when entering an account provider. (#5949)
* Adjust login flow to exclusively use the ServerSelectionScreen * Move async code to server selection vm * ServerSelection supports pro picker options * Use homeserver address for both confirmation and picker modes * rename ServerSelectionScreenMode * remove ServerConfirmationScreen It's been superseded by the ServerSelectionScreen * rename userInput * Update strings with latest design strings * Add server input autocompletion * Store previous servers in AppSettings and autofill on server signin * Audit changes for logging * Enforce lowercase server history storage * Update tests * Update Xcode project * PR review fixups * Add HomeserverHistoryManager * Review fixups 2 * Review fixups 3
This commit is contained in:
+73
-11
@@ -6,21 +6,71 @@
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
enum ServerSelectionScreenViewModelAction {
|
||||
/// The homeserver selection has been updated.
|
||||
case updated
|
||||
/// Dismiss the view without using the entered address.
|
||||
case dismiss
|
||||
/// 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 {
|
||||
/// The message to be shown in the text field footer when no error has occurred.
|
||||
private let regularFooterMessage = L10n.screenChangeServerFormNotice
|
||||
/// 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?
|
||||
|
||||
@@ -36,22 +86,32 @@ struct ServerSelectionScreenViewState: BindableState {
|
||||
|
||||
/// Whether it is possible to continue when tapping the confirmation button.
|
||||
var hasValidationError: Bool {
|
||||
bindings.homeserverAddress.isEmpty || isShowingFooterError
|
||||
switch mode {
|
||||
case .userInput:
|
||||
bindings.homeserverAddress.isEmpty || isShowingFooterError
|
||||
case .picker(let options):
|
||||
!options.contains(bindings.homeserverAddress) || isShowingFooterError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ServerSelectionScreenBindings {
|
||||
/// The homeserver address input by the user.
|
||||
/// The homeserver address input or chosen by the user.
|
||||
var homeserverAddress: String
|
||||
/// The selection range in `homeserverAddress`
|
||||
var homeserverSelection: 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
|
||||
/// Dismiss the view without using the entered address.
|
||||
case dismiss
|
||||
/// Clear any errors shown in the text field footer.
|
||||
case clearFooterError
|
||||
}
|
||||
@@ -67,4 +127,6 @@ enum ServerSelectionScreenErrorType: Hashable {
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user