Merge remote-tracking branch 'origin/develop' into feature/eric/registration-feature-flag

# Conflicts:
#	vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt
#	vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt
#	vector/src/main/java/im/vector/app/features/VectorFeatures.kt
This commit is contained in:
ericdecanini 2022-02-23 17:31:43 +01:00
commit 64e074840b
18 changed files with 283 additions and 38 deletions

1
changelog.d/5158.wip Normal file
View File

@ -0,0 +1 @@
Starts the FTUE account personalisation flow by adding an account created screen behind a feature flag

1
changelog.d/5312.misc Normal file
View File

@ -0,0 +1 @@
Log the `since` token used and `next_batch` token returned when doing an incremental sync.

1
changelog.d/5313.misc Normal file
View File

@ -0,0 +1 @@
Update reaction button layout.

1
changelog.d/5318.misc Normal file
View File

@ -0,0 +1 @@
Log the `since` token used and `next_batch` token returned when doing an incremental sync.

View File

@ -147,7 +147,7 @@ internal class DefaultSyncTask @Inject constructor(
}
defaultSyncStatusService.endAll()
} else {
Timber.tag(loggerTag.value).d("Start incremental sync request")
Timber.tag(loggerTag.value).d("Start incremental sync request with since token $token")
defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncIdle)
val syncResponse = try {
executeRequest(globalErrorReceiver) {
@ -163,7 +163,10 @@ internal class DefaultSyncTask @Inject constructor(
}
val nbRooms = syncResponse.rooms?.invite.orEmpty().size + syncResponse.rooms?.join.orEmpty().size + syncResponse.rooms?.leave.orEmpty().size
val nbToDevice = syncResponse.toDevice?.events.orEmpty().size
Timber.tag(loggerTag.value).d("Incremental sync request parsing, $nbRooms room(s) $nbToDevice toDevice(s)")
val nextBatch = syncResponse.nextBatch
Timber.tag(loggerTag.value).d(
"Incremental sync request parsing, $nbRooms room(s) $nbToDevice toDevice(s). Got nextBatch: $nextBatch"
)
defaultSyncStatusService.setStatus(SyncStatusService.Status.IncrementalSyncParsing(
rooms = nbRooms,
toDevice = nbToDevice

View File

@ -49,6 +49,11 @@ class DebugFeaturesStateFactory @Inject constructor(
key = DebugFeatureKeys.onboardingUseCase,
factory = VectorFeatures::isOnboardingUseCaseEnabled
),
createBooleanFeature(
label = "FTUE Personalize profile",
key = DebugFeatureKeys.onboardingPersonalize,
factory = VectorFeatures::isOnboardingPersonalizeEnabled
),
createBooleanFeature(
label = "Force login fallback",
key = DebugFeatureKeys.forceLoginFallback,

View File

@ -51,6 +51,9 @@ class DebugVectorFeatures(
override fun isOnboardingUseCaseEnabled(): Boolean = read(DebugFeatureKeys.onboardingUseCase) ?: vectorFeatures.isOnboardingUseCaseEnabled()
override fun isOnboardingPersonalizeEnabled(): Boolean = read(DebugFeatureKeys.onboardingPersonalize)
?: vectorFeatures.isOnboardingPersonalizeEnabled()
override fun isForceLoginFallbackEnabled(): Boolean = read(DebugFeatureKeys.forceLoginFallback) ?: vectorFeatures.isForceLoginFallbackEnabled()
fun <T> override(value: T?, key: Preferences.Key<T>) = updatePreferences {
@ -104,5 +107,6 @@ object DebugFeatureKeys {
val onboardingAlreadyHaveAnAccount = booleanPreferencesKey("onboarding-already-have-an-account")
val onboardingSplashCarousel = booleanPreferencesKey("onboarding-splash-carousel")
val onboardingUseCase = booleanPreferencesKey("onbboarding-splash-carousel")
val onboardingPersonalize = booleanPreferencesKey("onbboarding-personalize")
val forceLoginFallback = booleanPreferencesKey("force-login-fallback")
}

View File

@ -97,6 +97,7 @@ import im.vector.app.features.login2.created.AccountCreatedFragment
import im.vector.app.features.login2.terms.LoginTermsFragment2
import im.vector.app.features.matrixto.MatrixToRoomSpaceFragment
import im.vector.app.features.matrixto.MatrixToUserFragment
import im.vector.app.features.onboarding.ftueauth.FtueAuthAccountCreatedFragment
import im.vector.app.features.onboarding.ftueauth.FtueAuthCaptchaFragment
import im.vector.app.features.onboarding.ftueauth.FtueAuthGenericTextInputFormFragment
import im.vector.app.features.onboarding.ftueauth.FtueAuthLoginFragment
@ -473,6 +474,11 @@ interface FragmentModule {
@FragmentKey(FtueAuthTermsFragment::class)
fun bindFtueAuthTermsFragment(fragment: FtueAuthTermsFragment): Fragment
@Binds
@IntoMap
@FragmentKey(FtueAuthAccountCreatedFragment::class)
fun bindFtueAuthAccountCreatedFragment(fragment: FtueAuthAccountCreatedFragment): Fragment
@Binds
@IntoMap
@FragmentKey(UserListFragment::class)

View File

@ -24,6 +24,7 @@ interface VectorFeatures {
fun isOnboardingAlreadyHaveAccountSplashEnabled(): Boolean
fun isOnboardingSplashCarouselEnabled(): Boolean
fun isOnboardingUseCaseEnabled(): Boolean
fun isOnboardingPersonalizeEnabled(): Boolean
fun isForceLoginFallbackEnabled(): Boolean
enum class OnboardingVariant {
@ -38,5 +39,6 @@ class DefaultVectorFeatures : VectorFeatures {
override fun isOnboardingAlreadyHaveAccountSplashEnabled() = true
override fun isOnboardingSplashCarouselEnabled() = true
override fun isOnboardingUseCaseEnabled() = true
override fun isOnboardingPersonalizeEnabled() = false
override fun isForceLoginFallbackEnabled() = false
}

View File

@ -48,4 +48,8 @@ sealed class OnboardingViewEvents : VectorViewEvents {
data class OnSendMsisdnSuccess(val msisdn: String) : OnboardingViewEvents()
data class OnWebLoginError(val errorCode: Int, val description: String, val failingUrl: String) : OnboardingViewEvents()
object OnAccountCreated : OnboardingViewEvents()
object OnAccountSignedIn : OnboardingViewEvents()
object OnTakeMeHome : OnboardingViewEvents()
object OnPersonalizeProfile : OnboardingViewEvents()
}

View File

@ -243,7 +243,7 @@ class OnboardingViewModel @AssistedInject constructor(
}
null
}
?.let { onSessionCreated(it) }
?.let { onSessionCreated(it, isAccountCreated = false) }
}
}
}
@ -301,7 +301,7 @@ class OnboardingViewModel @AssistedInject constructor(
}
?.let { data ->
when (data) {
is RegistrationResult.Success -> onSessionCreated(data.session)
is RegistrationResult.Success -> onSessionCreated(data.session, isAccountCreated = true)
is RegistrationResult.FlowResponse -> onFlowResponse(data.flowResult)
}
}
@ -600,11 +600,11 @@ class OnboardingViewModel @AssistedInject constructor(
}
when (data) {
is WellknownResult.Prompt ->
onWellknownSuccess(action, data, homeServerConnectionConfig)
directLoginOnWellknownSuccess(action, data, homeServerConnectionConfig)
is WellknownResult.FailPrompt ->
// Relax on IS discovery if homeserver is valid
if (data.homeServerUrl != null && data.wellKnown != null) {
onWellknownSuccess(action, WellknownResult.Prompt(data.homeServerUrl!!, null, data.wellKnown!!), homeServerConnectionConfig)
directLoginOnWellknownSuccess(action, WellknownResult.Prompt(data.homeServerUrl!!, null, data.wellKnown!!), homeServerConnectionConfig)
} else {
onWellKnownError()
}
@ -624,9 +624,9 @@ class OnboardingViewModel @AssistedInject constructor(
_viewEvents.post(OnboardingViewEvents.Failure(Exception(stringProvider.getString(R.string.autodiscover_well_known_error))))
}
private suspend fun onWellknownSuccess(action: OnboardingAction.LoginOrRegister,
wellKnownPrompt: WellknownResult.Prompt,
homeServerConnectionConfig: HomeServerConnectionConfig?) {
private suspend fun directLoginOnWellknownSuccess(action: OnboardingAction.LoginOrRegister,
wellKnownPrompt: WellknownResult.Prompt,
homeServerConnectionConfig: HomeServerConnectionConfig?) {
val alteredHomeServerConnectionConfig = homeServerConnectionConfig
?.copy(
homeServerUriBase = Uri.parse(wellKnownPrompt.homeServerUrl),
@ -648,7 +648,7 @@ class OnboardingViewModel @AssistedInject constructor(
onDirectLoginError(failure)
return
}
onSessionCreated(data)
onSessionCreated(data, isAccountCreated = true)
}
private fun onDirectLoginError(failure: Throwable) {
@ -706,7 +706,7 @@ class OnboardingViewModel @AssistedInject constructor(
}
?.let {
reAuthHelper.data = action.password
onSessionCreated(it)
onSessionCreated(it, isAccountCreated = false)
}
}
}
@ -736,8 +736,9 @@ class OnboardingViewModel @AssistedInject constructor(
}
}
private suspend fun onSessionCreated(session: Session) {
awaitState().useCase?.let { useCase ->
private suspend fun onSessionCreated(session: Session, isAccountCreated: Boolean) {
val state = awaitState()
state.useCase?.let { useCase ->
session.vectorStore(applicationContext).setUseCase(useCase)
analyticsTracker.updateUserProperties(UserProperties(ftueUseCaseSelection = useCase.toTrackingValue()))
}
@ -750,6 +751,11 @@ class OnboardingViewModel @AssistedInject constructor(
asyncLoginAction = Success(Unit)
)
}
when (isAccountCreated) {
true -> _viewEvents.post(OnboardingViewEvents.OnAccountCreated)
false -> _viewEvents.post(OnboardingViewEvents.OnAccountSignedIn)
}
}
private fun handleWebLoginSuccess(action: OnboardingAction.WebLoginSuccess) = withState { state ->
@ -768,7 +774,7 @@ class OnboardingViewModel @AssistedInject constructor(
}
null
}
?.let { onSessionCreated(it) }
?.let { onSessionCreated(it, isAccountCreated = false) }
}
}
}

View File

@ -70,12 +70,10 @@ data class OnboardingViewState(
asyncHomeServerLoginFlowRequest is Loading ||
asyncResetPassword is Loading ||
asyncResetMailConfirmed is Loading ||
asyncRegistration is Loading ||
// Keep loading when it is success because of the delay to switch to the next Activity
asyncLoginAction is Success
asyncRegistration is Loading
}
fun isUserLogged(): Boolean {
fun isAuthTaskCompleted(): Boolean {
return asyncLoginAction is Success
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.ftueauth
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.databinding.FragmentFtueAccountCreatedBinding
import im.vector.app.features.onboarding.OnboardingAction
import im.vector.app.features.onboarding.OnboardingViewEvents
import javax.inject.Inject
class FtueAuthAccountCreatedFragment @Inject constructor(
private val activeSessionHolder: ActiveSessionHolder
) : AbstractFtueAuthFragment<FragmentFtueAccountCreatedBinding>() {
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueAccountCreatedBinding {
return FragmentFtueAccountCreatedBinding.inflate(inflater, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupViews()
}
private fun setupViews() {
views.accountCreatedSubtitle.text = getString(R.string.ftue_account_created_subtitle, activeSessionHolder.getActiveSession().myUserId)
views.accountCreatedPersonalize.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnPersonalizeProfile)) }
views.accountCreatedTakeMeHome.debouncedClicks { viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) }
}
override fun resetViewModel() {
// Nothing to do
}
override fun onBackPressed(toolbarButton: Boolean): Boolean {
viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome))
return true
}
}

View File

@ -32,6 +32,7 @@ import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.ScreenOrientationLocker
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityLoginBinding
@ -216,6 +217,10 @@ class FtueAuthVariant(
FtueAuthUseCaseFragment::class.java,
option = commonOption)
}
OnboardingViewEvents.OnAccountCreated -> onAccountCreated()
OnboardingViewEvents.OnAccountSignedIn -> onAccountSignedIn()
OnboardingViewEvents.OnPersonalizeProfile -> TODO()
OnboardingViewEvents.OnTakeMeHome -> navigateToHome(createdAccount = true)
}.exhaustive
}
@ -239,18 +244,12 @@ class FtueAuthVariant(
}
private fun updateWithState(viewState: OnboardingViewState) {
if (viewState.isUserLogged()) {
val intent = HomeActivity.newIntent(
activity,
accountCreation = viewState.signMode == SignMode.SignUp
)
activity.startActivity(intent)
activity.finish()
return
views.loginLoading.isVisible = if (vectorFeatures.isOnboardingPersonalizeEnabled()) {
viewState.isLoading()
} else {
// Keep loading when during success because of the delay when switching to the next Activity
viewState.isLoading() || viewState.isAuthTaskCompleted()
}
// Loading
views.loginLoading.isVisible = viewState.isLoading()
}
private fun onWebLoginError(onWebLoginError: OnboardingViewEvents.OnWebLoginError) {
@ -384,4 +383,26 @@ class FtueAuthVariant(
else -> Unit // Should not happen
}
}
private fun onAccountSignedIn() {
navigateToHome(createdAccount = false)
}
private fun onAccountCreated() {
if (vectorFeatures.isOnboardingPersonalizeEnabled()) {
activity.supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
activity.replaceFragment(
views.loginFragmentContainer,
FtueAuthAccountCreatedFragment::class.java,
)
} else {
navigateToHome(createdAccount = true)
}
}
private fun navigateToHome(createdAccount: Boolean) {
val intent = HomeActivity.newIntent(activity, accountCreation = createdAccount)
activity.startActivity(intent)
activity.finish()
}
}

