adding combined server selection/sign up fragment
This commit is contained in:
parent
2cbbfca73f
commit
7e5c3df7a7
|
@ -9,6 +9,11 @@
|
|||
<item name="endIconTint">?vctr_content_secondary</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Vector.TextInputLayout.Username">
|
||||
<item name="endIconMode">clear_text</item>
|
||||
<item name="endIconTint">?vctr_content_secondary</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Vector.TextInputLayout.Form">
|
||||
<item name="boxStrokeColor">@color/form_edit_text_stroke_color_selector</item>
|
||||
<item name="android:textColorHint">@color/form_edit_text_hint_color_selector</item>
|
||||
|
|
|
@ -36,6 +36,7 @@ sealed class OnboardingViewEvents : VectorViewEvents {
|
|||
|
||||
object OpenUseCaseSelection : OnboardingViewEvents()
|
||||
object OpenServerSelection : OnboardingViewEvents()
|
||||
object OpenCombinedServerSelection : OnboardingViewEvents()
|
||||
data class OnServerSelectionDone(val serverType: ServerType) : OnboardingViewEvents()
|
||||
object OnLoginFlowRetrieved : OnboardingViewEvents()
|
||||
data class OnSignModeSelected(val signMode: SignMode) : OnboardingViewEvents()
|
||||
|
|
|
@ -356,7 +356,13 @@ class OnboardingViewModel @AssistedInject constructor(
|
|||
|
||||
private fun handleUpdateUseCase(action: OnboardingAction.UpdateUseCase) {
|
||||
setState { copy(useCase = action.useCase) }
|
||||
_viewEvents.post(OnboardingViewEvents.OpenServerSelection)
|
||||
when (vectorFeatures.isOnboardingCombinedChooseServerEnabled()) {
|
||||
true -> {
|
||||
handle(OnboardingAction.UpdateHomeServer(matrixOrgUrl))
|
||||
OnboardingViewEvents.OpenCombinedServerSelection
|
||||
}
|
||||
false -> _viewEvents.post(OnboardingViewEvents.OpenServerSelection)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetUseCase() {
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import im.vector.app.core.extensions.hidePassword
|
||||
import im.vector.app.core.platform.SimpleTextWatcher
|
||||
import im.vector.app.databinding.FragmentFtueDisplayNameBinding
|
||||
import im.vector.app.features.onboarding.OnboardingAction
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright 2019 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.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.autofill.HintConstants
|
||||
import androidx.core.text.isDigitsOnly
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.airbnb.mvrx.withState
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.hideKeyboard
|
||||
import im.vector.app.core.extensions.hidePassword
|
||||
import im.vector.app.core.extensions.realignPercentagesToParent
|
||||
import im.vector.app.databinding.FragmentFtueSignUpCombinedBinding
|
||||
import im.vector.app.features.login.LoginMode
|
||||
import im.vector.app.features.login.SSORedirectRouterActivity
|
||||
import im.vector.app.features.login.ServerType
|
||||
import im.vector.app.features.login.SocialLoginButtonsView
|
||||
import im.vector.app.features.onboarding.OnboardingAction
|
||||
import im.vector.app.features.onboarding.OnboardingViewState
|
||||
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.failure.isInvalidPassword
|
||||
import org.matrix.android.sdk.api.failure.isInvalidUsername
|
||||
import org.matrix.android.sdk.api.failure.isLoginEmailUnknown
|
||||
import org.matrix.android.sdk.api.failure.isRegistrationDisabled
|
||||
import org.matrix.android.sdk.api.failure.isUsernameInUse
|
||||
import org.matrix.android.sdk.api.failure.isWeakPassword
|
||||
import reactivecircus.flowbinding.android.widget.textChanges
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* In this screen:
|
||||
* In signin mode:
|
||||
* - the user is asked for login (or email) and password to sign in to a homeserver.
|
||||
* - He also can reset his password
|
||||
* In signup mode:
|
||||
* - the user is asked for login and password
|
||||
*/
|
||||
class FtueAuthCombinedSignUpFragment @Inject constructor() : AbstractSSOFtueAuthFragment<FragmentFtueSignUpCombinedBinding>() {
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueSignUpCombinedBinding {
|
||||
return FragmentFtueSignUpCombinedBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
views.createAccountPasswordInput.editText().hidePassword()
|
||||
setupSubmitButton()
|
||||
|
||||
views.createAccountRoot.realignPercentagesToParent()
|
||||
|
||||
views.createAccountPasswordInput.editText().setOnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
submit()
|
||||
return@setOnEditorActionListener true
|
||||
}
|
||||
return@setOnEditorActionListener false
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupAutoFill() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
views.createAccountInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_USERNAME)
|
||||
views.createAccountPasswordInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_PASSWORD)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSocialLoginButtons() {
|
||||
views.ssoButtons.mode = SocialLoginButtonsView.Mode.MODE_SIGN_UP
|
||||
}
|
||||
|
||||
private fun submit() {
|
||||
withState(viewModel) { state ->
|
||||
|
||||
cleanupUi()
|
||||
|
||||
val login = views.createAccountInput.editText.toString()
|
||||
val password = views.createAccountPasswordInput.editText.toString()
|
||||
|
||||
// This can be called by the IME action, so deal with empty cases
|
||||
var error = 0
|
||||
if (login.isEmpty()) {
|
||||
views.createAccountInput.error = getString(R.string.error_empty_field_choose_user_name)
|
||||
error++
|
||||
}
|
||||
if (state.isNumericOnlyUserIdForbidden() && login.isDigitsOnly()) {
|
||||
views.createAccountInput.error = "The homeserver does not accept username with only digits."
|
||||
error++
|
||||
}
|
||||
if (password.isEmpty()) {
|
||||
views.createAccountPasswordInput.error = getString(R.string.error_empty_field_choose_password)
|
||||
error++
|
||||
}
|
||||
|
||||
if (error == 0) {
|
||||
viewModel.handle(OnboardingAction.LoginOrRegister(login, password, getString(R.string.login_default_session_public_name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun cleanupUi() {
|
||||
views.createAccountSubmit.hideKeyboard()
|
||||
views.createAccountInput.error = null
|
||||
views.createAccountPasswordInput.error = null
|
||||
}
|
||||
|
||||
private fun setupUi(state: OnboardingViewState) {
|
||||
if (state.loginMode is LoginMode.SsoAndPassword) {
|
||||
views.ssoGroup.isVisible = state.loginMode.ssoIdentityProviders?.isNotEmpty() == true
|
||||
views.ssoButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders?.sorted()
|
||||
views.ssoButtons.listener = object : SocialLoginButtonsView.InteractionListener {
|
||||
override fun onProviderSelected(id: String?) {
|
||||
viewModel.getSsoUrl(
|
||||
redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL,
|
||||
deviceId = state.deviceId,
|
||||
providerId = id
|
||||
)
|
||||
?.let { openInCustomTab(it) }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
views.ssoGroup.isVisible = false
|
||||
views.ssoButtons.ssoIdentityProviders = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSubmitButton() {
|
||||
views.createAccountSubmit.setOnClickListener { submit() }
|
||||
combine(
|
||||
views.createAccountInput.editText().textChanges().map { it.trim().isNotEmpty() },
|
||||
views.createAccountPasswordInput.editText().textChanges().map { it.isNotEmpty() }
|
||||
) { isLoginNotEmpty, isPasswordNotEmpty ->
|
||||
isLoginNotEmpty && isPasswordNotEmpty
|
||||
}
|
||||
.onEach {
|
||||
views.createAccountPasswordInput.error = null
|
||||
views.createAccountInput.error = null
|
||||
views.createAccountSubmit.isEnabled = it
|
||||
}
|
||||
.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
}
|
||||
|
||||
override fun resetViewModel() {
|
||||
viewModel.handle(OnboardingAction.ResetLogin)
|
||||
}
|
||||
|
||||
override fun onError(throwable: Throwable) {
|
||||
// Trick to display the error without text.
|
||||
views.createAccountInput.error = " "
|
||||
when {
|
||||
throwable.isUsernameInUse() || throwable.isInvalidUsername() -> {
|
||||
views.createAccountInput.error = errorFormatter.toHumanReadable(throwable)
|
||||
}
|
||||
throwable.isLoginEmailUnknown() -> {
|
||||
views.createAccountInput.error = getString(R.string.login_login_with_email_error)
|
||||
}
|
||||
throwable.isInvalidPassword() && spaceInPassword() -> {
|
||||
views.createAccountPasswordInput.error = getString(R.string.auth_invalid_login_param_space_in_password)
|
||||
}
|
||||
throwable.isWeakPassword() || throwable.isInvalidPassword() -> {
|
||||
views.createAccountPasswordInput.error = errorFormatter.toHumanReadable(throwable)
|
||||
}
|
||||
throwable.isRegistrationDisabled() -> {
|
||||
MaterialAlertDialogBuilder(requireActivity())
|
||||
.setTitle(R.string.dialog_title_error)
|
||||
.setMessage(getString(R.string.login_registration_disabled))
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
else -> {
|
||||
super.onError(throwable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateWithState(state: OnboardingViewState) {
|
||||
setupUi(state)
|
||||
setupAutoFill()
|
||||
setupSocialLoginButtons()
|
||||
|
||||
if (state.isLoading) {
|
||||
// Ensure password is hidden
|
||||
views.createAccountPasswordInput.editText().hidePassword()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if password ends or starts with spaces
|
||||
*/
|
||||
private fun spaceInPassword() = views.createAccountPasswordInput.editText().text.toString().let { it.trim() != it }
|
||||
}
|
||||
|
||||
private fun OnboardingViewState.isNumericOnlyUserIdForbidden() = serverType == ServerType.MatrixOrg
|
||||
|
||||
private fun TextInputLayout.editText() = this.editText!!
|
|
@ -137,10 +137,14 @@ class FtueAuthVariant(
|
|||
// Go on with registration flow
|
||||
handleRegistrationNavigation(viewEvents.flowResult)
|
||||
} else {
|
||||
// First ask for login and password
|
||||
// I add a tag to indicate that this fragment is a registration stage.
|
||||
// This way it will be automatically popped in when starting the next registration stage
|
||||
openAuthLoginFragmentWithTag(FRAGMENT_REGISTRATION_STAGE_TAG)
|
||||
if (vectorFeatures.isOnboardingCombinedChooseServerEnabled()) {
|
||||
openCombinedServerSelection()
|
||||
} else {
|
||||
// First ask for login and password
|
||||
// I add a tag to indicate that this fragment is a registration stage.
|
||||
// This way it will be automatically popped in when starting the next registration stage
|
||||
openAuthLoginFragmentWithTag(FRAGMENT_REGISTRATION_STAGE_TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,6 +225,7 @@ class FtueAuthVariant(
|
|||
FtueAuthUseCaseFragment::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
OnboardingViewEvents.OpenCombinedServerSelection -> openCombinedServerSelection()
|
||||
is OnboardingViewEvents.OnAccountCreated -> onAccountCreated()
|
||||
OnboardingViewEvents.OnAccountSignedIn -> onAccountSignedIn()
|
||||
OnboardingViewEvents.OnChooseDisplayName -> onChooseDisplayName()
|
||||
|
@ -231,6 +236,14 @@ class FtueAuthVariant(
|
|||
}
|
||||
}
|
||||
|
||||
private fun openCombinedServerSelection() {
|
||||
activity.addFragmentToBackstack(
|
||||
views.loginFragmentContainer,
|
||||
FtueAuthCombinedSignUpFragment::class.java,
|
||||
option = commonOption
|
||||
)
|
||||
}
|
||||
|
||||
private fun registrationShouldFallback(registrationFlowResult: OnboardingViewEvents.RegistrationFlowResult) =
|
||||
isForceLoginFallbackEnabled || registrationFlowResult.containsUnsupportedRegistrationFlow()
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/displayNameInput" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/actionsSpacing"
|
||||
android:id="@+id/entrySpacing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/displayNameSubmit"
|
||||
|
@ -133,7 +133,7 @@
|
|||
app:layout_constraintBottom_toTopOf="@id/displayNameSkip"
|
||||
app:layout_constraintEnd_toEndOf="@id/displayNameGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/displayNameGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/actionsSpacing" />
|
||||
app:layout_constraintTop_toBottomOf="@id/entrySpacing" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/displayNameSkip"
|
||||
|
|
|
@ -122,13 +122,13 @@
|
|||
android:gravity="center"
|
||||
android:text="@string/ftue_profile_picture_subtitle"
|
||||
android:textColor="?vctr_content_secondary"
|
||||
app:layout_constraintBottom_toTopOf="@id/actionsSpacing"
|
||||
app:layout_constraintBottom_toTopOf="@id/entrySpacing"
|
||||
app:layout_constraintEnd_toEndOf="@id/profilePictureGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/profilePictureGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/profilePictureHeaderTitle" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/actionsSpacing"
|
||||
android:id="@+id/entrySpacing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/profilePictureSubmit"
|
||||
|
@ -145,7 +145,7 @@
|
|||
app:layout_constraintBottom_toTopOf="@id/profilePictureSkip"
|
||||
app:layout_constraintEnd_toEndOf="@id/profilePictureGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/profilePictureGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/actionsSpacing" />
|
||||
app:layout_constraintTop_toBottomOf="@id/entrySpacing" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/profilePictureSkip"
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView 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"
|
||||
style="@style/LoginFormScrollView"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:colorBackground"
|
||||
android:fillViewport="true"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingBottom="0dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/createAccountRoot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/createAccountGutterStart"
|
||||
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/createAccountGutterEnd"
|
||||
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/headerSpacing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountHeaderIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/createAccountHeaderIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:background="@drawable/circle"
|
||||
android:backgroundTint="?colorSecondary"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_user_fg"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountHeaderTitle"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintHeight_percent="0.10"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/headerSpacing"
|
||||
app:tint="@color/palette_white" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/createAccountHeaderTitle"
|
||||
style="@style/Widget.Vector.TextView.Title.Medium"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/ftue_auth_create_account_title"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountHeaderSubtitle"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountHeaderIcon" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/createAccountHeaderSubtitle"
|
||||
style="@style/Widget.Vector.TextView.Subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/ftue_auth_create_account_subtitle"
|
||||
android:textColor="?vctr_content_secondary"
|
||||
app:layout_constraintBottom_toTopOf="@id/titleContentSpacing"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountHeaderTitle" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/titleContentSpacing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/chooseYourServerHeader"
|
||||
app:layout_constraintHeight_percent="0.03"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountHeaderSubtitle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/chooseYourServerHeader"
|
||||
style="@style/Widget.Vector.TextView.Caption"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/ftue_auth_create_account_choose_server_header"
|
||||
android:textColor="?vctr_content_secondary"
|
||||
app:layout_constraintBottom_toTopOf="@id/selectedServerName"
|
||||
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleContentSpacing" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/selectedServerName"
|
||||
style="@style/Widget.Vector.TextView.Subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:text="matrix.org"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toTopOf="@id/selectedServerDescription"
|
||||
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/chooseYourServerHeader" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/selectedServerDescription"
|
||||
style="@style/Widget.Vector.TextView.Micro"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:text="Join millions for free on the largest public server"
|
||||
android:textColor="?vctr_content_tertiary"
|
||||
app:layout_constraintBottom_toTopOf="@id/serverSelectionSpacing"
|
||||
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/selectedServerName" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/editServerButton"
|
||||
style="@style/Widget.Vector.Button.Outlined"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Edit"
|
||||
android:paddingLeft="1dp"
|
||||
android:paddingRight="1dp"
|
||||
android:textAllCaps="true"
|
||||
app:layout_constraintBottom_toBottomOf="@id/selectedServerDescription"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintTop_toTopOf="@id/chooseYourServerHeader" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/serverSelectionSpacing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountInput"
|
||||
app:layout_constraintHeight_percent="0.05"
|
||||
app:layout_constraintTop_toBottomOf="@id/selectedServerDescription" />
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:background="?vctr_content_quaternary"
|
||||
app:layout_constraintBottom_toBottomOf="@id/serverSelectionSpacing"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toTopOf="@id/serverSelectionSpacing" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/createAccountInput"
|
||||
style="@style/Widget.Vector.TextInputLayout.Username"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/username"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountEntryFooter"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/serverSelectionSpacing">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:imeOptions="actionDone"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/createAccountEntryFooter"
|
||||
style="@style/Widget.Vector.TextView.Micro"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/ftue_auth_create_account_username_entry_footer"
|
||||
app:layout_constraintBottom_toTopOf="@id/entrySpacing"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountInput" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/entrySpacing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountPasswordInput"
|
||||
app:layout_constraintHeight_percent="0.03"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountEntryFooter" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/createAccountPasswordInput"
|
||||
style="@style/Widget.Vector.TextInputLayout.Password"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/login_signup_password_hint"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountPasswordEntryFooter"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/entrySpacing">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:imeOptions="actionDone"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/createAccountPasswordEntryFooter"
|
||||
style="@style/Widget.Vector.TextView.Micro"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/ftue_auth_create_account_password_entry_footer"
|
||||
app:layout_constraintBottom_toTopOf="@id/actionSpacing"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountPasswordInput" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/actionSpacing"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/createAccountSubmit"
|
||||
app:layout_constraintHeight_percent="0.02"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountPasswordEntryFooter" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/createAccountSubmit"
|
||||
style="@style/Widget.Vector.Button.Login"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/login_signup_submit"
|
||||
android:textAllCaps="true"
|
||||
app:layout_constraintBottom_toTopOf="@id/ssoButtonsHeader"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/actionSpacing" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/ssoGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:constraint_referenced_ids="ssoButtonsHeader,ssoButtons"
|
||||
app:layout_constraintBottom_toTopOf="@id/ssoButtonsHeader"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountSubmit"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ssoButtonsHeader"
|
||||
style="@style/Widget.Vector.TextView.Subtitle.Medium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/ftue_auth_create_account_sso_section_header"
|
||||
android:textColor="?vctr_content_secondary"
|
||||
app:layout_constraintBottom_toTopOf="@id/ssoButtons"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/createAccountSubmit" />
|
||||
|
||||
<im.vector.app.features.login.SocialLoginButtonsView
|
||||
android:id="@+id/ssoButtons"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
||||
app:layout_constraintTop_toBottomOf="@id/ssoButtonsHeader"
|
||||
tools:signMode="signup" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
|
@ -10,4 +10,11 @@
|
|||
<string name="cut_the_slack_from_teams" translatable="false">Cut the slack from teams.</string>
|
||||
|
||||
<!-- WIP -->
|
||||
<string name="ftue_auth_create_account_title">Create your account</string>
|
||||
<string name="ftue_auth_create_account_subtitle">We\'ll need some info to get you set up.</string>
|
||||
<string name="ftue_auth_create_account_username_entry_footer">You can\'t change this later</string>
|
||||
<string name="ftue_auth_create_account_password_entry_footer">Must be 8 characters or more</string>
|
||||
<string name="ftue_auth_create_account_choose_server_header">Choose your server to store your data</string>
|
||||
<string name="ftue_auth_create_account_sso_section_header">Or</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue