diff --git a/changelog.d/5285.wip b/changelog.d/5285.wip new file mode 100644 index 0000000000..1dd68597be --- /dev/null +++ b/changelog.d/5285.wip @@ -0,0 +1 @@ +FTUE - Adds Sign Up tracking diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/SignUpExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/SignUpExt.kt new file mode 100644 index 0000000000..e63aafbfc4 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/SignUpExt.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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.analytics.extensions + +import im.vector.app.features.analytics.plan.Signup +import im.vector.app.features.onboarding.AuthenticationDescription + +fun AuthenticationDescription.AuthenticationType.toAnalyticsType() = when (this) { + AuthenticationDescription.AuthenticationType.Password -> Signup.AuthenticationType.Password + AuthenticationDescription.AuthenticationType.Apple -> Signup.AuthenticationType.Apple + AuthenticationDescription.AuthenticationType.Facebook -> Signup.AuthenticationType.Facebook + AuthenticationDescription.AuthenticationType.GitHub -> Signup.AuthenticationType.GitHub + AuthenticationDescription.AuthenticationType.GitLab -> Signup.AuthenticationType.GitLab + AuthenticationDescription.AuthenticationType.Google -> Signup.AuthenticationType.Google + AuthenticationDescription.AuthenticationType.SSO -> Signup.AuthenticationType.SSO + AuthenticationDescription.AuthenticationType.Other -> Signup.AuthenticationType.Other +} diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 9fe1e00ae7..2ccb34fde9 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -56,6 +56,7 @@ import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.navigation.Navigator import im.vector.app.features.notifications.NotificationDrawerManager +import im.vector.app.features.onboarding.AuthenticationDescription import im.vector.app.features.permalink.NavigationInterceptor import im.vector.app.features.permalink.PermalinkHandler import im.vector.app.features.permalink.PermalinkHandler.Companion.MATRIX_TO_CUSTOM_SCHEME_URL_BASE @@ -91,7 +92,7 @@ import javax.inject.Inject @Parcelize data class HomeActivityArgs( val clearNotification: Boolean, - val accountCreation: Boolean, + val authenticationDescription: AuthenticationDescription? = null, val hasExistingSession: Boolean = false, val inviteNotificationRoomId: String? = null ) : Parcelable @@ -612,13 +613,13 @@ class HomeActivity : fun newIntent( context: Context, clearNotification: Boolean = false, - accountCreation: Boolean = false, + authenticationDescription: AuthenticationDescription? = null, existingSession: Boolean = false, inviteNotificationRoomId: String? = null ): Intent { val args = HomeActivityArgs( clearNotification = clearNotification, - accountCreation = accountCreation, + authenticationDescription = authenticationDescription, hasExistingSession = existingSession, inviteNotificationRoomId = inviteNotificationRoomId ) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 5d441d4b59..2494f398bb 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -28,8 +28,12 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.analytics.AnalyticsTracker +import im.vector.app.features.analytics.extensions.toAnalyticsType +import im.vector.app.features.analytics.plan.Signup import im.vector.app.features.analytics.store.AnalyticsStore import im.vector.app.features.login.ReAuthHelper +import im.vector.app.features.onboarding.AuthenticationDescription import im.vector.app.features.raw.wellknown.ElementWellKnown import im.vector.app.features.raw.wellknown.getElementWellknown import im.vector.app.features.raw.wellknown.isSecureBackupRequired @@ -38,8 +42,11 @@ import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor @@ -73,7 +80,8 @@ class HomeActivityViewModel @AssistedInject constructor( private val reAuthHelper: ReAuthHelper, private val analyticsStore: AnalyticsStore, private val lightweightSettingsStorage: LightweightSettingsStorage, - private val vectorPreferences: VectorPreferences + private val vectorPreferences: VectorPreferences, + private val analyticsTracker: AnalyticsTracker ) : VectorViewModel(initialState) { @AssistedFactory @@ -85,7 +93,7 @@ class HomeActivityViewModel @AssistedInject constructor( override fun initialState(viewModelContext: ViewModelContext): HomeActivityViewState? { val activity: HomeActivity = viewModelContext.activity() val args: HomeActivityArgs? = activity.intent.getParcelableExtra(Mavericks.KEY_ARG) - return args?.let { HomeActivityViewState(accountCreation = it.accountCreation) } + return args?.let { HomeActivityViewState(authenticationDescription = it.authenticationDescription) } ?: super.initialState(viewModelContext) } } @@ -114,9 +122,32 @@ class HomeActivityViewModel @AssistedInject constructor( } } .launchIn(viewModelScope) + + when (val recentAuthentication = initialState.authenticationDescription) { + is AuthenticationDescription.Register -> { + viewModelScope.launch { + analyticsStore.onUserGaveConsent { + analyticsTracker.capture(Signup(authenticationType = recentAuthentication.type.toAnalyticsType())) + } + } + } + AuthenticationDescription.Login -> { + // do nothing + } + null -> { + // do nothing + } + } } } + private suspend fun AnalyticsStore.onUserGaveConsent(action: () -> Unit) { + userConsentFlow + .takeWhile { !it } + .onCompletion { action() } + .collect() + } + private fun cleanupFiles() { // Mitigation: delete all cached decrypted files each time the application is started. activeSessionHolder.getSafeActiveSession()?.fileService()?.clearDecryptedCache() @@ -191,10 +222,10 @@ class HomeActivityViewModel @AssistedInject constructor( .asFlow() .onEach { status -> when (status) { - is SyncStatusService.Status.Idle -> { + is SyncStatusService.Status.Idle -> { maybeVerifyOrBootstrapCrossSigning() } - else -> Unit + else -> Unit } setState { @@ -285,7 +316,7 @@ class HomeActivityViewModel @AssistedInject constructor( val isSecureBackupRequired = elementWellKnown?.isSecureBackupRequired() ?: false // In case of account creation, it is already done before - if (initialState.accountCreation) { + if (initialState.authenticationDescription is AuthenticationDescription.Register) { if (isSecureBackupRequired) { _viewEvents.post(HomeActivityViewEvents.StartRecoverySetupFlow) } else { diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt index 45fe04fc61..95ab75549f 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewState.kt @@ -17,9 +17,10 @@ package im.vector.app.features.home import com.airbnb.mvrx.MavericksState +import im.vector.app.features.onboarding.AuthenticationDescription import org.matrix.android.sdk.api.session.initsync.SyncStatusService data class HomeActivityViewState( val syncStatusServiceStatus: SyncStatusService.Status = SyncStatusService.Status.Idle, - val accountCreation: Boolean = false + val authenticationDescription: AuthenticationDescription? = null ) : MavericksState 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 42a9b18558..f763d26bf5 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 @@ -42,6 +42,7 @@ import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.HomeActivity import im.vector.app.features.login.terms.LoginTermsFragment import im.vector.app.features.login.terms.LoginTermsFragmentArgument +import im.vector.app.features.onboarding.AuthenticationDescription import im.vector.app.features.pin.UnlockedActivity import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage @@ -218,10 +219,8 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA // change the screen name analyticsScreenName = MobileScreen.ScreenName.Register } - val intent = HomeActivity.newIntent( - this, - accountCreation = loginViewState.signMode == SignMode.SignUp - ) + val authDescription = inferAuthDescription(loginViewState) + val intent = HomeActivity.newIntent(this, authenticationDescription = authDescription) startActivity(intent) finish() return @@ -231,6 +230,13 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA views.loginLoading.isVisible = loginViewState.isLoading() } + private fun inferAuthDescription(loginViewState: LoginViewState) = when (loginViewState.signMode) { + SignMode.Unknown -> null + SignMode.SignUp -> AuthenticationDescription.Register(type = AuthenticationDescription.AuthenticationType.Other) + SignMode.SignIn -> AuthenticationDescription.Login + SignMode.SignInWithMatrixId -> AuthenticationDescription.Login + } + private fun onWebLoginError(onWebLoginError: LoginViewEvents.OnWebLoginError) { // Pop the backstack supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt index e8c0b25027..f575aed3f8 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt @@ -37,6 +37,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.failure.isInvalidPassword @@ -202,11 +203,11 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment?, mode: SocialLoginButtonsView.Mode, listener: (String?) -> Unit) { +fun SocialLoginButtonsView.render(ssoProviders: List?, mode: SocialLoginButtonsView.Mode, listener: (SsoIdentityProvider?) -> Unit) { this.mode = mode this.ssoIdentityProviders = ssoProviders?.sorted() this.listener = SocialLoginButtonsView.InteractionListener { listener(it) } diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSignupUsername2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSignupUsername2.kt index f9917a4c31..a7c4b25344 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSignupUsername2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentSignupUsername2.kt @@ -35,6 +35,7 @@ import im.vector.app.features.login.SocialLoginButtonsView import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import reactivecircus.flowbinding.android.widget.textChanges import javax.inject.Inject @@ -96,11 +97,11 @@ class LoginFragmentSignupUsername2 @Inject constructor() : AbstractSSOLoginFragm views.loginSocialLoginContainer.isVisible = true views.loginSocialLoginButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders?.sorted() views.loginSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { - override fun onProviderSelected(id: String?) { + override fun onProviderSelected(provider: SsoIdentityProvider?) { loginViewModel.getSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = state.deviceId, - providerId = id + providerId = provider?.id ) ?.let { openInCustomTab(it) } } diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt index 064889876b..cc143b9255 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginFragmentToAny2.kt @@ -37,6 +37,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.failure.isInvalidPassword @@ -123,11 +124,11 @@ class LoginFragmentToAny2 @Inject constructor() : AbstractSSOLoginFragment2 AuthenticationType.Google + SsoIdentityProvider.BRAND_GITHUB -> AuthenticationType.GitHub + SsoIdentityProvider.BRAND_APPLE -> AuthenticationType.Apple + SsoIdentityProvider.BRAND_FACEBOOK -> AuthenticationType.Facebook + SsoIdentityProvider.BRAND_GITLAB -> AuthenticationType.GitLab + SsoIdentityProvider.BRAND_TWITTER -> AuthenticationType.SSO + null -> AuthenticationType.SSO + else -> AuthenticationType.SSO +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt b/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt index e6b5cfc95c..ed8112f369 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/Login2Variant.kt @@ -276,7 +276,7 @@ class Login2Variant( is LoginViewEvents2.OnLoginModeNotSupported -> onLoginModeNotSupported(event.supportedTypes) is LoginViewEvents2.OnSessionCreated -> handleOnSessionCreated(event) - is LoginViewEvents2.Finish -> terminate(true) + is LoginViewEvents2.Finish -> terminate() is LoginViewEvents2.CancelRegistration -> handleCancelRegistration() } } @@ -296,14 +296,13 @@ class Login2Variant( option = commonOption ) } else { - terminate(false) + terminate() } } - private fun terminate(newAccount: Boolean) { + private fun terminate() { val intent = HomeActivity.newIntent( - activity, - accountCreation = newAccount + activity ) activity.startActivity(intent) activity.finish() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index b1fbf45f2b..8c0eeb7b4f 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -54,6 +54,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.RegistrationWizard @@ -255,7 +256,7 @@ class OnboardingViewModel @AssistedInject constructor( currentJob = viewModelScope.launch { try { val result = safeLoginWizard.loginWithToken(action.loginToken) - onSessionCreated(result, isAccountCreated = false) + onSessionCreated(result, authenticationDescription = AuthenticationDescription.Login) } catch (failure: Throwable) { setState { copy(isLoading = false) } _viewEvents.post(OnboardingViewEvents.Failure(failure)) @@ -289,7 +290,11 @@ class OnboardingViewModel @AssistedInject constructor( // do nothing } else -> when (it) { - is RegistrationResult.Complete -> onSessionCreated(it.session, isAccountCreated = true) + is RegistrationResult.Complete -> onSessionCreated( + it.session, + authenticationDescription = awaitState().selectedAuthenticationState.description + ?: AuthenticationDescription.Register(AuthenticationDescription.AuthenticationType.Other) + ) is RegistrationResult.NextStep -> onFlowResponse(it.flowResult, onNextRegistrationStepAction) is RegistrationResult.SendEmailSuccess -> _viewEvents.post(OnboardingViewEvents.OnSendEmailSuccess(it.email)) is RegistrationResult.Error -> _viewEvents.post(OnboardingViewEvents.Failure(it.cause)) @@ -319,6 +324,10 @@ class OnboardingViewModel @AssistedInject constructor( private fun OnboardingViewState.hasSelectedMatrixOrg() = selectedHomeserver.userFacingUrl == matrixOrgUrl private fun handleRegisterWith(action: AuthenticateAction.Register) { + setState { + val authDescription = AuthenticationDescription.Register(AuthenticationDescription.AuthenticationType.Password) + copy(selectedAuthenticationState = SelectedAuthenticationState(authDescription)) + } reAuthHelper.data = action.password handleRegisterAction( RegisterAction.CreateAccount( @@ -499,7 +508,7 @@ class OnboardingViewModel @AssistedInject constructor( setState { copy(isLoading = true) } currentJob = viewModelScope.launch { directLoginUseCase.execute(action, homeServerConnectionConfig).fold( - onSuccess = { onSessionCreated(it, isAccountCreated = false) }, + onSuccess = { onSessionCreated(it, authenticationDescription = AuthenticationDescription.Login) }, onFailure = { setState { copy(isLoading = false) } _viewEvents.post(OnboardingViewEvents.Failure(it)) @@ -524,7 +533,7 @@ class OnboardingViewModel @AssistedInject constructor( action.initialDeviceName ) reAuthHelper.data = action.password - onSessionCreated(result, isAccountCreated = false) + onSessionCreated(result, authenticationDescription = AuthenticationDescription.Login) } catch (failure: Throwable) { setState { copy(isLoading = false) } _viewEvents.post(OnboardingViewEvents.Failure(failure)) @@ -553,7 +562,7 @@ class OnboardingViewModel @AssistedInject constructor( internalRegisterAction(RegisterAction.RegisterDummy, onNextRegistrationStepAction) } - private suspend fun onSessionCreated(session: Session, isAccountCreated: Boolean) { + private suspend fun onSessionCreated(session: Session, authenticationDescription: AuthenticationDescription) { val state = awaitState() state.useCase?.let { useCase -> session.vectorStore(applicationContext).setUseCase(useCase) @@ -564,15 +573,15 @@ class OnboardingViewModel @AssistedInject constructor( authenticationService.reset() session.configureAndStart(applicationContext) - when (isAccountCreated) { - true -> { + when (authenticationDescription) { + is AuthenticationDescription.Register -> { val personalizationState = createPersonalizationState(session, state) setState { copy(isLoading = false, personalizationState = personalizationState) } _viewEvents.post(OnboardingViewEvents.OnAccountCreated) } - false -> { + AuthenticationDescription.Login -> { setState { copy(isLoading = false) } _viewEvents.post(OnboardingViewEvents.OnAccountSignedIn) } @@ -603,7 +612,7 @@ class OnboardingViewModel @AssistedInject constructor( currentJob = viewModelScope.launch { try { val result = authenticationService.createSessionFromSso(homeServerConnectionConfigFinal, action.credentials) - onSessionCreated(result, isAccountCreated = false) + onSessionCreated(result, authenticationDescription = AuthenticationDescription.Login) } catch (failure: Throwable) { setState { copy(isLoading = false) } } @@ -745,8 +754,12 @@ class OnboardingViewModel @AssistedInject constructor( return loginConfig?.homeServerUrl } - fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? { - return authenticationService.getSsoUrl(redirectUrl, deviceId, providerId) + fun fetchSsoUrl(redirectUrl: String, deviceId: String?, provider: SsoIdentityProvider?): String? { + setState { + val authDescription = AuthenticationDescription.Register(provider.toAuthenticationType()) + copy(selectedAuthenticationState = SelectedAuthenticationState(authDescription)) + } + return authenticationService.getSsoUrl(redirectUrl, deviceId, provider?.id) } fun getFallbackUrl(forSignIn: Boolean, deviceId: String?): String? { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt index 442a0a7df1..e91fee4d21 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt @@ -51,6 +51,9 @@ data class OnboardingViewState( @PersistState val selectedHomeserver: SelectedHomeserverState = SelectedHomeserverState(), + @PersistState + val selectedAuthenticationState: SelectedAuthenticationState = SelectedAuthenticationState(), + @PersistState val personalizationState: PersonalizationState = PersonalizationState() ) : MavericksState @@ -80,3 +83,8 @@ data class PersonalizationState( fun supportsPersonalization() = supportsChangingDisplayName || supportsChangingProfilePicture } + +@Parcelize +data class SelectedAuthenticationState( + val description: AuthenticationDescription? = null, +) : Parcelable diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt index a032181e4d..1b764f4ce6 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt @@ -90,10 +90,10 @@ abstract class AbstractSSOFtueAuthFragment : AbstractFtueAuthF withState(viewModel) { state -> if (state.selectedHomeserver.preferredLoginMode.hasSso() && state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders().isNullOrEmpty()) { // in this case we can prefetch (not other cases for privacy concerns) - viewModel.getSsoUrl( + viewModel.fetchSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = state.deviceId, - providerId = null + provider = null ) ?.let { prefetchUrl(it) } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt index 7324c4fbb1..c3c662902d 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedLoginFragment.kt @@ -131,10 +131,10 @@ class FtueAuthCombinedLoginFragment @Inject constructor( views.ssoGroup.isVisible = ssoProviders?.isNotEmpty() == true views.ssoButtonsHeader.isVisible = views.ssoGroup.isVisible && views.loginEntryGroup.isVisible views.ssoButtons.render(ssoProviders, SocialLoginButtonsView.Mode.MODE_CONTINUE) { id -> - viewModel.getSsoUrl( + viewModel.fetchSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = deviceId, - providerId = id + provider = id )?.let { openInCustomTab(it) } } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt index f27e5502db..a6273dc822 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt @@ -164,11 +164,11 @@ class FtueAuthCombinedRegisterFragment @Inject constructor() : AbstractSSOFtueAu private fun renderSsoProviders(deviceId: String?, ssoProviders: List?) { views.ssoGroup.isVisible = ssoProviders?.isNotEmpty() == true - views.ssoButtons.render(ssoProviders, SocialLoginButtonsView.Mode.MODE_CONTINUE) { id -> - viewModel.getSsoUrl( + views.ssoButtons.render(ssoProviders, SocialLoginButtonsView.Mode.MODE_CONTINUE) { provider -> + viewModel.fetchSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = deviceId, - providerId = id + provider = provider )?.let { openInCustomTab(it) } } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt index 98d9a24999..6f33de3a94 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt @@ -45,6 +45,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import org.matrix.android.sdk.api.failure.isInvalidPassword import org.matrix.android.sdk.api.failure.isInvalidUsername import org.matrix.android.sdk.api.failure.isLoginEmailUnknown @@ -216,11 +217,11 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment< views.loginSocialLoginContainer.isVisible = true views.loginSocialLoginButtons.ssoIdentityProviders = state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders?.sorted() views.loginSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { - override fun onProviderSelected(id: String?) { - viewModel.getSsoUrl( + override fun onProviderSelected(provider: SsoIdentityProvider?) { + viewModel.fetchSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = state.deviceId, - providerId = id + provider = provider ) ?.let { openInCustomTab(it) } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt index 69fbd3459b..9a85e46802 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt @@ -34,6 +34,7 @@ import im.vector.app.features.login.SocialLoginButtonsView import im.vector.app.features.login.ssoIdentityProviders import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingViewState +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import javax.inject.Inject /** @@ -81,11 +82,11 @@ class FtueAuthSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOF views.loginSignupSigninSignInSocialLoginContainer.isVisible = true views.loginSignupSigninSocialLoginButtons.ssoIdentityProviders = state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders()?.sorted() views.loginSignupSigninSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { - override fun onProviderSelected(id: String?) { - viewModel.getSsoUrl( + override fun onProviderSelected(provider: SsoIdentityProvider?) { + viewModel.fetchSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = state.deviceId, - providerId = id + provider = provider ) ?.let { openInCustomTab(it) } } @@ -123,10 +124,10 @@ class FtueAuthSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOF private fun submit() = withState(viewModel) { state -> if (state.selectedHomeserver.preferredLoginMode is LoginMode.Sso) { - viewModel.getSsoUrl( + viewModel.fetchSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = state.deviceId, - providerId = null + provider = null ) ?.let { openInCustomTab(it) } } else { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 7a3729ac69..355200ca30 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -216,7 +216,7 @@ class FtueAuthVariant( is OnboardingViewEvents.OnAccountCreated -> onAccountCreated() OnboardingViewEvents.OnAccountSignedIn -> onAccountSignedIn() OnboardingViewEvents.OnChooseDisplayName -> onChooseDisplayName() - OnboardingViewEvents.OnTakeMeHome -> navigateToHome(createdAccount = true) + OnboardingViewEvents.OnTakeMeHome -> navigateToHome() OnboardingViewEvents.OnChooseProfilePicture -> onChooseProfilePicture() OnboardingViewEvents.OnPersonalizationComplete -> onPersonalizationComplete() OnboardingViewEvents.OnBack -> activity.popBackstack() @@ -467,7 +467,7 @@ class FtueAuthVariant( } private fun onAccountSignedIn() { - navigateToHome(createdAccount = false) + navigateToHome() } private fun onAccountCreated() { @@ -479,10 +479,12 @@ class FtueAuthVariant( ) } - private fun navigateToHome(createdAccount: Boolean) { - val intent = HomeActivity.newIntent(activity, accountCreation = createdAccount) - activity.startActivity(intent) - activity.finish() + private fun navigateToHome() { + withState(onboardingViewModel) { + val intent = HomeActivity.newIntent(activity, authenticationDescription = it.selectedAuthenticationState.description) + activity.startActivity(intent) + activity.finish() + } } private fun onChooseDisplayName() {