View File

@ -1,4 +1,10 @@
<vector android:height="14dp" android:viewportHeight="16"
android:viewportWidth="16" android:width="14dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#737D8C" android:fillType="evenOdd" android:pathData="M13.3334,0.667C12.9652,0.667 12.6667,0.9655 12.6667,1.3337V2.667L11.3334,2.667C10.9652,2.667 10.6667,2.9655 10.6667,3.3337C10.6667,3.7018 10.9652,4.0003 11.3334,4.0003H12.6667V5.3337C12.6667,5.7018 12.9652,6.0003 13.3334,6.0003C13.7016,6.0003 14,5.7018 14,5.3337V4.0003H15.3334C15.7016,4.0003 16,3.7018 16,3.3337C16,2.9655 15.7016,2.667 15.3334,2.667L14,2.667V1.3337C14,0.9655 13.7016,0.667 13.3334,0.667ZM4.6667,6.3337C4.6667,5.7803 5.1134,5.3337 5.6667,5.3337C6.22,5.3337 6.6667,5.7803 6.6667,6.3337C6.6667,6.887 6.22,7.3337 5.6667,7.3337C5.1134,7.3337 4.6667,6.887 4.6667,6.3337ZM10.3334,7.3337C10.8867,7.3337 11.3334,6.887 11.3334,6.3337C11.3334,5.7803 10.8867,5.3337 10.3334,5.3337C9.78,5.3337 9.3334,5.7803 9.3334,6.3337C9.3334,6.887 9.78,7.3337 10.3334,7.3337ZM8,11.667C9.5534,11.667 10.8734,10.6937 11.4067,9.3337H4.5934C5.1267,10.6937 6.4467,11.667 8,11.667ZM2.6667,8.0003C2.6667,5.0548 5.0545,2.667 8,2.667C8.4073,2.667 8.803,2.7125 9.1828,2.7985C9.542,2.8797 9.8989,2.6545 9.9802,2.2954C10.0615,1.9363 9.8362,1.5793 9.4771,1.498C9.0014,1.3903 8.5069,1.3337 8,1.3337C4.3181,1.3337 1.3334,4.3184 1.3334,8.0003C1.3334,11.6822 4.3181,14.667 8,14.667C11.6819,14.667 14.6667,11.6822 14.6667,8.0003C14.6667,7.8589 14.6623,7.7184 14.6536,7.579C14.6306,7.2115 14.3141,6.9322 13.9467,6.9552C13.5792,6.9781 13.2999,7.2946 13.3228,7.6621C13.3298,7.7738 13.3334,7.8866 13.3334,8.0003C13.3334,10.9458 10.9456,13.3337 8,13.3337C5.0545,13.3337 2.6667,10.9458 2.6667,8.0003Z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="15dp"
android:height="15dp"
android:viewportWidth="15"
android:viewportHeight="15">
<path
android:pathData="M12.3334,0.667C11.9652,0.667 11.6667,0.9655 11.6667,1.3337V2.667L10.3334,2.667C9.9652,2.667 9.6667,2.9655 9.6667,3.3337C9.6667,3.7018 9.9652,4.0003 10.3334,4.0003H11.6667V5.3337C11.6667,5.7018 11.9652,6.0003 12.3334,6.0003C12.7016,6.0003 13,5.7018 13,5.3337V4.0003H14.3334C14.7016,4.0003 15,3.7018 15,3.3337C15,2.9655 14.7016,2.667 14.3334,2.667L13,2.667V1.3337C13,0.9655 12.7016,0.667 12.3334,0.667ZM3.6667,6.3337C3.6667,5.7803 4.1134,5.3337 4.6667,5.3337C5.22,5.3337 5.6667,5.7803 5.6667,6.3337C5.6667,6.887 5.22,7.3337 4.6667,7.3337C4.1134,7.3337 3.6667,6.887 3.6667,6.3337ZM9.3334,7.3337C9.8867,7.3337 10.3334,6.887 10.3334,6.3337C10.3334,5.7803 9.8867,5.3337 9.3334,5.3337C8.78,5.3337 8.3334,5.7803 8.3334,6.3337C8.3334,6.887 8.78,7.3337 9.3334,7.3337ZM7.0001,11.667C8.5534,11.667 9.8734,10.6937 10.4067,9.3337H3.5934C4.1267,10.6937 5.4467,11.667 7.0001,11.667ZM1.6667,8.0003C1.6667,5.0548 4.0545,2.667 7,2.667C7.4072,2.667 7.803,2.7125 8.1828,2.7985C8.542,2.8797 8.8989,2.6545 8.9802,2.2954C9.0615,1.9363 8.8362,1.5793 8.4771,1.498C8.0014,1.3903 7.5069,1.3337 7,1.3337C3.3181,1.3337 0.3334,4.3184 0.3334,8.0003C0.3334,11.6822 3.3181,14.667 7,14.667C10.6819,14.667 13.6667,11.6822 13.6667,8.0003C13.6667,7.8589 13.6623,7.7184 13.6536,7.579C13.6306,7.2115 13.3141,6.9322 12.9467,6.9552C12.5792,6.9781 12.2999,7.2946 12.3228,7.6621C12.3298,7.7738 12.3334,7.8866 12.3334,8.0003C12.3334,10.9458 9.9456,13.3337 7,13.3337C4.0545,13.3337 1.6667,10.9458 1.6667,8.0003Z"
android:fillColor="#737D8C"
android:fillType="evenOdd"/>
</vector>

