mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-17 04:20:00 +03:00
Login screens: improve LoginFragment
This commit is contained in:
parent
c6b0ae63ea
commit
d50b690523
4 changed files with 103 additions and 12 deletions
55
vector/src/main/java/im/vector/riotx/core/utils/ViewUtils.kt
Normal file
55
vector/src/main/java/im/vector/riotx/core/utils/ViewUtils.kt
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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.riotx.core.utils
|
||||||
|
|
||||||
|
import android.text.Editable
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.children
|
||||||
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
|
import im.vector.riotx.core.platform.SimpleTextWatcher
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all TextInputLayout in a ViewGroup and in all its descendants
|
||||||
|
*/
|
||||||
|
fun ViewGroup.findAllTextInputLayout(): List<TextInputLayout> {
|
||||||
|
val res = ArrayList<TextInputLayout>()
|
||||||
|
|
||||||
|
children.forEach {
|
||||||
|
if (it is TextInputLayout) {
|
||||||
|
res.add(it)
|
||||||
|
} else if (it is ViewGroup) {
|
||||||
|
// Recursive call
|
||||||
|
res.addAll(it.findAllTextInputLayout())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a text change listener to all TextInputEditText to reset error on its TextInputLayout when the text is changed
|
||||||
|
*/
|
||||||
|
fun autoResetTextInputLayoutErrors(textInputLayouts: List<TextInputLayout>) {
|
||||||
|
textInputLayouts.forEach {
|
||||||
|
it.editText?.addTextChangedListener(object : SimpleTextWatcher() {
|
||||||
|
override fun afterTextChanged(s: Editable) {
|
||||||
|
// Reset the error
|
||||||
|
it.error = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ package im.vector.riotx.features.login
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.transition.TransitionManager
|
import androidx.core.view.isVisible
|
||||||
import com.airbnb.mvrx.Fail
|
import com.airbnb.mvrx.Fail
|
||||||
import com.airbnb.mvrx.Loading
|
import com.airbnb.mvrx.Loading
|
||||||
import com.airbnb.mvrx.Success
|
import com.airbnb.mvrx.Success
|
||||||
|
@ -69,9 +69,14 @@ class LoginFragment @Inject constructor(
|
||||||
isLoginNotEmpty && isPasswordNotEmpty
|
isLoginNotEmpty && isPasswordNotEmpty
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.subscribeBy { authenticateButton.isEnabled = it }
|
.subscribeBy {
|
||||||
.disposeOnDestroyView()
|
loginFieldTil.error = null
|
||||||
authenticateButton.setOnClickListener { authenticate() }
|
passwordFieldTil.error = null
|
||||||
|
loginSubmit.isEnabled = it
|
||||||
|
}
|
||||||
|
.disposeOnDestroy()
|
||||||
|
|
||||||
|
loginSubmit.setOnClickListener { authenticate() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// // TODO Move to server selection screen
|
// // TODO Move to server selection screen
|
||||||
|
@ -108,7 +113,28 @@ class LoginFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidate() = withState(viewModel) { state ->
|
override fun invalidate() = withState(viewModel) { state ->
|
||||||
TransitionManager.beginDelayedTransition(login_fragment)
|
when (state.serverType) {
|
||||||
|
ServerType.MatrixOrg -> {
|
||||||
|
loginServerIcon.isVisible = true
|
||||||
|
loginServerIcon.setImageResource(R.drawable.ic_logo_matrix_org)
|
||||||
|
loginTitle.text = getString(R.string.login_connect_to, "matrix.org")
|
||||||
|
loginNotice.text = getString(R.string.login_server_matrix_org_text)
|
||||||
|
}
|
||||||
|
ServerType.Modular -> {
|
||||||
|
loginServerIcon.isVisible = true
|
||||||
|
loginServerIcon.setImageResource(R.drawable.ic_logo_modular)
|
||||||
|
// TODO
|
||||||
|
loginTitle.text = getString(R.string.login_connect_to, "TODO")
|
||||||
|
// TODO Remove https://
|
||||||
|
loginNotice.text = viewModel.getHomeServerUrl()
|
||||||
|
}
|
||||||
|
ServerType.Other -> {
|
||||||
|
loginServerIcon.isVisible = false
|
||||||
|
loginTitle.text = getString(R.string.login_server_other_title)
|
||||||
|
// TODO Remove https://
|
||||||
|
loginNotice.text = viewModel.getHomeServerUrl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when (state.asyncLoginAction) {
|
when (state.asyncLoginAction) {
|
||||||
is Loading -> {
|
is Loading -> {
|
||||||
|
@ -117,8 +143,9 @@ class LoginFragment @Inject constructor(
|
||||||
renderPasswordField()
|
renderPasswordField()
|
||||||
}
|
}
|
||||||
is Fail -> {
|
is Fail -> {
|
||||||
|
// TODO This does not work, we want the error to be on without text. Fix that
|
||||||
|
loginFieldTil.error = ""
|
||||||
// TODO Handle error text properly
|
// TODO Handle error text properly
|
||||||
// TODO Reset error when text is changed
|
|
||||||
passwordFieldTil.error = errorFormatter.toHumanReadable(state.asyncLoginAction.error)
|
passwordFieldTil.error = errorFormatter.toHumanReadable(state.asyncLoginAction.error)
|
||||||
}
|
}
|
||||||
// Success is handled by the LoginActivity
|
// Success is handled by the LoginActivity
|
||||||
|
|
|
@ -152,6 +152,7 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
|
// TODO Handled JobCancellationException
|
||||||
setState {
|
setState {
|
||||||
copy(
|
copy(
|
||||||
asyncLoginAction = Fail(failure)
|
asyncLoginAction = Fail(failure)
|
||||||
|
|
|
@ -25,24 +25,32 @@
|
||||||
style="@style/LoginTopIcon"
|
style="@style/LoginTopIcon"
|
||||||
android:layout_gravity="center_horizontal" />
|
android:layout_gravity="center_horizontal" />
|
||||||
|
|
||||||
<TextView
|
<ImageView
|
||||||
android:id="@+id/loginServerTitle"
|
android:id="@+id/loginServerIcon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="84dp"
|
android:layout_marginTop="84dp"
|
||||||
|
tools:src="@drawable/ic_logo_matrix_org" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/loginTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||||
android:textAppearance="@style/TextAppearance.Vector.Login.Title"
|
android:textAppearance="@style/TextAppearance.Vector.Login.Title"
|
||||||
tools:text="@string/login_signin_to" />
|
tools:text="@string/login_signin_to" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/loginServerChoiceMatrixOrgText"
|
android:id="@+id/loginNotice"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||||
android:gravity="start"
|
android:gravity="start"
|
||||||
android:text="@string/login_server_matrix_org_text"
|
android:textAppearance="@style/TextAppearance.Vector.Login.Text.Small"
|
||||||
android:textAppearance="@style/TextAppearance.Vector.Login.Text.Small" />
|
tools:text="@string/login_server_matrix_org_text" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/loginFieldTil"
|
||||||
style="@style/VectorTextInputLayout"
|
style="@style/VectorTextInputLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -116,7 +124,7 @@
|
||||||
android:text="@string/auth_forgot_password" />
|
android:text="@string/auth_forgot_password" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/authenticateButton"
|
android:id="@+id/loginSubmit"
|
||||||
style="@style/Style.Vector.Login.Button"
|
style="@style/Style.Vector.Login.Button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
Loading…
Add table
Reference in a new issue