diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt index c76d24b3d0..9e715be193 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/DefaultRegistrationWizard.kt @@ -35,9 +35,9 @@ import org.matrix.android.sdk.internal.auth.login.LoginType * This class execute the registration request and is responsible to keep the session of interactive authentication */ internal class DefaultRegistrationWizard( - authAPI: AuthAPI, - private val sessionCreator: SessionCreator, - private val pendingSessionStore: PendingSessionStore + authAPI: AuthAPI, + private val sessionCreator: SessionCreator, + private val pendingSessionStore: PendingSessionStore ) : RegistrationWizard { private var pendingSessionData: PendingSessionData = pendingSessionStore.getPendingSessionData() ?: error("Pending session data should exist here") @@ -50,12 +50,12 @@ internal class DefaultRegistrationWizard( override val currentThreePid: String? get() { return when (val threePid = pendingSessionData.currentThreePidData?.threePid) { - is RegisterThreePid.Email -> threePid.email + is RegisterThreePid.Email -> threePid.email is RegisterThreePid.Msisdn -> { // Take formatted msisdn if provided by the server pendingSessionData.currentThreePidData?.addThreePidRegistrationResponse?.formattedMsisdn?.takeIf { it.isNotBlank() } ?: threePid.msisdn } - null -> null + null -> null } } @@ -67,24 +67,26 @@ internal class DefaultRegistrationWizard( return performRegistrationRequest(params, LoginType.PASSWORD) } - override suspend fun createAccount(userName: String?, - password: String?, - initialDeviceDisplayName: String?): RegistrationResult { + override suspend fun createAccount( + userName: String?, + password: String?, + initialDeviceDisplayName: String? + ): RegistrationResult { val params = RegistrationParams( - username = userName, - password = password, - initialDeviceDisplayName = initialDeviceDisplayName + username = userName, + password = password, + initialDeviceDisplayName = initialDeviceDisplayName ) return performRegistrationRequest(params, LoginType.PASSWORD) - .also { - pendingSessionData = pendingSessionData.copy(isRegistrationStarted = true) - .also { pendingSessionStore.savePendingSessionData(it) } - } + .also { + pendingSessionData = pendingSessionData.copy(isRegistrationStarted = true) + .also { pendingSessionStore.savePendingSessionData(it) } + } } override suspend fun performReCaptcha(response: String): RegistrationResult { val safeSession = pendingSessionData.currentSession - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") val params = RegistrationParams(auth = AuthParams.createForCaptcha(safeSession, response)) return performRegistrationRequest(params, LoginType.PASSWORD) @@ -92,7 +94,7 @@ internal class DefaultRegistrationWizard( override suspend fun acceptTerms(): RegistrationResult { val safeSession = pendingSessionData.currentSession - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") val params = RegistrationParams(auth = AuthParams(type = LoginFlowTypes.TERMS, session = safeSession)) return performRegistrationRequest(params, LoginType.PASSWORD) @@ -100,14 +102,14 @@ internal class DefaultRegistrationWizard( override suspend fun addThreePid(threePid: RegisterThreePid): RegistrationResult { pendingSessionData = pendingSessionData.copy(currentThreePidData = null) - .also { pendingSessionStore.savePendingSessionData(it) } + .also { pendingSessionStore.savePendingSessionData(it) } return sendThreePid(threePid) } override suspend fun sendAgainThreePid(): RegistrationResult { val safeCurrentThreePid = pendingSessionData.currentThreePidData?.threePid - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") return sendThreePid(safeCurrentThreePid) } @@ -115,34 +117,34 @@ internal class DefaultRegistrationWizard( private suspend fun sendThreePid(threePid: RegisterThreePid): RegistrationResult { val safeSession = pendingSessionData.currentSession ?: throw IllegalStateException("developer error, call createAccount() method first") val response = registerAddThreePidTask.execute( - RegisterAddThreePidTask.Params( - threePid, - pendingSessionData.clientSecret, - pendingSessionData.sendAttempt)) + RegisterAddThreePidTask.Params( + threePid, + pendingSessionData.clientSecret, + pendingSessionData.sendAttempt)) pendingSessionData = pendingSessionData.copy(sendAttempt = pendingSessionData.sendAttempt + 1) - .also { pendingSessionStore.savePendingSessionData(it) } + .also { pendingSessionStore.savePendingSessionData(it) } val params = RegistrationParams( - auth = if (threePid is RegisterThreePid.Email) { - AuthParams.createForEmailIdentity(safeSession, - ThreePidCredentials( - clientSecret = pendingSessionData.clientSecret, - sid = response.sid - ) + auth = if (threePid is RegisterThreePid.Email) { + AuthParams.createForEmailIdentity(safeSession, + ThreePidCredentials( + clientSecret = pendingSessionData.clientSecret, + sid = response.sid ) - } else { - AuthParams.createForMsisdnIdentity(safeSession, - ThreePidCredentials( - clientSecret = pendingSessionData.clientSecret, - sid = response.sid - ) + ) + } else { + AuthParams.createForMsisdnIdentity(safeSession, + ThreePidCredentials( + clientSecret = pendingSessionData.clientSecret, + sid = response.sid ) - } + ) + } ) // Store data pendingSessionData = pendingSessionData.copy(currentThreePidData = ThreePidData.from(threePid, response, params)) - .also { pendingSessionStore.savePendingSessionData(it) } + .also { pendingSessionStore.savePendingSessionData(it) } // and send the sid a first time return performRegistrationRequest(params, LoginType.PASSWORD) @@ -150,7 +152,7 @@ internal class DefaultRegistrationWizard( override suspend fun checkIfEmailHasBeenValidated(delayMillis: Long): RegistrationResult { val safeParam = pendingSessionData.currentThreePidData?.registrationParams - ?: throw IllegalStateException("developer error, no pending three pid") + ?: throw IllegalStateException("developer error, no pending three pid") return performRegistrationRequest(safeParam, LoginType.PASSWORD, delayMillis) } @@ -161,13 +163,13 @@ internal class DefaultRegistrationWizard( private suspend fun validateThreePid(code: String): RegistrationResult { val registrationParams = pendingSessionData.currentThreePidData?.registrationParams - ?: throw IllegalStateException("developer error, no pending three pid") + ?: throw IllegalStateException("developer error, no pending three pid") val safeCurrentData = pendingSessionData.currentThreePidData ?: throw IllegalStateException("developer error, call createAccount() method first") val url = safeCurrentData.addThreePidRegistrationResponse.submitUrl ?: throw IllegalStateException("Missing url to send the code") val validationBody = ValidationCodeBody( - clientSecret = pendingSessionData.clientSecret, - sid = safeCurrentData.addThreePidRegistrationResponse.sid, - code = code + clientSecret = pendingSessionData.clientSecret, + sid = safeCurrentData.addThreePidRegistrationResponse.sid, + code = code ) val validationResponse = validateCodeTask.execute(ValidateCodeTask.Params(url, validationBody)) if (validationResponse.isSuccess()) { @@ -182,16 +184,16 @@ internal class DefaultRegistrationWizard( override suspend fun dummy(): RegistrationResult { val safeSession = pendingSessionData.currentSession - ?: throw IllegalStateException("developer error, call createAccount() method first") + ?: throw IllegalStateException("developer error, call createAccount() method first") val params = RegistrationParams(auth = AuthParams(type = LoginFlowTypes.DUMMY, session = safeSession)) return performRegistrationRequest(params, LoginType.PASSWORD) } private suspend fun performRegistrationRequest( - registrationParams: RegistrationParams, - loginType: LoginType, - delayMillis: Long = 0, + registrationParams: RegistrationParams, + loginType: LoginType, + delayMillis: Long = 0, ): RegistrationResult { delay(delayMillis) val credentials = try { @@ -199,7 +201,7 @@ internal class DefaultRegistrationWizard( } catch (exception: Throwable) { if (exception is RegistrationFlowError) { pendingSessionData = pendingSessionData.copy(currentSession = exception.registrationFlowResponse.session) - .also { pendingSessionStore.savePendingSessionData(it) } + .also { pendingSessionStore.savePendingSessionData(it) } return RegistrationResult.FlowResponse(exception.registrationFlowResponse.toFlowResult()) } else { throw exception diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index f143929978..b2be245c0e 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -69,11 +69,11 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA private val commonOption: (FragmentTransaction) -> Unit = { ft -> // Find the loginLogo on the current Fragment, this should not return null (topFragment?.view as? ViewGroup) - // Find findViewById does not work, I do not know why - // findViewById(R.id.loginLogo) - ?.children - ?.firstOrNull { it.id == R.id.loginLogo } - ?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } + // Find findViewById does not work, I do not know why + // findViewById(R.id.loginLogo) + ?.children + ?.firstOrNull { it.id == R.id.loginLogo } + ?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim) } @@ -107,7 +107,7 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA private fun handleLoginViewEvents(loginViewEvents: LoginViewEvents) { when (loginViewEvents) { - is LoginViewEvents.RegistrationFlowResult -> { + is LoginViewEvents.RegistrationFlowResult -> { // Check that all flows are supported by the application if (loginViewEvents.flowResult.missingStages.any { !it.isSupported() }) { // Display a popup to propose use web fallback @@ -121,80 +121,80 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA // I add a tag to indicate that this fragment is a registration stage. // This way it will be automatically popped in when starting the next registration stage addFragmentToBackstack(views.loginFragmentContainer, - LoginFragment::class.java, - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption + LoginFragment::class.java, + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption ) } } } - is LoginViewEvents.OutdatedHomeserver -> { + is LoginViewEvents.OutdatedHomeserver -> { MaterialAlertDialogBuilder(this) - .setTitle(R.string.login_error_outdated_homeserver_title) - .setMessage(R.string.login_error_outdated_homeserver_warning_content) - .setPositiveButton(R.string.ok, null) - .show() + .setTitle(R.string.login_error_outdated_homeserver_title) + .setMessage(R.string.login_error_outdated_homeserver_warning_content) + .setPositiveButton(R.string.ok, null) + .show() Unit } - is LoginViewEvents.OpenServerSelection -> + is LoginViewEvents.OpenServerSelection -> addFragmentToBackstack(views.loginFragmentContainer, - LoginServerSelectionFragment::class.java, - option = { ft -> - findViewById(R.id.loginSplashLogo)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } - // Disable transition of text - // findViewById(R.id.loginSplashTitle)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } - // No transition here now actually - // findViewById(R.id.loginSplashSubmit)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } - // TODO Disabled because it provokes a flickering - // ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim) - }) - is LoginViewEvents.OnServerSelectionDone -> onServerSelectionDone(loginViewEvents) - is LoginViewEvents.OnSignModeSelected -> onSignModeSelected(loginViewEvents) - is LoginViewEvents.OnLoginFlowRetrieved -> + LoginServerSelectionFragment::class.java, + option = { ft -> + findViewById(R.id.loginSplashLogo)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } + // Disable transition of text + // findViewById(R.id.loginSplashTitle)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } + // No transition here now actually + // findViewById(R.id.loginSplashSubmit)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") } + // TODO Disabled because it provokes a flickering + // ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim) + }) + is LoginViewEvents.OnServerSelectionDone -> onServerSelectionDone(loginViewEvents) + is LoginViewEvents.OnSignModeSelected -> onSignModeSelected(loginViewEvents) + is LoginViewEvents.OnLoginFlowRetrieved -> addFragmentToBackstack(views.loginFragmentContainer, - LoginSignUpSignInSelectionFragment::class.java, - option = commonOption) - is LoginViewEvents.OnWebLoginError -> onWebLoginError(loginViewEvents) - is LoginViewEvents.OnForgetPasswordClicked -> + LoginSignUpSignInSelectionFragment::class.java, + option = commonOption) + is LoginViewEvents.OnWebLoginError -> onWebLoginError(loginViewEvents) + is LoginViewEvents.OnForgetPasswordClicked -> addFragmentToBackstack(views.loginFragmentContainer, - LoginResetPasswordFragment::class.java, - option = commonOption) - is LoginViewEvents.OnResetPasswordSendThreePidDone -> { + LoginResetPasswordFragment::class.java, + option = commonOption) + is LoginViewEvents.OnResetPasswordSendThreePidDone -> { supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) addFragmentToBackstack(views.loginFragmentContainer, - LoginResetPasswordMailConfirmationFragment::class.java, - option = commonOption) + LoginResetPasswordMailConfirmationFragment::class.java, + option = commonOption) } - is LoginViewEvents.OnResetPasswordMailConfirmationSuccess -> { + is LoginViewEvents.OnResetPasswordMailConfirmationSuccess -> { supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) addFragmentToBackstack(views.loginFragmentContainer, - LoginResetPasswordSuccessFragment::class.java, - option = commonOption) + LoginResetPasswordSuccessFragment::class.java, + option = commonOption) } is LoginViewEvents.OnResetPasswordMailConfirmationSuccessDone -> { // Go back to the login fragment supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) } - is LoginViewEvents.OnSendEmailSuccess -> { + is LoginViewEvents.OnSendEmailSuccess -> { // Pop the enter email Fragment supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) addFragmentToBackstack(views.loginFragmentContainer, - LoginWaitForEmailFragment::class.java, - LoginWaitForEmailFragmentArgument(loginViewEvents.email), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) + LoginWaitForEmailFragment::class.java, + LoginWaitForEmailFragmentArgument(loginViewEvents.email), + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption) } - is LoginViewEvents.OnSendMsisdnSuccess -> { + is LoginViewEvents.OnSendMsisdnSuccess -> { // Pop the enter Msisdn Fragment supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) addFragmentToBackstack(views.loginFragmentContainer, - LoginGenericTextInputFormFragment::class.java, - LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.ConfirmMsisdn, true, loginViewEvents.msisdn), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) + LoginGenericTextInputFormFragment::class.java, + LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.ConfirmMsisdn, true, loginViewEvents.msisdn), + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption) } is LoginViewEvents.Failure, - is LoginViewEvents.Loading -> + is LoginViewEvents.Loading -> // This is handled by the Fragments Unit }.exhaustive @@ -207,8 +207,8 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA analyticsScreenName = MobileScreen.ScreenName.Register } val intent = HomeActivity.newIntent( - this, - accountCreation = loginViewState.signMode == SignMode.SignUp + this, + accountCreation = loginViewState.signMode == SignMode.SignUp ) startActivity(intent) finish() @@ -225,55 +225,55 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA // And inform the user MaterialAlertDialogBuilder(this) - .setTitle(R.string.dialog_title_error) - .setMessage(getString(R.string.login_sso_error_message, onWebLoginError.description, onWebLoginError.errorCode)) - .setPositiveButton(R.string.ok, null) - .show() + .setTitle(R.string.dialog_title_error) + .setMessage(getString(R.string.login_sso_error_message, onWebLoginError.description, onWebLoginError.errorCode)) + .setPositiveButton(R.string.ok, null) + .show() } private fun onServerSelectionDone(loginViewEvents: LoginViewEvents.OnServerSelectionDone) { when (loginViewEvents.serverType) { ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow ServerType.EMS, - ServerType.Other -> addFragmentToBackstack(views.loginFragmentContainer, - LoginServerUrlFormFragment::class.java, - option = commonOption) - ServerType.Unknown -> Unit /* Should not happen */ + ServerType.Other -> addFragmentToBackstack(views.loginFragmentContainer, + LoginServerUrlFormFragment::class.java, + option = commonOption) + ServerType.Unknown -> Unit /* Should not happen */ } } private fun onSignModeSelected(loginViewEvents: LoginViewEvents.OnSignModeSelected) = withState(loginViewModel) { state -> // state.signMode could not be ready yet. So use value from the ViewEvent when (loginViewEvents.signMode) { - SignMode.Unknown -> error("Sign mode has to be set before calling this method") - SignMode.SignUp -> { + SignMode.Unknown -> error("Sign mode has to be set before calling this method") + SignMode.SignUp -> { // This is managed by the LoginViewEvents } - SignMode.SignIn -> { + SignMode.SignIn -> { // It depends on the LoginMode when (state.loginMode) { - LoginMode.Unknown, + LoginMode.Unknown -> error("Developer error") is LoginMode.Sso -> launchSsoFlow() is LoginMode.SsoAndPassword, - LoginMode.Password -> addFragmentToBackstack(views.loginFragmentContainer, - LoginFragment::class.java, - tag = FRAGMENT_LOGIN_TAG, - option = commonOption) + LoginMode.Password -> addFragmentToBackstack(views.loginFragmentContainer, + LoginFragment::class.java, + tag = FRAGMENT_LOGIN_TAG, + option = commonOption) LoginMode.Unsupported -> onLoginModeNotSupported(state.loginModeSupportedTypes) }.exhaustive } SignMode.SignInWithMatrixId -> addFragmentToBackstack(views.loginFragmentContainer, - LoginFragment::class.java, - tag = FRAGMENT_LOGIN_TAG, - option = commonOption) + LoginFragment::class.java, + tag = FRAGMENT_LOGIN_TAG, + option = commonOption) }.exhaustive } private fun launchSsoFlow() = withState(loginViewModel) { state -> loginViewModel.getSsoUrl( - redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, - deviceId = state.deviceId, - providerId = null, + redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, + deviceId = state.deviceId, + providerId = null, )?.let { ssoUrl -> openUrlInChromeCustomTab(this, null, ssoUrl) } @@ -286,34 +286,34 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA super.onNewIntent(intent) intent?.data - ?.let { tryOrNull { it.getQueryParameter("loginToken") } } - ?.let { loginViewModel.handle(LoginAction.LoginWithToken(it)) } + ?.let { tryOrNull { it.getQueryParameter("loginToken") } } + ?.let { loginViewModel.handle(LoginAction.LoginWithToken(it)) } } private fun onRegistrationStageNotSupported() { MaterialAlertDialogBuilder(this) - .setTitle(R.string.app_name) - .setMessage(getString(R.string.login_registration_not_supported)) - .setPositiveButton(R.string.yes) { _, _ -> - addFragmentToBackstack(views.loginFragmentContainer, - LoginWebFragment::class.java, - option = commonOption) - } - .setNegativeButton(R.string.no, null) - .show() + .setTitle(R.string.app_name) + .setMessage(getString(R.string.login_registration_not_supported)) + .setPositiveButton(R.string.yes) { _, _ -> + addFragmentToBackstack(views.loginFragmentContainer, + LoginWebFragment::class.java, + option = commonOption) + } + .setNegativeButton(R.string.no, null) + .show() } private fun onLoginModeNotSupported(supportedTypes: List) { MaterialAlertDialogBuilder(this) - .setTitle(R.string.app_name) - .setMessage(getString(R.string.login_mode_not_supported, supportedTypes.joinToString { "'$it'" })) - .setPositiveButton(R.string.yes) { _, _ -> - addFragmentToBackstack(views.loginFragmentContainer, - LoginWebFragment::class.java, - option = commonOption) - } - .setNegativeButton(R.string.no, null) - .show() + .setTitle(R.string.app_name) + .setMessage(getString(R.string.login_mode_not_supported, supportedTypes.joinToString { "'$it'" })) + .setPositiveButton(R.string.yes) { _, _ -> + addFragmentToBackstack(views.loginFragmentContainer, + LoginWebFragment::class.java, + option = commonOption) + } + .setNegativeButton(R.string.no, null) + .show() } private fun handleRegistrationNavigation(flowResult: FlowResult) { @@ -339,26 +339,26 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA when (stage) { is Stage.ReCaptcha -> addFragmentToBackstack(views.loginFragmentContainer, - LoginCaptchaFragment::class.java, - LoginCaptchaFragmentArgument(stage.publicKey), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) - is Stage.Email -> addFragmentToBackstack(views.loginFragmentContainer, - LoginGenericTextInputFormFragment::class.java, - LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetEmail, stage.mandatory), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) - is Stage.Msisdn -> addFragmentToBackstack(views.loginFragmentContainer, - LoginGenericTextInputFormFragment::class.java, - LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetMsisdn, stage.mandatory), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) - is Stage.Terms -> addFragmentToBackstack(views.loginFragmentContainer, - LoginTermsFragment::class.java, - LoginTermsFragmentArgument(stage.policies.toLocalizedLoginTerms(getString(R.string.resources_language))), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) - else -> Unit // Should not happen + LoginCaptchaFragment::class.java, + LoginCaptchaFragmentArgument(stage.publicKey), + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption) + is Stage.Email -> addFragmentToBackstack(views.loginFragmentContainer, + LoginGenericTextInputFormFragment::class.java, + LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetEmail, stage.mandatory), + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption) + is Stage.Msisdn -> addFragmentToBackstack(views.loginFragmentContainer, + LoginGenericTextInputFormFragment::class.java, + LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetMsisdn, stage.mandatory), + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption) + is Stage.Terms -> addFragmentToBackstack(views.loginFragmentContainer, + LoginTermsFragment::class.java, + LoginTermsFragmentArgument(stage.policies.toLocalizedLoginTerms(getString(R.string.resources_language))), + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption) + else -> Unit // Should not happen } }