renaming the ftue domain to onboarding and ftue to ftue auth

This commit is contained in:
Adam Brown 2021-12-09 11:03:34 +00:00
parent 1e5c057223
commit 98078da13d
17 changed files with 232 additions and 209 deletions

View file

@ -140,7 +140,7 @@ android {
buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\"" buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
resValue "string", "build_number", "\"${buildNumber}\"" resValue "string", "build_number", "\"${buildNumber}\""
buildConfigField "im.vector.app.features.VectorFeatures.LoginVariant", "LOGIN_VARIANT", "im.vector.app.features.VectorFeatures.LoginVariant.LEGACY" buildConfigField "im.vector.app.features.VectorFeatures.OnboardingVariant", "ONBOARDING_VARIANT", "im.vector.app.features.VectorFeatures.OnboardingVariant.LEGACY"
buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping" buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping"

View file

@ -27,9 +27,9 @@ class DebugFeaturesStateFactory @Inject constructor(
fun create(): FeaturesState { fun create(): FeaturesState {
return FeaturesState(listOf( return FeaturesState(listOf(
createEnumFeature( createEnumFeature(
label = "Login version", label = "Onboarding variant",
selection = debugFeatures.loginVariant(), selection = debugFeatures.onboardingVariant(),
default = defaultFeatures.loginVariant() default = defaultFeatures.onboardingVariant()
) )
)) ))
} }

View file

@ -38,8 +38,8 @@ class DebugVectorFeatures(
private val dataStore = context.dataStore private val dataStore = context.dataStore
override fun loginVariant(): VectorFeatures.LoginVariant { override fun onboardingVariant(): VectorFeatures.OnboardingVariant {
return readPreferences().getEnum<VectorFeatures.LoginVariant>() ?: vectorFeatures.loginVariant() return readPreferences().getEnum<VectorFeatures.OnboardingVariant>() ?: vectorFeatures.onboardingVariant()
} }
fun <T : Enum<T>> hasEnumOverride(type: KClass<T>) = readPreferences().containsEnum(type) fun <T : Enum<T>> hasEnumOverride(type: KClass<T>) = readPreferences().containsEnum(type)

View file

@ -137,7 +137,7 @@
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity <activity
android:name=".features.ftue.FTUEActivity" android:name=".features.onboarding.OnboardingActivity"
android:launchMode="singleTask" android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />

View file

@ -37,7 +37,6 @@ import im.vector.app.features.crypto.verification.emoji.VerificationEmojiCodeVie
import im.vector.app.features.devtools.RoomDevToolViewModel import im.vector.app.features.devtools.RoomDevToolViewModel
import im.vector.app.features.discovery.DiscoverySettingsViewModel import im.vector.app.features.discovery.DiscoverySettingsViewModel
import im.vector.app.features.discovery.change.SetIdentityServerViewModel import im.vector.app.features.discovery.change.SetIdentityServerViewModel
import im.vector.app.features.ftue.FTUEViewModel
import im.vector.app.features.home.HomeActivityViewModel import im.vector.app.features.home.HomeActivityViewModel
import im.vector.app.features.home.HomeDetailViewModel import im.vector.app.features.home.HomeDetailViewModel
import im.vector.app.features.home.PromoteRestrictedViewModel import im.vector.app.features.home.PromoteRestrictedViewModel
@ -58,6 +57,7 @@ import im.vector.app.features.login.LoginViewModel
import im.vector.app.features.login2.LoginViewModel2 import im.vector.app.features.login2.LoginViewModel2
import im.vector.app.features.login2.created.AccountCreatedViewModel import im.vector.app.features.login2.created.AccountCreatedViewModel
import im.vector.app.features.matrixto.MatrixToBottomSheetViewModel import im.vector.app.features.matrixto.MatrixToBottomSheetViewModel
import im.vector.app.features.onboarding.OnboardingViewModel
import im.vector.app.features.poll.create.CreatePollViewModel import im.vector.app.features.poll.create.CreatePollViewModel
import im.vector.app.features.rageshake.BugReportViewModel import im.vector.app.features.rageshake.BugReportViewModel
import im.vector.app.features.reactions.EmojiSearchResultViewModel import im.vector.app.features.reactions.EmojiSearchResultViewModel
@ -450,8 +450,8 @@ interface MavericksViewModelModule {
@Binds @Binds
@IntoMap @IntoMap
@MavericksViewModelKey(FTUEViewModel::class) @MavericksViewModelKey(OnboardingViewModel::class)
fun ftueViewModelFactory(factory: FTUEViewModel.Factory): MavericksAssistedViewModelFactory<*, *> fun ftueViewModelFactory(factory: OnboardingViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds @Binds
@IntoMap @IntoMap

View file

@ -20,12 +20,12 @@ import im.vector.app.BuildConfig
interface VectorFeatures { interface VectorFeatures {
fun loginVariant(): LoginVariant fun onboardingVariant(): OnboardingVariant
enum class LoginVariant { enum class OnboardingVariant {
LEGACY, LEGACY,
FTUE, LOGIN_2,
FTUE_WIP FTUE_AUTH
} }
enum class NotificationSettingsVersion { enum class NotificationSettingsVersion {
@ -35,5 +35,5 @@ interface VectorFeatures {
} }
class DefaultVectorFeatures : VectorFeatures { class DefaultVectorFeatures : VectorFeatures {
override fun loginVariant(): VectorFeatures.LoginVariant = BuildConfig.LOGIN_VARIANT override fun onboardingVariant(): VectorFeatures.OnboardingVariant = BuildConfig.ONBOARDING_VARIANT
} }

View file

@ -34,12 +34,12 @@ import im.vector.app.core.resources.ColorProvider
import im.vector.app.databinding.DialogBaseEditTextBinding import im.vector.app.databinding.DialogBaseEditTextBinding
import im.vector.app.databinding.FragmentLoginAccountCreatedBinding import im.vector.app.databinding.FragmentLoginAccountCreatedBinding
import im.vector.app.features.displayname.getBestName import im.vector.app.features.displayname.getBestName
import im.vector.app.features.ftue.FTUEActivity
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
import im.vector.app.features.login2.AbstractLoginFragment2 import im.vector.app.features.login2.AbstractLoginFragment2
import im.vector.app.features.login2.LoginAction2 import im.vector.app.features.login2.LoginAction2
import im.vector.app.features.login2.LoginViewState2 import im.vector.app.features.login2.LoginViewState2
import im.vector.app.features.onboarding.OnboardingActivity
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
import java.util.UUID import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
@ -130,7 +130,7 @@ class AccountCreatedFragment @Inject constructor(
private fun invalidateState(state: AccountCreatedViewState) { private fun invalidateState(state: AccountCreatedViewState) {
// Ugly hack... // Ugly hack...
(activity as? FTUEActivity)?.setIsLoading(state.isLoading) (activity as? OnboardingActivity)?.setIsLoading(state.isLoading)
views.loginAccountCreatedSubtitle.text = getString(R.string.login_account_created_subtitle, state.userId) views.loginAccountCreatedSubtitle.text = getString(R.string.login_account_created_subtitle, state.userId)

View file

@ -38,6 +38,7 @@ import im.vector.app.core.error.fatalError
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
import im.vector.app.features.VectorFeatures import im.vector.app.features.VectorFeatures
import im.vector.app.features.VectorFeatures.OnboardingVariant
import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity
import im.vector.app.features.call.conference.JitsiCallViewModel import im.vector.app.features.call.conference.JitsiCallViewModel
import im.vector.app.features.call.conference.VectorJitsiActivity import im.vector.app.features.call.conference.VectorJitsiActivity
@ -51,7 +52,6 @@ import im.vector.app.features.crypto.verification.SupportedVerificationMethodsPr
import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.crypto.verification.VerificationBottomSheet
import im.vector.app.features.debug.DebugMenuActivity import im.vector.app.features.debug.DebugMenuActivity
import im.vector.app.features.devtools.RoomDevToolActivity import im.vector.app.features.devtools.RoomDevToolActivity
import im.vector.app.features.ftue.FTUEActivity
import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.home.room.detail.RoomDetailArgs import im.vector.app.features.home.room.detail.RoomDetailArgs
import im.vector.app.features.home.room.detail.search.SearchActivity import im.vector.app.features.home.room.detail.search.SearchActivity
@ -64,6 +64,7 @@ import im.vector.app.features.matrixto.MatrixToBottomSheet
import im.vector.app.features.media.AttachmentData import im.vector.app.features.media.AttachmentData
import im.vector.app.features.media.BigImageViewerActivity import im.vector.app.features.media.BigImageViewerActivity
import im.vector.app.features.media.VectorAttachmentViewerActivity import im.vector.app.features.media.VectorAttachmentViewerActivity
import im.vector.app.features.onboarding.OnboardingActivity
import im.vector.app.features.pin.PinActivity import im.vector.app.features.pin.PinActivity
import im.vector.app.features.pin.PinArgs import im.vector.app.features.pin.PinArgs
import im.vector.app.features.pin.PinMode import im.vector.app.features.pin.PinMode
@ -111,20 +112,20 @@ class DefaultNavigator @Inject constructor(
) : Navigator { ) : Navigator {
override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) { override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) {
val intent = when (features.loginVariant()) { val intent = when (features.onboardingVariant()) {
VectorFeatures.LoginVariant.LEGACY -> LoginActivity.newIntent(context, loginConfig) OnboardingVariant.LEGACY -> LoginActivity.newIntent(context, loginConfig)
VectorFeatures.LoginVariant.FTUE, OnboardingVariant.LOGIN_2,
VectorFeatures.LoginVariant.FTUE_WIP -> FTUEActivity.newIntent(context, loginConfig) OnboardingVariant.FTUE_AUTH -> OnboardingActivity.newIntent(context, loginConfig)
} }
intent.addFlags(flags) intent.addFlags(flags)
context.startActivity(intent) context.startActivity(intent)
} }
override fun loginSSORedirect(context: Context, data: Uri?) { override fun loginSSORedirect(context: Context, data: Uri?) {
val intent = when (features.loginVariant()) { val intent = when (features.onboardingVariant()) {
VectorFeatures.LoginVariant.LEGACY -> LoginActivity.redirectIntent(context, data) OnboardingVariant.LEGACY -> LoginActivity.redirectIntent(context, data)
VectorFeatures.LoginVariant.FTUE, OnboardingVariant.LOGIN_2,
VectorFeatures.LoginVariant.FTUE_WIP -> FTUEActivity.redirectIntent(context, data) OnboardingVariant.FTUE_AUTH -> OnboardingActivity.redirectIntent(context, data)
} }
context.startActivity(intent) context.startActivity(intent)
} }

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import android.content.Intent import android.content.Intent
import android.view.View import android.view.View
@ -72,12 +72,12 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
private const val FRAGMENT_REGISTRATION_STAGE_TAG = "FRAGMENT_REGISTRATION_STAGE_TAG" private const val FRAGMENT_REGISTRATION_STAGE_TAG = "FRAGMENT_REGISTRATION_STAGE_TAG"
private const val FRAGMENT_LOGIN_TAG = "FRAGMENT_LOGIN_TAG" private const val FRAGMENT_LOGIN_TAG = "FRAGMENT_LOGIN_TAG"
class FTUEWipVariant( class Login2Variant(
private val views: ActivityLoginBinding, private val views: ActivityLoginBinding,
private val loginViewModel: LoginViewModel2, private val loginViewModel: LoginViewModel2,
private val activity: VectorBaseActivity<ActivityLoginBinding>, private val activity: VectorBaseActivity<ActivityLoginBinding>,
private val supportFragmentManager: FragmentManager private val supportFragmentManager: FragmentManager
) : FTUEVariant { ) : OnboardingVariant {
private val enterAnim = R.anim.enter_fade_in private val enterAnim = R.anim.enter_fade_in
private val exitAnim = R.anim.exit_fade_out private val exitAnim = R.anim.exit_fade_out
@ -112,7 +112,7 @@ class FTUEWipVariant(
} }
// Get config extra // Get config extra
val loginConfig = activity.intent.getParcelableExtra<LoginConfig?>(FTUEActivity.EXTRA_CONFIG) val loginConfig = activity.intent.getParcelableExtra<LoginConfig?>(OnboardingActivity.EXTRA_CONFIG)
if (isFirstCreation) { if (isFirstCreation) {
// TODO Check this // TODO Check this
loginViewModel.handle(LoginAction2.InitWith(loginConfig)) loginViewModel.handle(LoginAction2.InitWith(loginConfig))

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import im.vector.app.core.platform.VectorViewModelAction import im.vector.app.core.platform.VectorViewModelAction
import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.LoginConfig
@ -25,23 +25,23 @@ import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider
import org.matrix.android.sdk.api.auth.registration.RegisterThreePid import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
import org.matrix.android.sdk.internal.network.ssl.Fingerprint import org.matrix.android.sdk.internal.network.ssl.Fingerprint
sealed class FTUEAction : VectorViewModelAction { sealed class OnboardingAction : VectorViewModelAction {
data class OnGetStarted(val resetLoginConfig: Boolean) : FTUEAction() data class OnGetStarted(val resetLoginConfig: Boolean) : OnboardingAction()
data class UpdateServerType(val serverType: ServerType) : FTUEAction() data class UpdateServerType(val serverType: ServerType) : OnboardingAction()
data class UpdateHomeServer(val homeServerUrl: String) : FTUEAction() data class UpdateHomeServer(val homeServerUrl: String) : OnboardingAction()
data class UpdateSignMode(val signMode: SignMode) : FTUEAction() data class UpdateSignMode(val signMode: SignMode) : OnboardingAction()
data class LoginWithToken(val loginToken: String) : FTUEAction() data class LoginWithToken(val loginToken: String) : OnboardingAction()
data class WebLoginSuccess(val credentials: Credentials) : FTUEAction() data class WebLoginSuccess(val credentials: Credentials) : OnboardingAction()
data class InitWith(val loginConfig: LoginConfig?) : FTUEAction() data class InitWith(val loginConfig: LoginConfig?) : OnboardingAction()
data class ResetPassword(val email: String, val newPassword: String) : FTUEAction() data class ResetPassword(val email: String, val newPassword: String) : OnboardingAction()
object ResetPasswordMailConfirmed : FTUEAction() object ResetPasswordMailConfirmed : OnboardingAction()
// Login or Register, depending on the signMode // Login or Register, depending on the signMode
data class LoginOrRegister(val username: String, val password: String, val initialDeviceName: String) : FTUEAction() data class LoginOrRegister(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction()
// Register actions // Register actions
open class RegisterAction : FTUEAction() open class RegisterAction : OnboardingAction()
data class AddThreePid(val threePid: RegisterThreePid) : RegisterAction() data class AddThreePid(val threePid: RegisterThreePid) : RegisterAction()
object SendAgainThreePid : RegisterAction() object SendAgainThreePid : RegisterAction()
@ -57,7 +57,7 @@ sealed class FTUEAction : VectorViewModelAction {
object RegisterDummy : RegisterAction() object RegisterDummy : RegisterAction()
// Reset actions // Reset actions
open class ResetAction : FTUEAction() open class ResetAction : OnboardingAction()
object ResetHomeServerType : ResetAction() object ResetHomeServerType : ResetAction()
object ResetHomeServerUrl : ResetAction() object ResetHomeServerUrl : ResetAction()
@ -66,14 +66,14 @@ sealed class FTUEAction : VectorViewModelAction {
object ResetResetPassword : ResetAction() object ResetResetPassword : ResetAction()
// Homeserver history // Homeserver history
object ClearHomeServerHistory : FTUEAction() object ClearHomeServerHistory : OnboardingAction()
// For the soft logout case // For the soft logout case
data class SetupSsoForSessionRecovery(val homeServerUrl: String, data class SetupSsoForSessionRecovery(val homeServerUrl: String,
val deviceId: String, val deviceId: String,
val ssoIdentityProviders: List<SsoIdentityProvider>?) : FTUEAction() val ssoIdentityProviders: List<SsoIdentityProvider>?) : OnboardingAction()
data class PostViewEvent(val viewEvent: FTUEViewEvents) : FTUEAction() data class PostViewEvent(val viewEvent: OnboardingViewEvents) : OnboardingAction()
data class UserAcceptCertificate(val fingerprint: Fingerprint) : FTUEAction() data class UserAcceptCertificate(val fingerprint: Fingerprint) : OnboardingAction()
} }

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -31,13 +31,13 @@ import im.vector.app.features.pin.UnlockedActivity
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class FTUEActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarConfigurable, UnlockedActivity { class OnboardingActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarConfigurable, UnlockedActivity {
private val ftueVariant by lifecycleAwareLazy { private val onboardingVariant by lifecycleAwareLazy {
ftueVariantFactory.create(this, ftueViewModel = lazyViewModel(), loginViewModel2 = lazyViewModel()) onboardingVariantFactory.create(this, onboardingViewModel = lazyViewModel(), loginViewModel2 = lazyViewModel())
} }
@Inject lateinit var ftueVariantFactory: FTUEVariantFactory @Inject lateinit var onboardingVariantFactory: OnboardingVariantFactory
override fun getBinding() = ActivityLoginBinding.inflate(layoutInflater) override fun getBinding() = ActivityLoginBinding.inflate(layoutInflater)
@ -49,37 +49,31 @@ class FTUEActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarConfigur
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent) super.onNewIntent(intent)
ftueVariant.onNewIntent(intent) onboardingVariant.onNewIntent(intent)
} }
override fun initUiAndData() { override fun initUiAndData() {
ftueVariant.initUiAndData(isFirstCreation()) onboardingVariant.initUiAndData(isFirstCreation())
} }
// Hack for AccountCreatedFragment // Hack for AccountCreatedFragment
fun setIsLoading(isLoading: Boolean) { fun setIsLoading(isLoading: Boolean) {
ftueVariant.setIsLoading(isLoading) onboardingVariant.setIsLoading(isLoading)
} }
companion object { companion object {
const val EXTRA_CONFIG = "EXTRA_CONFIG" const val EXTRA_CONFIG = "EXTRA_CONFIG"
fun newIntent(context: Context, loginConfig: LoginConfig?): Intent { fun newIntent(context: Context, loginConfig: LoginConfig?): Intent {
return Intent(context, FTUEActivity::class.java).apply { return Intent(context, OnboardingActivity::class.java).apply {
putExtra(EXTRA_CONFIG, loginConfig) putExtra(EXTRA_CONFIG, loginConfig)
} }
} }
fun redirectIntent(context: Context, data: Uri?): Intent { fun redirectIntent(context: Context, data: Uri?): Intent {
return Intent(context, FTUEActivity::class.java).apply { return Intent(context, OnboardingActivity::class.java).apply {
setData(data) setData(data)
} }
} }
} }
} }
interface FTUEVariant {
fun onNewIntent(intent: Intent?)
fun initUiAndData(isFirstCreation: Boolean)
fun setIsLoading(isLoading: Boolean)
}

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import android.content.Intent import android.content.Intent
import android.view.View import android.view.View
@ -66,12 +66,12 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
private const val FRAGMENT_REGISTRATION_STAGE_TAG = "FRAGMENT_REGISTRATION_STAGE_TAG" private const val FRAGMENT_REGISTRATION_STAGE_TAG = "FRAGMENT_REGISTRATION_STAGE_TAG"
private const val FRAGMENT_LOGIN_TAG = "FRAGMENT_LOGIN_TAG" private const val FRAGMENT_LOGIN_TAG = "FRAGMENT_LOGIN_TAG"
class DefaultFTUEVariant( class OnboardingAuthVariant(
private val views: ActivityLoginBinding, private val views: ActivityLoginBinding,
private val ftueViewModel: FTUEViewModel, private val onboardingViewModel: OnboardingViewModel,
private val activity: VectorBaseActivity<ActivityLoginBinding>, private val activity: VectorBaseActivity<ActivityLoginBinding>,
private val supportFragmentManager: FragmentManager private val supportFragmentManager: FragmentManager
) : FTUEVariant { ) : OnboardingVariant {
private val enterAnim = R.anim.enter_fade_in private val enterAnim = R.anim.enter_fade_in
private val exitAnim = R.anim.exit_fade_out private val exitAnim = R.anim.exit_fade_out
@ -99,16 +99,16 @@ class DefaultFTUEVariant(
} }
with(activity) { with(activity) {
ftueViewModel.onEach { onboardingViewModel.onEach {
updateWithState(it) updateWithState(it)
} }
ftueViewModel.observeViewEvents { handleLoginViewEvents(it) } onboardingViewModel.observeViewEvents { handleLoginViewEvents(it) }
} }
// Get config extra // Get config extra
val loginConfig = activity.intent.getParcelableExtra<LoginConfig?>(FTUEActivity.EXTRA_CONFIG) val loginConfig = activity.intent.getParcelableExtra<LoginConfig?>(OnboardingActivity.EXTRA_CONFIG)
if (isFirstCreation) { if (isFirstCreation) {
ftueViewModel.handle(FTUEAction.InitWith(loginConfig)) onboardingViewModel.handle(OnboardingAction.InitWith(loginConfig))
} }
} }
@ -120,17 +120,17 @@ class DefaultFTUEVariant(
activity.addFragment(views.loginFragmentContainer, LoginSplashFragment::class.java) activity.addFragment(views.loginFragmentContainer, LoginSplashFragment::class.java)
} }
private fun handleLoginViewEvents(ftueViewEvents: FTUEViewEvents) { private fun handleLoginViewEvents(onboardingViewEvents: OnboardingViewEvents) {
when (ftueViewEvents) { when (onboardingViewEvents) {
is FTUEViewEvents.RegistrationFlowResult -> { is OnboardingViewEvents.RegistrationFlowResult -> {
// Check that all flows are supported by the application // Check that all flows are supported by the application
if (ftueViewEvents.flowResult.missingStages.any { !it.isSupported() }) { if (onboardingViewEvents.flowResult.missingStages.any { !it.isSupported() }) {
// Display a popup to propose use web fallback // Display a popup to propose use web fallback
onRegistrationStageNotSupported() onRegistrationStageNotSupported()
} else { } else {
if (ftueViewEvents.isRegistrationStarted) { if (onboardingViewEvents.isRegistrationStarted) {
// Go on with registration flow // Go on with registration flow
handleRegistrationNavigation(ftueViewEvents.flowResult) handleRegistrationNavigation(onboardingViewEvents.flowResult)
} else { } else {
// First ask for login and password // First ask for login and password
// I add a tag to indicate that this fragment is a registration stage. // I add a tag to indicate that this fragment is a registration stage.
@ -143,7 +143,7 @@ class DefaultFTUEVariant(
} }
} }
} }
is FTUEViewEvents.OutdatedHomeserver -> { is OnboardingViewEvents.OutdatedHomeserver -> {
MaterialAlertDialogBuilder(activity) MaterialAlertDialogBuilder(activity)
.setTitle(R.string.login_error_outdated_homeserver_title) .setTitle(R.string.login_error_outdated_homeserver_title)
.setMessage(R.string.login_error_outdated_homeserver_warning_content) .setMessage(R.string.login_error_outdated_homeserver_warning_content)
@ -151,7 +151,7 @@ class DefaultFTUEVariant(
.show() .show()
Unit Unit
} }
is FTUEViewEvents.OpenServerSelection -> is OnboardingViewEvents.OpenServerSelection ->
activity.addFragmentToBackstack(views.loginFragmentContainer, activity.addFragmentToBackstack(views.loginFragmentContainer,
LoginServerSelectionFragment::class.java, LoginServerSelectionFragment::class.java,
option = { ft -> option = { ft ->
@ -163,63 +163,63 @@ class DefaultFTUEVariant(
// TODO Disabled because it provokes a flickering // TODO Disabled because it provokes a flickering
// ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim) // ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
}) })
is FTUEViewEvents.OnServerSelectionDone -> onServerSelectionDone(ftueViewEvents) is OnboardingViewEvents.OnServerSelectionDone -> onServerSelectionDone(onboardingViewEvents)
is FTUEViewEvents.OnSignModeSelected -> onSignModeSelected(ftueViewEvents) is OnboardingViewEvents.OnSignModeSelected -> onSignModeSelected(onboardingViewEvents)
is FTUEViewEvents.OnLoginFlowRetrieved -> is OnboardingViewEvents.OnLoginFlowRetrieved ->
activity.addFragmentToBackstack(views.loginFragmentContainer, activity.addFragmentToBackstack(views.loginFragmentContainer,
LoginSignUpSignInSelectionFragment::class.java, LoginSignUpSignInSelectionFragment::class.java,
option = commonOption) option = commonOption)
is FTUEViewEvents.OnWebLoginError -> onWebLoginError(ftueViewEvents) is OnboardingViewEvents.OnWebLoginError -> onWebLoginError(onboardingViewEvents)
is FTUEViewEvents.OnForgetPasswordClicked -> is OnboardingViewEvents.OnForgetPasswordClicked ->
activity.addFragmentToBackstack(views.loginFragmentContainer, activity.addFragmentToBackstack(views.loginFragmentContainer,
LoginResetPasswordFragment::class.java, LoginResetPasswordFragment::class.java,
option = commonOption) option = commonOption)
is FTUEViewEvents.OnResetPasswordSendThreePidDone -> { is OnboardingViewEvents.OnResetPasswordSendThreePidDone -> {
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
activity.addFragmentToBackstack(views.loginFragmentContainer, activity.addFragmentToBackstack(views.loginFragmentContainer,
LoginResetPasswordMailConfirmationFragment::class.java, LoginResetPasswordMailConfirmationFragment::class.java,
option = commonOption) option = commonOption)
} }
is FTUEViewEvents.OnResetPasswordMailConfirmationSuccess -> { is OnboardingViewEvents.OnResetPasswordMailConfirmationSuccess -> {
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
activity.addFragmentToBackstack(views.loginFragmentContainer, activity.addFragmentToBackstack(views.loginFragmentContainer,
LoginResetPasswordSuccessFragment::class.java, LoginResetPasswordSuccessFragment::class.java,
option = commonOption) option = commonOption)
} }
is FTUEViewEvents.OnResetPasswordMailConfirmationSuccessDone -> { is OnboardingViewEvents.OnResetPasswordMailConfirmationSuccessDone -> {
// Go back to the login fragment // Go back to the login fragment
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
} }
is FTUEViewEvents.OnSendEmailSuccess -> { is OnboardingViewEvents.OnSendEmailSuccess -> {
// Pop the enter email Fragment // Pop the enter email Fragment
supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE)
activity.addFragmentToBackstack(views.loginFragmentContainer, activity.addFragmentToBackstack(views.loginFragmentContainer,
LoginWaitForEmailFragment::class.java, LoginWaitForEmailFragment::class.java,
LoginWaitForEmailFragmentArgument(ftueViewEvents.email), LoginWaitForEmailFragmentArgument(onboardingViewEvents.email),
tag = FRAGMENT_REGISTRATION_STAGE_TAG, tag = FRAGMENT_REGISTRATION_STAGE_TAG,
option = commonOption) option = commonOption)
} }
is FTUEViewEvents.OnSendMsisdnSuccess -> { is OnboardingViewEvents.OnSendMsisdnSuccess -> {
// Pop the enter Msisdn Fragment // Pop the enter Msisdn Fragment
supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE)
activity.addFragmentToBackstack(views.loginFragmentContainer, activity.addFragmentToBackstack(views.loginFragmentContainer,
LoginGenericTextInputFormFragment::class.java, LoginGenericTextInputFormFragment::class.java,
LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.ConfirmMsisdn, true, ftueViewEvents.msisdn), LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.ConfirmMsisdn, true, onboardingViewEvents.msisdn),
tag = FRAGMENT_REGISTRATION_STAGE_TAG, tag = FRAGMENT_REGISTRATION_STAGE_TAG,
option = commonOption) option = commonOption)
} }
is FTUEViewEvents.Failure, is OnboardingViewEvents.Failure,
is FTUEViewEvents.Loading -> is OnboardingViewEvents.Loading ->
// This is handled by the Fragments // This is handled by the Fragments
Unit Unit
}.exhaustive }.exhaustive
} }
private fun updateWithState(ftueViewState: FTUEViewState) { private fun updateWithState(onboardingViewState: OnboardingViewState) {
if (ftueViewState.isUserLogged()) { if (onboardingViewState.isUserLogged()) {
val intent = HomeActivity.newIntent( val intent = HomeActivity.newIntent(
activity, activity,
accountCreation = ftueViewState.signMode == SignMode.SignUp accountCreation = onboardingViewState.signMode == SignMode.SignUp
) )
activity.startActivity(intent) activity.startActivity(intent)
activity.finish() activity.finish()
@ -227,10 +227,10 @@ class DefaultFTUEVariant(
} }
// Loading // Loading
views.loginLoading.isVisible = ftueViewState.isLoading() views.loginLoading.isVisible = onboardingViewState.isLoading()
} }
private fun onWebLoginError(onWebLoginError: FTUEViewEvents.OnWebLoginError) { private fun onWebLoginError(onWebLoginError: OnboardingViewEvents.OnWebLoginError) {
// Pop the backstack // Pop the backstack
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
@ -242,7 +242,7 @@ class DefaultFTUEVariant(
.show() .show()
} }
private fun onServerSelectionDone(loginViewEvents: FTUEViewEvents.OnServerSelectionDone) { private fun onServerSelectionDone(loginViewEvents: OnboardingViewEvents.OnServerSelectionDone) {
when (loginViewEvents.serverType) { when (loginViewEvents.serverType) {
ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow
ServerType.EMS, ServerType.EMS,
@ -253,7 +253,7 @@ class DefaultFTUEVariant(
} }
} }
private fun onSignModeSelected(loginViewEvents: FTUEViewEvents.OnSignModeSelected) = withState(ftueViewModel) { state -> private fun onSignModeSelected(loginViewEvents: OnboardingViewEvents.OnSignModeSelected) = withState(onboardingViewModel) { state ->
// state.signMode could not be ready yet. So use value from the ViewEvent // state.signMode could not be ready yet. So use value from the ViewEvent
when (loginViewEvents.signMode) { when (loginViewEvents.signMode) {
SignMode.Unknown -> error("Sign mode has to be set before calling this method") SignMode.Unknown -> error("Sign mode has to be set before calling this method")
@ -286,7 +286,7 @@ class DefaultFTUEVariant(
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
intent?.data intent?.data
?.let { tryOrNull { it.getQueryParameter("loginToken") } } ?.let { tryOrNull { it.getQueryParameter("loginToken") } }
?.let { ftueViewModel.handle(FTUEAction.LoginWithToken(it)) } ?.let { onboardingViewModel.handle(OnboardingAction.LoginWithToken(it)) }
} }
private fun onRegistrationStageNotSupported() { private fun onRegistrationStageNotSupported() {

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2021 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.
*/
package im.vector.app.features.onboarding
import android.content.Intent
interface OnboardingVariant {
fun onNewIntent(intent: Intent?)
fun initUiAndData(isFirstCreation: Boolean)
fun setIsLoading(isLoading: Boolean)
}

View file

@ -14,25 +14,28 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import im.vector.app.features.VectorFeatures import im.vector.app.features.VectorFeatures
import im.vector.app.features.login2.LoginViewModel2 import im.vector.app.features.login2.LoginViewModel2
import javax.inject.Inject import javax.inject.Inject
class FTUEVariantFactory @Inject constructor( class OnboardingVariantFactory @Inject constructor(
private val vectorFeatures: VectorFeatures, private val vectorFeatures: VectorFeatures,
) { ) {
fun create(activity: FTUEActivity, ftueViewModel: Lazy<FTUEViewModel>, loginViewModel2: Lazy<LoginViewModel2>) = when (vectorFeatures.loginVariant()) { fun create(activity: OnboardingActivity,
VectorFeatures.LoginVariant.LEGACY -> error("Legacy is not supported by the FTUE") onboardingViewModel: Lazy<OnboardingViewModel>,
VectorFeatures.LoginVariant.FTUE -> DefaultFTUEVariant( loginViewModel2: Lazy<LoginViewModel2>
) = when (vectorFeatures.onboardingVariant()) {
VectorFeatures.OnboardingVariant.LEGACY -> error("Legacy is not supported by the FTUE")
VectorFeatures.OnboardingVariant.FTUE_AUTH -> OnboardingAuthVariant(
views = activity.getBinding(), views = activity.getBinding(),
ftueViewModel = ftueViewModel.value, onboardingViewModel = onboardingViewModel.value,
activity = activity, activity = activity,
supportFragmentManager = activity.supportFragmentManager supportFragmentManager = activity.supportFragmentManager
) )
VectorFeatures.LoginVariant.FTUE_WIP -> FTUEWipVariant( VectorFeatures.OnboardingVariant.LOGIN_2 -> Login2Variant(
views = activity.getBinding(), views = activity.getBinding(),
loginViewModel = loginViewModel2.value, loginViewModel = loginViewModel2.value,
activity = activity, activity = activity,

View file

@ -15,7 +15,7 @@
* *
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import im.vector.app.core.platform.VectorViewEvents import im.vector.app.core.platform.VectorViewEvents
import im.vector.app.features.login.ServerType import im.vector.app.features.login.ServerType
@ -25,26 +25,26 @@ import org.matrix.android.sdk.api.auth.registration.FlowResult
/** /**
* Transient events for Login * Transient events for Login
*/ */
sealed class FTUEViewEvents : VectorViewEvents { sealed class OnboardingViewEvents : VectorViewEvents {
data class Loading(val message: CharSequence? = null) : FTUEViewEvents() data class Loading(val message: CharSequence? = null) : OnboardingViewEvents()
data class Failure(val throwable: Throwable) : FTUEViewEvents() data class Failure(val throwable: Throwable) : OnboardingViewEvents()
data class RegistrationFlowResult(val flowResult: FlowResult, val isRegistrationStarted: Boolean) : FTUEViewEvents() data class RegistrationFlowResult(val flowResult: FlowResult, val isRegistrationStarted: Boolean) : OnboardingViewEvents()
object OutdatedHomeserver : FTUEViewEvents() object OutdatedHomeserver : OnboardingViewEvents()
// Navigation event // Navigation event
object OpenServerSelection : FTUEViewEvents() object OpenServerSelection : OnboardingViewEvents()
data class OnServerSelectionDone(val serverType: ServerType) : FTUEViewEvents() data class OnServerSelectionDone(val serverType: ServerType) : OnboardingViewEvents()
object OnLoginFlowRetrieved : FTUEViewEvents() object OnLoginFlowRetrieved : OnboardingViewEvents()
data class OnSignModeSelected(val signMode: SignMode) : FTUEViewEvents() data class OnSignModeSelected(val signMode: SignMode) : OnboardingViewEvents()
object OnForgetPasswordClicked : FTUEViewEvents() object OnForgetPasswordClicked : OnboardingViewEvents()
object OnResetPasswordSendThreePidDone : FTUEViewEvents() object OnResetPasswordSendThreePidDone : OnboardingViewEvents()
object OnResetPasswordMailConfirmationSuccess : FTUEViewEvents() object OnResetPasswordMailConfirmationSuccess : OnboardingViewEvents()
object OnResetPasswordMailConfirmationSuccessDone : FTUEViewEvents() object OnResetPasswordMailConfirmationSuccessDone : OnboardingViewEvents()
data class OnSendEmailSuccess(val email: String) : FTUEViewEvents() data class OnSendEmailSuccess(val email: String) : OnboardingViewEvents()
data class OnSendMsisdnSuccess(val msisdn: String) : FTUEViewEvents() data class OnSendMsisdnSuccess(val msisdn: String) : OnboardingViewEvents()
data class OnWebLoginError(val errorCode: Int, val description: String, val failingUrl: String) : FTUEViewEvents() data class OnWebLoginError(val errorCode: Int, val description: String, val failingUrl: String) : OnboardingViewEvents()
} }

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
@ -63,8 +63,8 @@ import java.util.concurrent.CancellationException
/** /**
* *
*/ */
class FTUEViewModel @AssistedInject constructor( class OnboardingViewModel @AssistedInject constructor(
@Assisted initialState: FTUEViewState, @Assisted initialState: OnboardingViewState,
private val applicationContext: Context, private val applicationContext: Context,
private val authenticationService: AuthenticationService, private val authenticationService: AuthenticationService,
private val activeSessionHolder: ActiveSessionHolder, private val activeSessionHolder: ActiveSessionHolder,
@ -72,14 +72,14 @@ class FTUEViewModel @AssistedInject constructor(
private val reAuthHelper: ReAuthHelper, private val reAuthHelper: ReAuthHelper,
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
private val homeServerHistoryService: HomeServerHistoryService private val homeServerHistoryService: HomeServerHistoryService
) : VectorViewModel<FTUEViewState, FTUEAction, FTUEViewEvents>(initialState) { ) : VectorViewModel<OnboardingViewState, OnboardingAction, OnboardingViewEvents>(initialState) {
@AssistedFactory @AssistedFactory
interface Factory : MavericksAssistedViewModelFactory<FTUEViewModel, FTUEViewState> { interface Factory : MavericksAssistedViewModelFactory<OnboardingViewModel, OnboardingViewState> {
override fun create(initialState: FTUEViewState): FTUEViewModel override fun create(initialState: OnboardingViewState): OnboardingViewModel
} }
companion object : MavericksViewModelFactory<FTUEViewModel, FTUEViewState> by hiltMavericksViewModelFactory() companion object : MavericksViewModelFactory<OnboardingViewModel, OnboardingViewState> by hiltMavericksViewModelFactory()
init { init {
getKnownCustomHomeServersUrls() getKnownCustomHomeServersUrls()
@ -92,7 +92,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
// Store the last action, to redo it after user has trusted the untrusted certificate // Store the last action, to redo it after user has trusted the untrusted certificate
private var lastAction: FTUEAction? = null private var lastAction: OnboardingAction? = null
private var currentHomeServerConnectionConfig: HomeServerConnectionConfig? = null private var currentHomeServerConnectionConfig: HomeServerConnectionConfig? = null
private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash()
@ -119,28 +119,28 @@ class FTUEViewModel @AssistedInject constructor(
field = value field = value
} }
override fun handle(action: FTUEAction) { override fun handle(action: OnboardingAction) {
when (action) { when (action) {
is FTUEAction.OnGetStarted -> handleOnGetStarted(action) is OnboardingAction.OnGetStarted -> handleOnGetStarted(action)
is FTUEAction.UpdateServerType -> handleUpdateServerType(action) is OnboardingAction.UpdateServerType -> handleUpdateServerType(action)
is FTUEAction.UpdateSignMode -> handleUpdateSignMode(action) is OnboardingAction.UpdateSignMode -> handleUpdateSignMode(action)
is FTUEAction.InitWith -> handleInitWith(action) is OnboardingAction.InitWith -> handleInitWith(action)
is FTUEAction.UpdateHomeServer -> handleUpdateHomeserver(action).also { lastAction = action } is OnboardingAction.UpdateHomeServer -> handleUpdateHomeserver(action).also { lastAction = action }
is FTUEAction.LoginOrRegister -> handleLoginOrRegister(action).also { lastAction = action } is OnboardingAction.LoginOrRegister -> handleLoginOrRegister(action).also { lastAction = action }
is FTUEAction.LoginWithToken -> handleLoginWithToken(action) is OnboardingAction.LoginWithToken -> handleLoginWithToken(action)
is FTUEAction.WebLoginSuccess -> handleWebLoginSuccess(action) is OnboardingAction.WebLoginSuccess -> handleWebLoginSuccess(action)
is FTUEAction.ResetPassword -> handleResetPassword(action) is OnboardingAction.ResetPassword -> handleResetPassword(action)
is FTUEAction.ResetPasswordMailConfirmed -> handleResetPasswordMailConfirmed() is OnboardingAction.ResetPasswordMailConfirmed -> handleResetPasswordMailConfirmed()
is FTUEAction.RegisterAction -> handleRegisterAction(action) is OnboardingAction.RegisterAction -> handleRegisterAction(action)
is FTUEAction.ResetAction -> handleResetAction(action) is OnboardingAction.ResetAction -> handleResetAction(action)
is FTUEAction.SetupSsoForSessionRecovery -> handleSetupSsoForSessionRecovery(action) is OnboardingAction.SetupSsoForSessionRecovery -> handleSetupSsoForSessionRecovery(action)
is FTUEAction.UserAcceptCertificate -> handleUserAcceptCertificate(action) is OnboardingAction.UserAcceptCertificate -> handleUserAcceptCertificate(action)
FTUEAction.ClearHomeServerHistory -> handleClearHomeServerHistory() OnboardingAction.ClearHomeServerHistory -> handleClearHomeServerHistory()
is FTUEAction.PostViewEvent -> _viewEvents.post(action.viewEvent) is OnboardingAction.PostViewEvent -> _viewEvents.post(action.viewEvent)
}.exhaustive }.exhaustive
} }
private fun handleOnGetStarted(action: FTUEAction.OnGetStarted) { private fun handleOnGetStarted(action: OnboardingAction.OnGetStarted) {
if (action.resetLoginConfig) { if (action.resetLoginConfig) {
loginConfig = null loginConfig = null
} }
@ -152,25 +152,25 @@ class FTUEViewModel @AssistedInject constructor(
if (homeServerConnectionConfig == null) { if (homeServerConnectionConfig == null) {
// Url is invalid, in this case, just use the regular flow // Url is invalid, in this case, just use the regular flow
Timber.w("Url from config url was invalid: $configUrl") Timber.w("Url from config url was invalid: $configUrl")
_viewEvents.post(FTUEViewEvents.OpenServerSelection) _viewEvents.post(OnboardingViewEvents.OpenServerSelection)
} else { } else {
getLoginFlow(homeServerConnectionConfig, ServerType.Other) getLoginFlow(homeServerConnectionConfig, ServerType.Other)
} }
} else { } else {
_viewEvents.post(FTUEViewEvents.OpenServerSelection) _viewEvents.post(OnboardingViewEvents.OpenServerSelection)
} }
} }
private fun handleUserAcceptCertificate(action: FTUEAction.UserAcceptCertificate) { private fun handleUserAcceptCertificate(action: OnboardingAction.UserAcceptCertificate) {
// It happens when we get the login flow, or during direct authentication. // It happens when we get the login flow, or during direct authentication.
// So alter the homeserver config and retrieve again the login flow // So alter the homeserver config and retrieve again the login flow
when (val finalLastAction = lastAction) { when (val finalLastAction = lastAction) {
is FTUEAction.UpdateHomeServer -> { is OnboardingAction.UpdateHomeServer -> {
currentHomeServerConnectionConfig currentHomeServerConnectionConfig
?.let { it.copy(allowedFingerprints = it.allowedFingerprints + action.fingerprint) } ?.let { it.copy(allowedFingerprints = it.allowedFingerprints + action.fingerprint) }
?.let { getLoginFlow(it) } ?.let { getLoginFlow(it) }
} }
is FTUEAction.LoginOrRegister -> is OnboardingAction.LoginOrRegister ->
handleDirectLogin( handleDirectLogin(
finalLastAction, finalLastAction,
HomeServerConnectionConfig.Builder() HomeServerConnectionConfig.Builder()
@ -192,7 +192,7 @@ class FTUEViewModel @AssistedInject constructor(
getKnownCustomHomeServersUrls() getKnownCustomHomeServersUrls()
} }
private fun handleLoginWithToken(action: FTUEAction.LoginWithToken) { private fun handleLoginWithToken(action: OnboardingAction.LoginWithToken) {
val safeLoginWizard = loginWizard val safeLoginWizard = loginWizard
if (safeLoginWizard == null) { if (safeLoginWizard == null) {
@ -212,7 +212,7 @@ class FTUEViewModel @AssistedInject constructor(
try { try {
safeLoginWizard.loginWithToken(action.loginToken) safeLoginWizard.loginWithToken(action.loginToken)
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(FTUEViewEvents.Failure(failure)) _viewEvents.post(OnboardingViewEvents.Failure(failure))
setState { setState {
copy( copy(
asyncLoginAction = Fail(failure) asyncLoginAction = Fail(failure)
@ -225,7 +225,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleSetupSsoForSessionRecovery(action: FTUEAction.SetupSsoForSessionRecovery) { private fun handleSetupSsoForSessionRecovery(action: OnboardingAction.SetupSsoForSessionRecovery) {
setState { setState {
copy( copy(
signMode = SignMode.SignIn, signMode = SignMode.SignIn,
@ -237,20 +237,20 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleRegisterAction(action: FTUEAction.RegisterAction) { private fun handleRegisterAction(action: OnboardingAction.RegisterAction) {
when (action) { when (action) {
is FTUEAction.CaptchaDone -> handleCaptchaDone(action) is OnboardingAction.CaptchaDone -> handleCaptchaDone(action)
is FTUEAction.AcceptTerms -> handleAcceptTerms() is OnboardingAction.AcceptTerms -> handleAcceptTerms()
is FTUEAction.RegisterDummy -> handleRegisterDummy() is OnboardingAction.RegisterDummy -> handleRegisterDummy()
is FTUEAction.AddThreePid -> handleAddThreePid(action) is OnboardingAction.AddThreePid -> handleAddThreePid(action)
is FTUEAction.SendAgainThreePid -> handleSendAgainThreePid() is OnboardingAction.SendAgainThreePid -> handleSendAgainThreePid()
is FTUEAction.ValidateThreePid -> handleValidateThreePid(action) is OnboardingAction.ValidateThreePid -> handleValidateThreePid(action)
is FTUEAction.CheckIfEmailHasBeenValidated -> handleCheckIfEmailHasBeenValidated(action) is OnboardingAction.CheckIfEmailHasBeenValidated -> handleCheckIfEmailHasBeenValidated(action)
is FTUEAction.StopEmailValidationCheck -> handleStopEmailValidationCheck() is OnboardingAction.StopEmailValidationCheck -> handleStopEmailValidationCheck()
} }
} }
private fun handleCheckIfEmailHasBeenValidated(action: FTUEAction.CheckIfEmailHasBeenValidated) { private fun handleCheckIfEmailHasBeenValidated(action: OnboardingAction.CheckIfEmailHasBeenValidated) {
// We do not want the common progress bar to be displayed, so we do not change asyncRegistration value in the state // We do not want the common progress bar to be displayed, so we do not change asyncRegistration value in the state
currentJob = executeRegistrationStep(withLoading = false) { currentJob = executeRegistrationStep(withLoading = false) {
it.checkIfEmailHasBeenValidated(action.delayMillis) it.checkIfEmailHasBeenValidated(action.delayMillis)
@ -261,7 +261,7 @@ class FTUEViewModel @AssistedInject constructor(
currentJob = null currentJob = null
} }
private fun handleValidateThreePid(action: FTUEAction.ValidateThreePid) { private fun handleValidateThreePid(action: OnboardingAction.ValidateThreePid) {
currentJob = executeRegistrationStep { currentJob = executeRegistrationStep {
it.handleValidateThreePid(action.code) it.handleValidateThreePid(action.code)
} }
@ -284,7 +284,7 @@ class FTUEViewModel @AssistedInject constructor(
*/ */
} catch (failure: Throwable) { } catch (failure: Throwable) {
if (failure !is CancellationException) { if (failure !is CancellationException) {
_viewEvents.post(FTUEViewEvents.Failure(failure)) _viewEvents.post(OnboardingViewEvents.Failure(failure))
} }
null null
} }
@ -303,13 +303,13 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleAddThreePid(action: FTUEAction.AddThreePid) { private fun handleAddThreePid(action: OnboardingAction.AddThreePid) {
setState { copy(asyncRegistration = Loading()) } setState { copy(asyncRegistration = Loading()) }
currentJob = viewModelScope.launch { currentJob = viewModelScope.launch {
try { try {
registrationWizard?.addThreePid(action.threePid) registrationWizard?.addThreePid(action.threePid)
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(FTUEViewEvents.Failure(failure)) _viewEvents.post(OnboardingViewEvents.Failure(failure))
} }
setState { setState {
copy( copy(
@ -325,7 +325,7 @@ class FTUEViewModel @AssistedInject constructor(
try { try {
registrationWizard?.sendAgainThreePid() registrationWizard?.sendAgainThreePid()
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(FTUEViewEvents.Failure(failure)) _viewEvents.post(OnboardingViewEvents.Failure(failure))
} }
setState { setState {
copy( copy(
@ -347,7 +347,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleRegisterWith(action: FTUEAction.LoginOrRegister) { private fun handleRegisterWith(action: OnboardingAction.LoginOrRegister) {
reAuthHelper.data = action.password reAuthHelper.data = action.password
currentJob = executeRegistrationStep { currentJob = executeRegistrationStep {
it.createAccount( it.createAccount(
@ -358,25 +358,25 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleCaptchaDone(action: FTUEAction.CaptchaDone) { private fun handleCaptchaDone(action: OnboardingAction.CaptchaDone) {
currentJob = executeRegistrationStep { currentJob = executeRegistrationStep {
it.performReCaptcha(action.captchaResponse) it.performReCaptcha(action.captchaResponse)
} }
} }
private fun handleResetAction(action: FTUEAction.ResetAction) { private fun handleResetAction(action: OnboardingAction.ResetAction) {
// Cancel any request // Cancel any request
currentJob = null currentJob = null
when (action) { when (action) {
FTUEAction.ResetHomeServerType -> { OnboardingAction.ResetHomeServerType -> {
setState { setState {
copy( copy(
serverType = ServerType.Unknown serverType = ServerType.Unknown
) )
} }
} }
FTUEAction.ResetHomeServerUrl -> { OnboardingAction.ResetHomeServerUrl -> {
viewModelScope.launch { viewModelScope.launch {
authenticationService.reset() authenticationService.reset()
setState { setState {
@ -391,7 +391,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
} }
FTUEAction.ResetSignMode -> { OnboardingAction.ResetSignMode -> {
setState { setState {
copy( copy(
asyncHomeServerLoginFlowRequest = Uninitialized, asyncHomeServerLoginFlowRequest = Uninitialized,
@ -401,7 +401,7 @@ class FTUEViewModel @AssistedInject constructor(
) )
} }
} }
FTUEAction.ResetLogin -> { OnboardingAction.ResetLogin -> {
viewModelScope.launch { viewModelScope.launch {
authenticationService.cancelPendingLoginOrRegistration() authenticationService.cancelPendingLoginOrRegistration()
setState { setState {
@ -412,7 +412,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
} }
FTUEAction.ResetResetPassword -> { OnboardingAction.ResetResetPassword -> {
setState { setState {
copy( copy(
asyncResetPassword = Uninitialized, asyncResetPassword = Uninitialized,
@ -424,7 +424,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleUpdateSignMode(action: FTUEAction.UpdateSignMode) { private fun handleUpdateSignMode(action: OnboardingAction.UpdateSignMode) {
setState { setState {
copy( copy(
signMode = action.signMode signMode = action.signMode
@ -434,12 +434,12 @@ class FTUEViewModel @AssistedInject constructor(
when (action.signMode) { when (action.signMode) {
SignMode.SignUp -> startRegistrationFlow() SignMode.SignUp -> startRegistrationFlow()
SignMode.SignIn -> startAuthenticationFlow() SignMode.SignIn -> startAuthenticationFlow()
SignMode.SignInWithMatrixId -> _viewEvents.post(FTUEViewEvents.OnSignModeSelected(SignMode.SignInWithMatrixId)) SignMode.SignInWithMatrixId -> _viewEvents.post(OnboardingViewEvents.OnSignModeSelected(SignMode.SignInWithMatrixId))
SignMode.Unknown -> Unit SignMode.Unknown -> Unit
} }
} }
private fun handleUpdateServerType(action: FTUEAction.UpdateServerType) { private fun handleUpdateServerType(action: OnboardingAction.UpdateServerType) {
setState { setState {
copy( copy(
serverType = action.serverType serverType = action.serverType
@ -450,20 +450,20 @@ class FTUEViewModel @AssistedInject constructor(
ServerType.Unknown -> Unit /* Should not happen */ ServerType.Unknown -> Unit /* Should not happen */
ServerType.MatrixOrg -> ServerType.MatrixOrg ->
// Request login flow here // Request login flow here
handle(FTUEAction.UpdateHomeServer(matrixOrgUrl)) handle(OnboardingAction.UpdateHomeServer(matrixOrgUrl))
ServerType.EMS, ServerType.EMS,
ServerType.Other -> _viewEvents.post(FTUEViewEvents.OnServerSelectionDone(action.serverType)) ServerType.Other -> _viewEvents.post(OnboardingViewEvents.OnServerSelectionDone(action.serverType))
}.exhaustive }.exhaustive
} }
private fun handleInitWith(action: FTUEAction.InitWith) { private fun handleInitWith(action: OnboardingAction.InitWith) {
loginConfig = action.loginConfig loginConfig = action.loginConfig
// If there is a pending email validation continue on this step // If there is a pending email validation continue on this step
try { try {
if (registrationWizard?.isRegistrationStarted == true) { if (registrationWizard?.isRegistrationStarted == true) {
currentThreePid?.let { currentThreePid?.let {
handle(FTUEAction.PostViewEvent(FTUEViewEvents.OnSendEmailSuccess(it))) handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnSendEmailSuccess(it)))
} }
} }
} catch (e: Throwable) { } catch (e: Throwable) {
@ -472,7 +472,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleResetPassword(action: FTUEAction.ResetPassword) { private fun handleResetPassword(action: OnboardingAction.ResetPassword) {
val safeLoginWizard = loginWizard val safeLoginWizard = loginWizard
if (safeLoginWizard == null) { if (safeLoginWizard == null) {
@ -509,7 +509,7 @@ class FTUEViewModel @AssistedInject constructor(
) )
} }
_viewEvents.post(FTUEViewEvents.OnResetPasswordSendThreePidDone) _viewEvents.post(OnboardingViewEvents.OnResetPasswordSendThreePidDone)
} }
} }
} }
@ -550,12 +550,12 @@ class FTUEViewModel @AssistedInject constructor(
) )
} }
_viewEvents.post(FTUEViewEvents.OnResetPasswordMailConfirmationSuccess) _viewEvents.post(OnboardingViewEvents.OnResetPasswordMailConfirmationSuccess)
} }
} }
} }
private fun handleLoginOrRegister(action: FTUEAction.LoginOrRegister) = withState { state -> private fun handleLoginOrRegister(action: OnboardingAction.LoginOrRegister) = withState { state ->
when (state.signMode) { when (state.signMode) {
SignMode.Unknown -> error("Developer error, invalid sign mode") SignMode.Unknown -> error("Developer error, invalid sign mode")
SignMode.SignIn -> handleLogin(action) SignMode.SignIn -> handleLogin(action)
@ -564,7 +564,7 @@ class FTUEViewModel @AssistedInject constructor(
}.exhaustive }.exhaustive
} }
private fun handleDirectLogin(action: FTUEAction.LoginOrRegister, homeServerConnectionConfig: HomeServerConnectionConfig?) { private fun handleDirectLogin(action: OnboardingAction.LoginOrRegister, homeServerConnectionConfig: HomeServerConnectionConfig?) {
setState { setState {
copy( copy(
asyncLoginAction = Loading() asyncLoginAction = Loading()
@ -601,10 +601,10 @@ class FTUEViewModel @AssistedInject constructor(
asyncLoginAction = Uninitialized asyncLoginAction = Uninitialized
) )
} }
_viewEvents.post(FTUEViewEvents.Failure(Exception(stringProvider.getString(R.string.autodiscover_well_known_error)))) _viewEvents.post(OnboardingViewEvents.Failure(Exception(stringProvider.getString(R.string.autodiscover_well_known_error))))
} }
private suspend fun onWellknownSuccess(action: FTUEAction.LoginOrRegister, private suspend fun onWellknownSuccess(action: OnboardingAction.LoginOrRegister,
wellKnownPrompt: WellknownResult.Prompt, wellKnownPrompt: WellknownResult.Prompt,
homeServerConnectionConfig: HomeServerConnectionConfig?) { homeServerConnectionConfig: HomeServerConnectionConfig?) {
val alteredHomeServerConnectionConfig = homeServerConnectionConfig val alteredHomeServerConnectionConfig = homeServerConnectionConfig
@ -636,7 +636,7 @@ class FTUEViewModel @AssistedInject constructor(
is MatrixIdFailure.InvalidMatrixId, is MatrixIdFailure.InvalidMatrixId,
is Failure.UnrecognizedCertificateFailure -> { is Failure.UnrecognizedCertificateFailure -> {
// Display this error in a dialog // Display this error in a dialog
_viewEvents.post(FTUEViewEvents.Failure(failure)) _viewEvents.post(OnboardingViewEvents.Failure(failure))
setState { setState {
copy( copy(
asyncLoginAction = Uninitialized asyncLoginAction = Uninitialized
@ -653,7 +653,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleLogin(action: FTUEAction.LoginOrRegister) { private fun handleLogin(action: OnboardingAction.LoginOrRegister) {
val safeLoginWizard = loginWizard val safeLoginWizard = loginWizard
if (safeLoginWizard == null) { if (safeLoginWizard == null) {
@ -702,7 +702,7 @@ class FTUEViewModel @AssistedInject constructor(
// Ensure Wizard is ready // Ensure Wizard is ready
loginWizard loginWizard
_viewEvents.post(FTUEViewEvents.OnSignModeSelected(SignMode.SignIn)) _viewEvents.post(OnboardingViewEvents.OnSignModeSelected(SignMode.SignIn))
} }
private fun onFlowResponse(flowResult: FlowResult) { private fun onFlowResponse(flowResult: FlowResult) {
@ -712,7 +712,7 @@ class FTUEViewModel @AssistedInject constructor(
handleRegisterDummy() handleRegisterDummy()
} else { } else {
// Notify the user // Notify the user
_viewEvents.post(FTUEViewEvents.RegistrationFlowResult(flowResult, isRegistrationStarted)) _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(flowResult, isRegistrationStarted))
} }
} }
@ -728,7 +728,7 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleWebLoginSuccess(action: FTUEAction.WebLoginSuccess) = withState { state -> private fun handleWebLoginSuccess(action: OnboardingAction.WebLoginSuccess) = withState { state ->
val homeServerConnectionConfigFinal = homeServerConnectionConfigFactory.create(state.homeServerUrl) val homeServerConnectionConfigFinal = homeServerConnectionConfigFactory.create(state.homeServerUrl)
if (homeServerConnectionConfigFinal == null) { if (homeServerConnectionConfigFinal == null) {
@ -749,11 +749,11 @@ class FTUEViewModel @AssistedInject constructor(
} }
} }
private fun handleUpdateHomeserver(action: FTUEAction.UpdateHomeServer) { private fun handleUpdateHomeserver(action: OnboardingAction.UpdateHomeServer) {
val homeServerConnectionConfig = homeServerConnectionConfigFactory.create(action.homeServerUrl) val homeServerConnectionConfig = homeServerConnectionConfigFactory.create(action.homeServerUrl)
if (homeServerConnectionConfig == null) { if (homeServerConnectionConfig == null) {
// This is invalid // This is invalid
_viewEvents.post(FTUEViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig"))) _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig")))
} else { } else {
getLoginFlow(homeServerConnectionConfig) getLoginFlow(homeServerConnectionConfig)
} }
@ -782,7 +782,7 @@ class FTUEViewModel @AssistedInject constructor(
val data = try { val data = try {
authenticationService.getLoginFlow(homeServerConnectionConfig) authenticationService.getLoginFlow(homeServerConnectionConfig)
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(FTUEViewEvents.Failure(failure)) _viewEvents.post(OnboardingViewEvents.Failure(failure))
setState { setState {
copy( copy(
asyncHomeServerLoginFlowRequest = Uninitialized, asyncHomeServerLoginFlowRequest = Uninitialized,
@ -820,9 +820,9 @@ class FTUEViewModel @AssistedInject constructor(
if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) || if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) ||
data.isOutdatedHomeserver) { data.isOutdatedHomeserver) {
// Notify the UI // Notify the UI
_viewEvents.post(FTUEViewEvents.OutdatedHomeserver) _viewEvents.post(OnboardingViewEvents.OutdatedHomeserver)
} }
_viewEvents.post(FTUEViewEvents.OnLoginFlowRetrieved) _viewEvents.post(OnboardingViewEvents.OnLoginFlowRetrieved)
} }
} }

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.features.ftue package im.vector.app.features.onboarding
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Loading
@ -26,7 +26,7 @@ import im.vector.app.features.login.LoginMode
import im.vector.app.features.login.ServerType import im.vector.app.features.login.ServerType
import im.vector.app.features.login.SignMode import im.vector.app.features.login.SignMode
data class FTUEViewState( data class OnboardingViewState(
val asyncLoginAction: Async<Unit> = Uninitialized, val asyncLoginAction: Async<Unit> = Uninitialized,
val asyncHomeServerLoginFlowRequest: Async<Unit> = Uninitialized, val asyncHomeServerLoginFlowRequest: Async<Unit> = Uninitialized,
val asyncResetPassword: Async<Unit> = Uninitialized, val asyncResetPassword: Async<Unit> = Uninitialized,