mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-28 20:26:57 +02:00
Merge branch 'feature/4231_add_new_loginflow' into 'develop'
MESSENGER-4231 add new loginflow See merge request bwmessenger/bundesmessenger/bundesmessenger-ios!98
This commit is contained in:
@@ -33,6 +33,8 @@ enum AuthenticationLoginViewModelResult: CustomStringConvertible {
|
||||
case fallback
|
||||
/// Continue with QR login
|
||||
case qrLogin
|
||||
/// bwi: register info
|
||||
case register
|
||||
|
||||
/// A string representation of the result, ignoring any associated values that could leak PII.
|
||||
var description: String {
|
||||
@@ -51,6 +53,8 @@ enum AuthenticationLoginViewModelResult: CustomStringConvertible {
|
||||
return "fallback"
|
||||
case .qrLogin:
|
||||
return "qrLogin"
|
||||
case .register:
|
||||
return "register"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,6 +116,8 @@ enum AuthenticationLoginViewAction {
|
||||
case continueWithSSO(SSOIdentityProvider)
|
||||
/// Continue using QR login
|
||||
case qrLogin
|
||||
/// bwi: register info
|
||||
case register
|
||||
}
|
||||
|
||||
enum AuthenticationLoginErrorType: Hashable {
|
||||
|
||||
@@ -52,6 +52,8 @@ class AuthenticationLoginViewModel: AuthenticationLoginViewModelType, Authentica
|
||||
Task { await callback?(.continueWithSSO(provider)) }
|
||||
case .qrLogin:
|
||||
Task { await callback?(.qrLogin) }
|
||||
case .register:
|
||||
Task { await callback?(.register) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,4 +80,20 @@ class AuthenticationLoginViewModel: AuthenticationLoginViewModelType, Authentica
|
||||
state.bindings.alertInfo = AlertInfo(id: type)
|
||||
}
|
||||
}
|
||||
|
||||
// bwi: show custom alert
|
||||
@MainActor func displayInfoAlert(_ type: AuthenticationLoginViewAction) {
|
||||
switch type {
|
||||
case .forgotPassword:
|
||||
state.bindings.alertInfo = AlertInfo(id: .unknown,
|
||||
title: BWIL10n.authForgotPassword,
|
||||
message: BWIL10n.bwiAuthForgotPasswordAlertText)
|
||||
case .register:
|
||||
state.bindings.alertInfo = AlertInfo(id: .unknown,
|
||||
title: BWIL10n.bwiAuthRegisterAlertTitle,
|
||||
message: BWIL10n.bwiAuthRegisterAlertText)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,8 @@ protocol AuthenticationLoginViewModelProtocol {
|
||||
/// Display an error to the user.
|
||||
/// - Parameter type: The type of error to be displayed.
|
||||
@MainActor func displayError(_ type: AuthenticationLoginErrorType)
|
||||
|
||||
/// bwi: Display an info alert.
|
||||
/// - Parameter type: The type of the message to be displayed.
|
||||
@MainActor func displayInfoAlert(_ type: AuthenticationLoginViewAction)
|
||||
}
|
||||
|
||||
+9
-1
@@ -123,7 +123,12 @@ final class AuthenticationLoginCoordinator: Coordinator, Presentable {
|
||||
case .parseUsername(let username):
|
||||
self.parseUsername(username)
|
||||
case .forgotPassword:
|
||||
self.showForgotPasswordScreen()
|
||||
// bwi: show info alert
|
||||
if BWIBuildSettings.shared.forgotPasswordInformationAlert {
|
||||
self.authenticationLoginViewModel.displayInfoAlert(.forgotPassword)
|
||||
} else {
|
||||
self.showForgotPasswordScreen()
|
||||
}
|
||||
case .login(let username, let password):
|
||||
self.login(username: username, password: password)
|
||||
case .continueWithSSO(let identityProvider):
|
||||
@@ -132,6 +137,9 @@ final class AuthenticationLoginCoordinator: Coordinator, Presentable {
|
||||
self.callback?(.fallback)
|
||||
case .qrLogin:
|
||||
self.showQRLoginScreen()
|
||||
case .register:
|
||||
// bwi: show info alert
|
||||
self.authenticationLoginViewModel.displayInfoAlert(.register)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ struct AuthenticationLoginScreen: View {
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
private enum CustomText {
|
||||
case username, submit
|
||||
}
|
||||
|
||||
@Environment(\.theme) private var theme: ThemeSwiftUI
|
||||
|
||||
@@ -35,8 +38,8 @@ struct AuthenticationLoginScreen: View {
|
||||
VStack {
|
||||
ScrollView {
|
||||
VStack(spacing: 0) {
|
||||
if BWIBuildSettings.shared.bumLoginFlowLayout {
|
||||
ServerIcon(image: Asset.SharedImages.loginFlowLogo, size: OnboardingMetrics.iconSize)
|
||||
if BWIBuildSettings.shared.bumLoginFlowLayout || BWIBuildSettings.shared.bwiLoginFlowLayout {
|
||||
ServerIcon(image: getServerIcon(), size: OnboardingMetrics.iconSize)
|
||||
.padding(.top, OnboardingMetrics.topPaddingToNavigationBar)
|
||||
.padding(.bottom, 16)
|
||||
} else {
|
||||
@@ -45,14 +48,19 @@ struct AuthenticationLoginScreen: View {
|
||||
.padding(.bottom, 28)
|
||||
}
|
||||
|
||||
serverInfo
|
||||
.padding(.leading, 12)
|
||||
.padding(.bottom, 16)
|
||||
if !BWIBuildSettings.shared.bwiLoginFlowLayout {
|
||||
serverInfo
|
||||
.padding(.leading, 12)
|
||||
.padding(.bottom, 16)
|
||||
|
||||
Rectangle()
|
||||
.fill(theme.colors.quinaryContent)
|
||||
.frame(height: 1)
|
||||
.padding(.bottom, 22)
|
||||
Rectangle()
|
||||
.fill(theme.colors.quinaryContent)
|
||||
.frame(height: 1)
|
||||
.padding(.bottom, 22)
|
||||
} else {
|
||||
// bwi: show cutom header
|
||||
authLoginHeaderlineText
|
||||
}
|
||||
|
||||
if BWIBuildSettings.shared.bumLoginFlowLayout {
|
||||
loginDescription
|
||||
@@ -115,7 +123,7 @@ struct AuthenticationLoginScreen: View {
|
||||
/// The form with text fields for username and password, along with a submit button.
|
||||
var loginForm: some View {
|
||||
VStack(spacing: 14) {
|
||||
RoundedBorderTextField(placeHolder: BWIL10n.authenticationLoginUsername,
|
||||
RoundedBorderTextField(placeHolder: getCustomText(text: .username),
|
||||
text: $viewModel.username,
|
||||
isFirstResponder: false,
|
||||
configuration: UIKitTextInputConfiguration(returnKeyType: .next,
|
||||
@@ -134,8 +142,8 @@ struct AuthenticationLoginScreen: View {
|
||||
onEditingChanged: passwordEditingChanged,
|
||||
onCommit: submit)
|
||||
.accessibilityIdentifier("passwordTextField")
|
||||
|
||||
if !BWIBuildSettings.shared.bumLoginFlowLayout {
|
||||
// bwi: hide nv forgot password button
|
||||
if !BWIBuildSettings.shared.bumLoginFlowLayout && !BWIBuildSettings.shared.bwiLoginFlowLayout {
|
||||
Button { viewModel.send(viewAction: .forgotPassword) } label: {
|
||||
Text(VectorL10n.authenticationLoginForgotPassword)
|
||||
.font(theme.fonts.body)
|
||||
@@ -145,11 +153,20 @@ struct AuthenticationLoginScreen: View {
|
||||
}
|
||||
|
||||
Button(action: submit) {
|
||||
Text(VectorL10n.next)
|
||||
Text(getCustomText(text: .submit))
|
||||
}
|
||||
.buttonStyle(PrimaryActionButtonStyle())
|
||||
.disabled(!viewModel.viewState.canSubmit)
|
||||
.accessibilityIdentifier("nextButton")
|
||||
.padding([.vertical], BWIBuildSettings.shared.bwiLoginFlowLayout ? 36 : 0)
|
||||
|
||||
|
||||
if BWIBuildSettings.shared.authScreenShowForgotPassword {
|
||||
forgotPasswordButton
|
||||
}
|
||||
if BWIBuildSettings.shared.bwiEnableRegisterInfo {
|
||||
registerButton
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +256,59 @@ struct AuthenticationLoginScreen: View {
|
||||
func qrLogin() {
|
||||
viewModel.send(viewAction: .qrLogin)
|
||||
}
|
||||
|
||||
// bwi: custom forgot password button
|
||||
var forgotPasswordButton: some View {
|
||||
Button {
|
||||
viewModel.send(viewAction: .forgotPassword)
|
||||
} label: {
|
||||
Text(BWIL10n.authForgotPassword)
|
||||
.font(theme.fonts.body)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
.padding(.bottom, 8)
|
||||
}
|
||||
|
||||
// bwi: custom register button
|
||||
var registerButton: some View {
|
||||
Button {
|
||||
viewModel.send(viewAction: .register)
|
||||
} label: {
|
||||
Text(BWIL10n.bwiAuthRegisterButtonTitle)
|
||||
.font(theme.fonts.body)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
.padding(.bottom, 8)
|
||||
}
|
||||
|
||||
// bwi: custom header
|
||||
var authLoginHeaderlineText: some View {
|
||||
VStack(alignment: .leading) {
|
||||
Text(BWIL10n.authLoginHeadlineText)
|
||||
.font(theme.fonts.body)
|
||||
.foregroundColor(theme.colors.primaryContent)
|
||||
Text(BWIL10n.authLoginSubheadlineText)
|
||||
.font(theme.fonts.subheadline)
|
||||
.foregroundColor(theme.colors.secondaryContent)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding([.vertical], 36)
|
||||
}
|
||||
|
||||
// bwi: get app specific ServerIcon
|
||||
func getServerIcon() -> ImageAsset {
|
||||
return BWIBuildSettings.shared.bwiLoginFlowLayout ? Asset.Images.launchScreenLogo : Asset.SharedImages.loginFlowLogo
|
||||
}
|
||||
|
||||
// bwi: get app specific text
|
||||
private func getCustomText(text: CustomText) -> String {
|
||||
switch text {
|
||||
case .submit:
|
||||
return BWIBuildSettings.shared.bwiLoginFlowLayout ? BWIL10n.authenticationServerSelectionSubmitButtonTitle : VectorL10n.next
|
||||
case .username:
|
||||
return BWIBuildSettings.shared.bwiLoginFlowLayout ? BWIL10n.authUserIdPlaceholder : BWIL10n.authenticationLoginUsername
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
+21
@@ -67,6 +67,9 @@ struct AuthenticationServerSelectionScreen: View {
|
||||
message: Text(BWIL10n.authenticationServerSelectionServerDeniedMessage),
|
||||
dismissButton: .default(Text(VectorL10n.ok)))
|
||||
}
|
||||
if BWIBuildSettings.shared.authScreenShowTestServerOptions {
|
||||
serverSelectionButton
|
||||
}
|
||||
}
|
||||
.readableFrame()
|
||||
.padding(.horizontal, 16)
|
||||
@@ -221,6 +224,24 @@ struct AuthenticationServerSelectionScreen: View {
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
// bwi: show server selection button
|
||||
var serverSelectionButton: some View {
|
||||
VStack() {
|
||||
Menu(content: {
|
||||
ForEach(ServerURLHelper.shared.serverSettings, id: \.self) { server in
|
||||
Button(server.name, action: {
|
||||
viewModel.homeserverAddress = server.serverUrl
|
||||
})
|
||||
}
|
||||
}, label: {
|
||||
Button(action: { return }) {
|
||||
Text(BWIL10n.bwiAuthBetaSelectionButtonTitle)
|
||||
}
|
||||
.buttonStyle(PrimaryActionButtonStyle())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user