View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSecondary">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/ftueAuthGutterStart"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_start_percent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/ftueAuthGutterEnd"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_end_percent" />
<Space
android:id="@+id/accountCreatedSpace1"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/accountCreatedLogo"
app:layout_constraintHeight_percent="0.10"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread_inside" />
<ImageView
android:id="@+id/accountCreatedLogo"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:importantForAccessibility="no"
android:src="@drawable/ic_user_round"
app:layout_constraintBottom_toTopOf="@id/accountCreatedSpace2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/accountCreatedSpace1"
app:tint="@color/element_background_light" />
<Space
android:id="@+id/accountCreatedSpace2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/accountCreatedTitle"
app:layout_constraintHeight_percent="0.05"
app:layout_constraintTop_toBottomOf="@id/accountCreatedLogo" />
<TextView
android:id="@+id/accountCreatedTitle"
style="@style/Widget.Vector.TextView.Title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/ftue_account_created_congratulations_title"
android:textColor="@color/element_background_light"
android:transitionName="loginTitleTransition"
app:layout_constraintBottom_toTopOf="@id/accountCreatedSubtitle"
app:layout_constraintEnd_toEndOf="@id/ftueAuthGutterEnd"
app:layout_constraintStart_toStartOf="@id/ftueAuthGutterStart"
app:layout_constraintTop_toBottomOf="@id/accountCreatedSpace2" />
<TextView
android:id="@+id/accountCreatedSubtitle"
style="@style/Widget.Vector.TextView.Subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:textColor="@color/element_background_light"
app:layout_constraintBottom_toTopOf="@id/accountCreatedSpace4"
app:layout_constraintEnd_toEndOf="@id/ftueAuthGutterEnd"
app:layout_constraintStart_toStartOf="@id/ftueAuthGutterStart"
app:layout_constraintTop_toBottomOf="@id/accountCreatedTitle"
tools:text="Your account @hello:matrix.org has been created" />
<Space
android:id="@+id/accountCreatedSpace4"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/accountCreatedPersonalize"
app:layout_constraintTop_toBottomOf="@id/accountCreatedSubtitle" />
<Button
android:id="@+id/accountCreatedPersonalize"
style="@style/Widget.Vector.Button.Login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/element_background_light"
android:text="@string/ftue_account_created_personalize"
android:textAllCaps="true"
android:textColor="?colorSecondary"
android:transitionName="loginSubmitTransition"
app:layout_constraintBottom_toTopOf="@id/accountCreatedSpace5"
app:layout_constraintEnd_toEndOf="@id/ftueAuthGutterEnd"
app:layout_constraintStart_toStartOf="@id/ftueAuthGutterStart"
app:layout_constraintTop_toBottomOf="@id/accountCreatedSpace4"
tools:text="@string/ftue_account_created_personalize" />
<Button
android:id="@+id/accountCreatedTakeMeHome"
style="@style/Widget.Vector.Button.Text.Login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/ftue_account_created_take_me_home"
android:textAllCaps="true"
android:textColor="@color/element_background_light"
android:transitionName="loginSubmitTransition"
app:layout_constraintBottom_toTopOf="@id/accountCreatedSpace5"
app:layout_constraintEnd_toEndOf="@id/ftueAuthGutterEnd"
app:layout_constraintStart_toStartOf="@id/ftueAuthGutterStart"
app:layout_constraintTop_toBottomOf="@id/accountCreatedPersonalize" />
<Space
android:id="@+id/accountCreatedSpace5"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.05"
app:layout_constraintTop_toBottomOf="@id/accountCreatedPersonalize" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -29,17 +28,14 @@
<TextView
android:id="@+id/reactionCount"
style="@style/Widget.Vector.TextView.Micro"
style="@style/Widget.Vector.TextView.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:layout_marginStart="4dp"
android:gravity="center"
android:maxLines="1"
android:textColor="?vctr_content_secondary"
android:textStyle="bold"
app:autoSizeMaxTextSize="14sp"
app:autoSizeMinTextSize="8sp"
app:autoSizeTextType="uniform"
tools:text="13450" />
</merge>

View File

@ -16,4 +16,10 @@
<!-- onboarding english only word play -->
<string name="cut_the_slack_from_teams" translatable="false">Cut the slack from teams.</string>
<!-- WIP -->
<string name="ftue_account_created_personalize" translatable="false">Personalize profile</string>
<string name="ftue_account_created_take_me_home" translatable="false">Take me home</string>
<string name="ftue_account_created_congratulations_title" translatable="false">Congratulations!</string>
<string name="ftue_account_created_subtitle" translatable="false">Your account %s has been created.</string>
</resources>