mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 18:35:40 +03:00
minor refactors
- extracting login fields validation - renaming xml fields to login - renaming direct login property to matrixId
This commit is contained in:
parent
b3bbb0329e
commit
c3ce887e33
7 changed files with 141 additions and 100 deletions
|
@ -33,7 +33,7 @@ class DirectLoginUseCase @Inject constructor(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun execute(action: OnboardingAction.LoginDirect, homeServerConnectionConfig: HomeServerConnectionConfig?): Result<Session> {
|
suspend fun execute(action: OnboardingAction.LoginDirect, homeServerConnectionConfig: HomeServerConnectionConfig?): Result<Session> {
|
||||||
return fetchWellKnown(action.username, homeServerConnectionConfig)
|
return fetchWellKnown(action.matrixId, homeServerConnectionConfig)
|
||||||
.andThen { wellKnown -> createSessionFor(wellKnown, action, homeServerConnectionConfig) }
|
.andThen { wellKnown -> createSessionFor(wellKnown, action, homeServerConnectionConfig) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ class DirectLoginUseCase @Inject constructor(
|
||||||
return runCatching {
|
return runCatching {
|
||||||
authenticationService.directAuthentication(
|
authenticationService.directAuthentication(
|
||||||
alteredHomeServerConnectionConfig,
|
alteredHomeServerConnectionConfig,
|
||||||
action.username,
|
action.matrixId,
|
||||||
action.password,
|
action.password,
|
||||||
action.initialDeviceName
|
action.initialDeviceName
|
||||||
)
|
)
|
||||||
|
|
|
@ -48,7 +48,7 @@ sealed interface OnboardingAction : VectorViewModelAction {
|
||||||
|
|
||||||
data class Register(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction
|
data class Register(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction
|
||||||
data class Login(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction
|
data class Login(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction
|
||||||
data class LoginDirect(val username: String, val password: String, val initialDeviceName: String) : OnboardingAction
|
data class LoginDirect(val matrixId: String, val password: String, val initialDeviceName: String) : OnboardingAction
|
||||||
object StopEmailValidationCheck : OnboardingAction
|
object StopEmailValidationCheck : OnboardingAction
|
||||||
|
|
||||||
data class PostRegisterAction(val registerAction: RegisterAction) : OnboardingAction
|
data class PostRegisterAction(val registerAction: RegisterAction) : OnboardingAction
|
||||||
|
|
|
@ -23,7 +23,6 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import androidx.autofill.HintConstants
|
import androidx.autofill.HintConstants
|
||||||
import androidx.core.text.isDigitsOnly
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
|
@ -52,7 +51,9 @@ import org.matrix.android.sdk.api.failure.isInvalidUsername
|
||||||
import org.matrix.android.sdk.api.failure.isLoginEmailUnknown
|
import org.matrix.android.sdk.api.failure.isLoginEmailUnknown
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class FtueAuthCombinedLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment<FragmentFtueCombinedLoginBinding>() {
|
class FtueAuthCombinedLoginFragment @Inject constructor(
|
||||||
|
private val loginFieldsValidation: LoginFieldsValidation
|
||||||
|
) : AbstractSSOFtueAuthFragment<FragmentFtueCombinedLoginBinding>() {
|
||||||
|
|
||||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueCombinedLoginBinding {
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueCombinedLoginBinding {
|
||||||
return FragmentFtueCombinedLoginBinding.inflate(inflater, container, false)
|
return FragmentFtueCombinedLoginBinding.inflate(inflater, container, false)
|
||||||
|
@ -61,12 +62,12 @@ class FtueAuthCombinedLoginFragment @Inject constructor() : AbstractSSOFtueAuthF
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
setupSubmitButton()
|
setupSubmitButton()
|
||||||
views.createAccountRoot.realignPercentagesToParent()
|
views.loginRoot.realignPercentagesToParent()
|
||||||
views.editServerButton.debouncedClicks {
|
views.editServerButton.debouncedClicks {
|
||||||
viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection))
|
viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection))
|
||||||
}
|
}
|
||||||
|
|
||||||
views.createAccountPasswordInput.editText().setOnEditorActionListener { _, actionId, _ ->
|
views.loginPasswordInput.editText().setOnEditorActionListener { _, actionId, _ ->
|
||||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
submit()
|
submit()
|
||||||
return@setOnEditorActionListener true
|
return@setOnEditorActionListener true
|
||||||
|
@ -76,54 +77,38 @@ class FtueAuthCombinedLoginFragment @Inject constructor() : AbstractSSOFtueAuthF
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupSubmitButton() {
|
private fun setupSubmitButton() {
|
||||||
views.createAccountSubmit.setOnClickListener { submit() }
|
views.loginSubmit.setOnClickListener { submit() }
|
||||||
observeInputFields()
|
observeInputFields()
|
||||||
.onEach {
|
.onEach {
|
||||||
views.createAccountPasswordInput.error = null
|
views.loginPasswordInput.error = null
|
||||||
views.createAccountInput.error = null
|
views.loginInput.error = null
|
||||||
views.createAccountSubmit.isEnabled = it
|
views.loginSubmit.isEnabled = it
|
||||||
}
|
}
|
||||||
.launchIn(viewLifecycleOwner.lifecycleScope)
|
.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeInputFields() = combine(
|
private fun observeInputFields() = combine(
|
||||||
views.createAccountInput.hasContentFlow { it.trim() },
|
views.loginInput.hasContentFlow { it.trim() },
|
||||||
views.createAccountPasswordInput.hasContentFlow(),
|
views.loginPasswordInput.hasContentFlow(),
|
||||||
transform = { isLoginNotEmpty, isPasswordNotEmpty -> isLoginNotEmpty && isPasswordNotEmpty }
|
transform = { isLoginNotEmpty, isPasswordNotEmpty -> isLoginNotEmpty && isPasswordNotEmpty }
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun submit() {
|
private fun submit() {
|
||||||
withState(viewModel) { state ->
|
withState(viewModel) { state ->
|
||||||
cleanupUi()
|
cleanupUi()
|
||||||
|
val login = views.loginInput.content()
|
||||||
val login = views.createAccountInput.content()
|
val password = views.loginPasswordInput.content()
|
||||||
val password = views.createAccountPasswordInput.content()
|
val isMatrixOrg = state.selectedHomeserver.userFacingUrl == getString(R.string.matrix_org_server_url)
|
||||||
|
loginFieldsValidation.validate(login, password, isMatrixOrg).onValid {
|
||||||
// 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 = getString(R.string.error_forbidden_digits_only_username)
|
|
||||||
error++
|
|
||||||
}
|
|
||||||
if (password.isEmpty()) {
|
|
||||||
views.createAccountPasswordInput.error = getString(R.string.error_empty_field_choose_password)
|
|
||||||
error++
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == 0) {
|
|
||||||
viewModel.handle(OnboardingAction.Login(login, password, getString(R.string.login_default_session_public_name)))
|
viewModel.handle(OnboardingAction.Login(login, password, getString(R.string.login_default_session_public_name)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cleanupUi() {
|
private fun cleanupUi() {
|
||||||
views.createAccountSubmit.hideKeyboard()
|
views.loginSubmit.hideKeyboard()
|
||||||
views.createAccountInput.error = null
|
views.loginInput.error = null
|
||||||
views.createAccountPasswordInput.error = null
|
views.loginPasswordInput.error = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun resetViewModel() {
|
override fun resetViewModel() {
|
||||||
|
@ -132,16 +117,16 @@ class FtueAuthCombinedLoginFragment @Inject constructor() : AbstractSSOFtueAuthF
|
||||||
|
|
||||||
override fun onError(throwable: Throwable) {
|
override fun onError(throwable: Throwable) {
|
||||||
// Trick to display the error without text.
|
// Trick to display the error without text.
|
||||||
views.createAccountInput.error = " "
|
views.loginInput.error = " "
|
||||||
when {
|
when {
|
||||||
throwable.isInvalidUsername() -> {
|
throwable.isInvalidUsername() -> {
|
||||||
views.createAccountInput.error = errorFormatter.toHumanReadable(throwable)
|
views.loginInput.error = errorFormatter.toHumanReadable(throwable)
|
||||||
}
|
}
|
||||||
throwable.isLoginEmailUnknown() -> {
|
throwable.isLoginEmailUnknown() -> {
|
||||||
views.createAccountInput.error = getString(R.string.login_login_with_email_error)
|
views.loginInput.error = getString(R.string.login_login_with_email_error)
|
||||||
}
|
}
|
||||||
throwable.isInvalidPassword() && views.createAccountPasswordInput.hasSurroundingSpaces() -> {
|
throwable.isInvalidPassword() && views.loginPasswordInput.hasSurroundingSpaces() -> {
|
||||||
views.createAccountPasswordInput.error = getString(R.string.auth_invalid_login_param_space_in_password)
|
views.loginPasswordInput.error = getString(R.string.auth_invalid_login_param_space_in_password)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
super.onError(throwable)
|
super.onError(throwable)
|
||||||
|
@ -158,7 +143,7 @@ class FtueAuthCombinedLoginFragment @Inject constructor() : AbstractSSOFtueAuthF
|
||||||
|
|
||||||
if (state.isLoading) {
|
if (state.isLoading) {
|
||||||
// Ensure password is hidden
|
// Ensure password is hidden
|
||||||
views.createAccountPasswordInput.editText().hidePassword()
|
views.loginPasswordInput.editText().hidePassword()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,10 +174,8 @@ class FtueAuthCombinedLoginFragment @Inject constructor() : AbstractSSOFtueAuthF
|
||||||
|
|
||||||
private fun setupAutoFill() {
|
private fun setupAutoFill() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
views.createAccountInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_USERNAME)
|
views.loginInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_USERNAME)
|
||||||
views.createAccountPasswordInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_PASSWORD)
|
views.loginPasswordInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_PASSWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun OnboardingViewState.isNumericOnlyUserIdForbidden() = selectedHomeserver.userFacingUrl == getString(R.string.matrix_org_server_url)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,9 +157,9 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment<
|
||||||
val initialDeviceName = getString(R.string.login_default_session_public_name)
|
val initialDeviceName = getString(R.string.login_default_session_public_name)
|
||||||
val action = when (state.signMode) {
|
val action = when (state.signMode) {
|
||||||
SignMode.Unknown -> error("developer error")
|
SignMode.Unknown -> error("developer error")
|
||||||
SignMode.SignUp -> OnboardingAction.Register(login, password, initialDeviceName)
|
SignMode.SignUp -> OnboardingAction.Register(username = login, password, initialDeviceName)
|
||||||
SignMode.SignIn -> OnboardingAction.Login(login, password, initialDeviceName)
|
SignMode.SignIn -> OnboardingAction.Login(username = login, password, initialDeviceName)
|
||||||
SignMode.SignInWithMatrixId -> OnboardingAction.LoginDirect(login, password, initialDeviceName)
|
SignMode.SignInWithMatrixId -> OnboardingAction.LoginDirect(matrixId = login, password, initialDeviceName)
|
||||||
}
|
}
|
||||||
viewModel.handle(action)
|
viewModel.handle(action)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* 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.onboarding.ftueauth
|
||||||
|
|
||||||
|
import androidx.core.text.isDigitsOnly
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
typealias LoginValidationResult = Pair<String?, String?>
|
||||||
|
|
||||||
|
class LoginFieldsValidation @Inject constructor(
|
||||||
|
private val stringProvider: StringProvider
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun validate(usernameOrId: String, password: String, isMatrixOrg: Boolean): Pair<String?, String?> {
|
||||||
|
return validateUsernameOrId(usernameOrId, isMatrixOrg) to validatePassword(password)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateUsernameOrId(usernameOrId: String, isMatrixOrg: Boolean): String? {
|
||||||
|
val accountError = when {
|
||||||
|
usernameOrId.isEmpty() -> stringProvider.getString(R.string.error_empty_field_choose_user_name)
|
||||||
|
isNumericOnlyUserIdForbidden(isMatrixOrg) && usernameOrId.isDigitsOnly() -> stringProvider.getString(R.string.error_forbidden_digits_only_username)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
return accountError
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isNumericOnlyUserIdForbidden(isMatrixOrg: Boolean) = isMatrixOrg
|
||||||
|
|
||||||
|
private fun validatePassword(password: String): String? {
|
||||||
|
val passwordError = when {
|
||||||
|
password.isEmpty() -> stringProvider.getString(R.string.error_empty_field_choose_password)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
return passwordError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun LoginValidationResult.onValid(action: () -> Unit) {
|
||||||
|
when {
|
||||||
|
first != null && second != null -> action()
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,19 +10,19 @@
|
||||||
android:paddingBottom="0dp">
|
android:paddingBottom="0dp">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/createAccountRoot"
|
android:id="@+id/loginRoot"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
<androidx.constraintlayout.widget.Guideline
|
||||||
android:id="@+id/createAccountGutterStart"
|
android:id="@+id/loginGutterStart"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_start_percent" />
|
app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_start_percent" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Guideline
|
<androidx.constraintlayout.widget.Guideline
|
||||||
android:id="@+id/createAccountGutterEnd"
|
android:id="@+id/loginGutterEnd"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
@ -32,13 +32,13 @@
|
||||||
android:id="@+id/headerSpacing"
|
android:id="@+id/headerSpacing"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="52dp"
|
android:layout_height="52dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/createAccountHeaderTitle"
|
app:layout_constraintBottom_toTopOf="@id/loginHeaderTitle"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintVertical_bias="0"
|
app:layout_constraintVertical_bias="0"
|
||||||
app:layout_constraintVertical_chainStyle="packed" />
|
app:layout_constraintVertical_chainStyle="packed" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/createAccountHeaderTitle"
|
android:id="@+id/loginHeaderTitle"
|
||||||
style="@style/Widget.Vector.TextView.Title.Medium"
|
style="@style/Widget.Vector.TextView.Title.Medium"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -47,8 +47,8 @@
|
||||||
android:text="@string/ftue_auth_welcome_back_title"
|
android:text="@string/ftue_auth_welcome_back_title"
|
||||||
android:textColor="?vctr_content_primary"
|
android:textColor="?vctr_content_primary"
|
||||||
app:layout_constraintBottom_toTopOf="@id/titleContentSpacing"
|
app:layout_constraintBottom_toTopOf="@id/titleContentSpacing"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/headerSpacing" />
|
app:layout_constraintTop_toBottomOf="@id/headerSpacing" />
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/chooseYourServerHeader"
|
app:layout_constraintBottom_toTopOf="@id/chooseYourServerHeader"
|
||||||
app:layout_constraintHeight_percent="0.03"
|
app:layout_constraintHeight_percent="0.03"
|
||||||
app:layout_constraintTop_toBottomOf="@id/createAccountHeaderTitle" />
|
app:layout_constraintTop_toBottomOf="@id/loginHeaderTitle" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/chooseYourServerHeader"
|
android:id="@+id/chooseYourServerHeader"
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
android:textColor="?vctr_content_secondary"
|
android:textColor="?vctr_content_secondary"
|
||||||
app:layout_constraintBottom_toTopOf="@id/selectedServerName"
|
app:layout_constraintBottom_toTopOf="@id/selectedServerName"
|
||||||
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/titleContentSpacing" />
|
app:layout_constraintTop_toBottomOf="@id/titleContentSpacing" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
android:textColor="?vctr_content_primary"
|
android:textColor="?vctr_content_primary"
|
||||||
app:layout_constraintBottom_toTopOf="@id/selectedServerDescription"
|
app:layout_constraintBottom_toTopOf="@id/selectedServerDescription"
|
||||||
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/chooseYourServerHeader" />
|
app:layout_constraintTop_toBottomOf="@id/chooseYourServerHeader" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
android:textColor="?vctr_content_tertiary"
|
android:textColor="?vctr_content_tertiary"
|
||||||
app:layout_constraintBottom_toTopOf="@id/serverSelectionSpacing"
|
app:layout_constraintBottom_toTopOf="@id/serverSelectionSpacing"
|
||||||
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
app:layout_constraintEnd_toStartOf="@id/editServerButton"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/selectedServerName" />
|
app:layout_constraintTop_toBottomOf="@id/selectedServerName" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@ -108,14 +108,14 @@
|
||||||
android:text="@string/ftue_auth_create_account_edit_server_selection"
|
android:text="@string/ftue_auth_create_account_edit_server_selection"
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/selectedServerDescription"
|
app:layout_constraintBottom_toBottomOf="@id/selectedServerDescription"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintTop_toTopOf="@id/chooseYourServerHeader" />
|
app:layout_constraintTop_toTopOf="@id/chooseYourServerHeader" />
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:id="@+id/serverSelectionSpacing"
|
android:id="@+id/serverSelectionSpacing"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/createAccountInput"
|
app:layout_constraintBottom_toTopOf="@id/loginInput"
|
||||||
app:layout_constraintHeight_percent="0.05"
|
app:layout_constraintHeight_percent="0.05"
|
||||||
app:layout_constraintTop_toBottomOf="@id/selectedServerDescription" />
|
app:layout_constraintTop_toBottomOf="@id/selectedServerDescription" />
|
||||||
|
|
||||||
|
@ -124,19 +124,19 @@
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="?vctr_content_quaternary"
|
android:background="?vctr_content_quaternary"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/serverSelectionSpacing"
|
app:layout_constraintBottom_toBottomOf="@id/serverSelectionSpacing"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toTopOf="@id/serverSelectionSpacing" />
|
app:layout_constraintTop_toTopOf="@id/serverSelectionSpacing" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/createAccountInput"
|
android:id="@+id/loginInput"
|
||||||
style="@style/Widget.Vector.TextInputLayout.Username"
|
style="@style/Widget.Vector.TextInputLayout.Username"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/username"
|
android:hint="@string/username"
|
||||||
app:layout_constraintBottom_toTopOf="@id/createAccountEntryFooter"
|
app:layout_constraintBottom_toTopOf="@id/loginEntryFooter"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/serverSelectionSpacing">
|
app:layout_constraintTop_toBottomOf="@id/serverSelectionSpacing">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
@ -145,39 +145,39 @@
|
||||||
android:imeOptions="actionNext"
|
android:imeOptions="actionNext"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:nextFocusForward="@id/createAccountPasswordInput" />
|
android:nextFocusForward="@id/loginPasswordInput" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/createAccountEntryFooter"
|
android:id="@+id/loginEntryFooter"
|
||||||
style="@style/Widget.Vector.TextView.Micro"
|
style="@style/Widget.Vector.TextView.Micro"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="@string/ftue_auth_create_account_username_entry_footer"
|
android:text="@string/ftue_auth_create_account_username_entry_footer"
|
||||||
app:layout_constraintBottom_toTopOf="@id/entrySpacing"
|
app:layout_constraintBottom_toTopOf="@id/entrySpacing"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/createAccountInput" />
|
app:layout_constraintTop_toBottomOf="@id/loginInput" />
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:id="@+id/entrySpacing"
|
android:id="@+id/entrySpacing"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/createAccountPasswordInput"
|
app:layout_constraintBottom_toTopOf="@id/loginPasswordInput"
|
||||||
app:layout_constraintHeight_percent="0.03"
|
app:layout_constraintHeight_percent="0.03"
|
||||||
app:layout_constraintTop_toBottomOf="@id/createAccountEntryFooter" />
|
app:layout_constraintTop_toBottomOf="@id/loginEntryFooter" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/createAccountPasswordInput"
|
android:id="@+id/loginPasswordInput"
|
||||||
style="@style/Widget.Vector.TextInputLayout.Password"
|
style="@style/Widget.Vector.TextInputLayout.Password"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/login_signup_password_hint"
|
android:hint="@string/login_signup_password_hint"
|
||||||
app:layout_constraintBottom_toTopOf="@id/createAccountPasswordEntryFooter"
|
app:layout_constraintBottom_toTopOf="@id/loginPasswordEntryFooter"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/entrySpacing">
|
app:layout_constraintTop_toBottomOf="@id/entrySpacing">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
@ -190,35 +190,35 @@
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/createAccountPasswordEntryFooter"
|
android:id="@+id/loginPasswordEntryFooter"
|
||||||
style="@style/Widget.Vector.TextView.Micro"
|
style="@style/Widget.Vector.TextView.Micro"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="@string/ftue_auth_create_account_password_entry_footer"
|
android:text="@string/ftue_auth_create_account_password_entry_footer"
|
||||||
app:layout_constraintBottom_toTopOf="@id/actionSpacing"
|
app:layout_constraintBottom_toTopOf="@id/actionSpacing"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/createAccountPasswordInput" />
|
app:layout_constraintTop_toBottomOf="@id/loginPasswordInput" />
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:id="@+id/actionSpacing"
|
android:id="@+id/actionSpacing"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/createAccountSubmit"
|
app:layout_constraintBottom_toTopOf="@id/loginSubmit"
|
||||||
app:layout_constraintHeight_percent="0.02"
|
app:layout_constraintHeight_percent="0.02"
|
||||||
app:layout_constraintTop_toBottomOf="@id/createAccountPasswordEntryFooter" />
|
app:layout_constraintTop_toBottomOf="@id/loginPasswordEntryFooter" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/createAccountSubmit"
|
android:id="@+id/loginSubmit"
|
||||||
style="@style/Widget.Vector.Button.Login"
|
style="@style/Widget.Vector.Button.Login"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/login_signup_submit"
|
android:text="@string/login_signup_submit"
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
app:layout_constraintBottom_toTopOf="@id/ssoButtonsHeader"
|
app:layout_constraintBottom_toTopOf="@id/ssoButtonsHeader"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/actionSpacing" />
|
app:layout_constraintTop_toBottomOf="@id/actionSpacing" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.Group
|
<androidx.constraintlayout.widget.Group
|
||||||
|
@ -228,7 +228,7 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:constraint_referenced_ids="ssoButtonsHeader,ssoButtons"
|
app:constraint_referenced_ids="ssoButtonsHeader,ssoButtons"
|
||||||
app:layout_constraintBottom_toTopOf="@id/ssoButtonsHeader"
|
app:layout_constraintBottom_toTopOf="@id/ssoButtonsHeader"
|
||||||
app:layout_constraintTop_toBottomOf="@id/createAccountSubmit"
|
app:layout_constraintTop_toBottomOf="@id/loginSubmit"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -241,9 +241,9 @@
|
||||||
android:text="@string/ftue_auth_create_account_sso_section_header"
|
android:text="@string/ftue_auth_create_account_sso_section_header"
|
||||||
android:textColor="?vctr_content_secondary"
|
android:textColor="?vctr_content_secondary"
|
||||||
app:layout_constraintBottom_toTopOf="@id/ssoButtons"
|
app:layout_constraintBottom_toTopOf="@id/ssoButtons"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/createAccountSubmit" />
|
app:layout_constraintTop_toBottomOf="@id/loginSubmit" />
|
||||||
|
|
||||||
<im.vector.app.features.login.SocialLoginButtonsView
|
<im.vector.app.features.login.SocialLoginButtonsView
|
||||||
android:id="@+id/ssoButtons"
|
android:id="@+id/ssoButtons"
|
||||||
|
@ -251,8 +251,8 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd"
|
app:layout_constraintEnd_toEndOf="@id/loginGutterEnd"
|
||||||
app:layout_constraintStart_toStartOf="@id/createAccountGutterStart"
|
app:layout_constraintStart_toStartOf="@id/loginGutterStart"
|
||||||
app:layout_constraintTop_toBottomOf="@id/ssoButtonsHeader"
|
app:layout_constraintTop_toBottomOf="@id/ssoButtonsHeader"
|
||||||
tools:signMode="signup" />
|
tools:signMode="signup" />
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ private val A_WELLKNOWN_FAILED_WITH_CONTENT_RESULT = WellknownResult.FailPrompt(
|
||||||
private val A_WELLKNOWN_FAILED_WITHOUT_CONTENT_RESULT = WellknownResult.FailPrompt(null, null)
|
private val A_WELLKNOWN_FAILED_WITHOUT_CONTENT_RESULT = WellknownResult.FailPrompt(null, null)
|
||||||
private val NO_HOMESERVER_CONFIG: HomeServerConnectionConfig? = null
|
private val NO_HOMESERVER_CONFIG: HomeServerConnectionConfig? = null
|
||||||
private val A_FALLBACK_CONFIG: HomeServerConnectionConfig = HomeServerConnectionConfig(
|
private val A_FALLBACK_CONFIG: HomeServerConnectionConfig = HomeServerConnectionConfig(
|
||||||
homeServerUri = FakeUri("https://${A_LOGIN_OR_REGISTER_ACTION.username.getServerName()}").instance,
|
homeServerUri = FakeUri("https://${A_LOGIN_OR_REGISTER_ACTION.matrixId.getServerName()}").instance,
|
||||||
homeServerUriBase = FakeUri(A_WELLKNOWN_SUCCESS_RESULT.homeServerUrl).instance,
|
homeServerUriBase = FakeUri(A_WELLKNOWN_SUCCESS_RESULT.homeServerUrl).instance,
|
||||||
identityServerUri = null
|
identityServerUri = null
|
||||||
)
|
)
|
||||||
|
@ -54,7 +54,7 @@ class DirectLoginUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when logging in directly, then returns success with direct session result`() = runTest {
|
fun `when logging in directly, then returns success with direct session result`() = runTest {
|
||||||
fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_SUCCESS_RESULT)
|
fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.matrixId, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_SUCCESS_RESULT)
|
||||||
val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
|
val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
|
||||||
fakeAuthenticationService.givenDirectAuthentication(A_FALLBACK_CONFIG, username, password, initialDeviceName, result = fakeSession)
|
fakeAuthenticationService.givenDirectAuthentication(A_FALLBACK_CONFIG, username, password, initialDeviceName, result = fakeSession)
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class DirectLoginUseCaseTest {
|
||||||
@Test
|
@Test
|
||||||
fun `given wellknown fails with content, when logging in directly, then returns success with direct session result`() = runTest {
|
fun `given wellknown fails with content, when logging in directly, then returns success with direct session result`() = runTest {
|
||||||
fakeAuthenticationService.givenWellKnown(
|
fakeAuthenticationService.givenWellKnown(
|
||||||
A_LOGIN_OR_REGISTER_ACTION.username,
|
A_LOGIN_OR_REGISTER_ACTION.matrixId,
|
||||||
config = NO_HOMESERVER_CONFIG,
|
config = NO_HOMESERVER_CONFIG,
|
||||||
result = A_WELLKNOWN_FAILED_WITH_CONTENT_RESULT
|
result = A_WELLKNOWN_FAILED_WITH_CONTENT_RESULT
|
||||||
)
|
)
|
||||||
|
@ -81,7 +81,7 @@ class DirectLoginUseCaseTest {
|
||||||
@Test
|
@Test
|
||||||
fun `given wellknown fails without content, when logging in directly, then returns well known error`() = runTest {
|
fun `given wellknown fails without content, when logging in directly, then returns well known error`() = runTest {
|
||||||
fakeAuthenticationService.givenWellKnown(
|
fakeAuthenticationService.givenWellKnown(
|
||||||
A_LOGIN_OR_REGISTER_ACTION.username,
|
A_LOGIN_OR_REGISTER_ACTION.matrixId,
|
||||||
config = NO_HOMESERVER_CONFIG,
|
config = NO_HOMESERVER_CONFIG,
|
||||||
result = A_WELLKNOWN_FAILED_WITHOUT_CONTENT_RESULT
|
result = A_WELLKNOWN_FAILED_WITHOUT_CONTENT_RESULT
|
||||||
)
|
)
|
||||||
|
@ -97,7 +97,7 @@ class DirectLoginUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given wellknown throws, when logging in directly, then returns failure result with original cause`() = runTest {
|
fun `given wellknown throws, when logging in directly, then returns failure result with original cause`() = runTest {
|
||||||
fakeAuthenticationService.givenWellKnownThrows(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, cause = AN_ERROR)
|
fakeAuthenticationService.givenWellKnownThrows(A_LOGIN_OR_REGISTER_ACTION.matrixId, config = NO_HOMESERVER_CONFIG, cause = AN_ERROR)
|
||||||
|
|
||||||
val result = useCase.execute(A_LOGIN_OR_REGISTER_ACTION, homeServerConnectionConfig = NO_HOMESERVER_CONFIG)
|
val result = useCase.execute(A_LOGIN_OR_REGISTER_ACTION, homeServerConnectionConfig = NO_HOMESERVER_CONFIG)
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ class DirectLoginUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given direct authentication throws, when logging in directly, then returns failure result with original cause`() = runTest {
|
fun `given direct authentication throws, when logging in directly, then returns failure result with original cause`() = runTest {
|
||||||
fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.username, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_SUCCESS_RESULT)
|
fakeAuthenticationService.givenWellKnown(A_LOGIN_OR_REGISTER_ACTION.matrixId, config = NO_HOMESERVER_CONFIG, result = A_WELLKNOWN_SUCCESS_RESULT)
|
||||||
val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
|
val (username, password, initialDeviceName) = A_LOGIN_OR_REGISTER_ACTION
|
||||||
fakeAuthenticationService.givenDirectAuthenticationThrows(A_FALLBACK_CONFIG, username, password, initialDeviceName, cause = AN_ERROR)
|
fakeAuthenticationService.givenDirectAuthenticationThrows(A_FALLBACK_CONFIG, username, password, initialDeviceName, cause = AN_ERROR)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue