Skip to content
Snippets Groups Projects
Commit 40af6913 authored by Taras's avatar Taras
Browse files

Implement select password on login

parent c7feccef
No related branches found
No related tags found
No related merge requests found
...@@ -55,7 +55,7 @@ class PasswordDataSource @Inject constructor( ...@@ -55,7 +55,7 @@ class PasswordDataSource @Inject constructor(
is Response.Error -> result is Response.Error -> result
} }
} }
private suspend fun processDirectPasswordStage(password: String): Response<Unit> { private suspend fun processDirectPasswordStage(password: String): Response<Unit> {
val result = createResult { val result = createResult {
MatrixInstanceProvider.matrix.authenticationService().getLoginWizard().login( MatrixInstanceProvider.matrix.authenticationService().getLoginWizard().login(
......
...@@ -16,6 +16,7 @@ import org.futo.circles.auth.feature.uia.stages.password.confirmation.SetupPassw ...@@ -16,6 +16,7 @@ import org.futo.circles.auth.feature.uia.stages.password.confirmation.SetupPassw
import org.futo.circles.core.base.fragment.HasLoadingState import org.futo.circles.core.base.fragment.HasLoadingState
import org.futo.circles.core.base.fragment.ParentBackPressOwnerFragment import org.futo.circles.core.base.fragment.ParentBackPressOwnerFragment
import org.futo.circles.core.extensions.getText import org.futo.circles.core.extensions.getText
import org.futo.circles.core.extensions.observeData
import org.futo.circles.core.extensions.observeResponse import org.futo.circles.core.extensions.observeResponse
import org.futo.circles.core.extensions.setIsVisible import org.futo.circles.core.extensions.setIsVisible
import org.futo.circles.core.extensions.showError import org.futo.circles.core.extensions.showError
...@@ -33,6 +34,7 @@ class PasswordFragment : ParentBackPressOwnerFragment(R.layout.fragment_password ...@@ -33,6 +34,7 @@ class PasswordFragment : ParentBackPressOwnerFragment(R.layout.fragment_password
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupViews() setupViews()
setupObservers() setupObservers()
if (!isSignupMode()) viewModel.getCredentials(requireContext())
} }
override fun onResume() { override fun onResume() {
...@@ -73,14 +75,18 @@ class PasswordFragment : ParentBackPressOwnerFragment(R.layout.fragment_password ...@@ -73,14 +75,18 @@ class PasswordFragment : ParentBackPressOwnerFragment(R.layout.fragment_password
private fun setupObservers() { private fun setupObservers() {
viewModel.passwordResponseLiveData.observeResponse(this, viewModel.passwordResponseLiveData.observeResponse(this,
error = { showError(getString(R.string.invalid_password)) }) error = { showError(getString(R.string.invalid_password)) })
viewModel.passwordSelectedEventLiveData.observeData(this) {
startLoading(binding.btnLogin)
binding.etPassword.setText(it)
}
} }
private fun onPasswordDataChanged() { private fun onPasswordDataChanged() {
val password = binding.tilPassword.getText() val password = binding.tilPassword.getText()
val repeat = binding.tilRepeatPassword.getText() val repeat = binding.tilRepeatPassword.getText()
binding.btnLogin.isEnabled = if (isSignupMode()) { binding.btnLogin.isEnabled = if (isSignupMode()) {
binding.vPasswordStrength.isPasswordStrong() && password == repeat && password.isNotEmpty() binding.vPasswordStrength.isPasswordStrong() && password == repeat && password.isNotEmpty() && !binding.btnLogin.isLoading
} else password.isNotEmpty() } else password.isNotEmpty() && !binding.btnLogin.isLoading
} }
private fun showPasswordWarningIfNeeded() { private fun showPasswordWarningIfNeeded() {
......
package org.futo.circles.auth.feature.uia.stages.password package org.futo.circles.auth.feature.uia.stages.password
import android.content.Context
import androidx.credentials.CredentialManager
import androidx.credentials.GetCredentialRequest
import androidx.credentials.GetPasswordOption
import androidx.credentials.PasswordCredential
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import org.futo.circles.auth.feature.uia.UIADataSourceProvider
import org.futo.circles.core.base.SingleEventLiveData import org.futo.circles.core.base.SingleEventLiveData
import org.futo.circles.core.extensions.Response import org.futo.circles.core.extensions.Response
import org.futo.circles.core.extensions.launchBg import org.futo.circles.core.extensions.launchBg
import org.matrix.android.sdk.api.extensions.tryOrNull
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
...@@ -14,13 +21,40 @@ class PasswordViewModel @Inject constructor( ...@@ -14,13 +21,40 @@ class PasswordViewModel @Inject constructor(
private var isPasswordWarningConfirmed: Boolean = false private var isPasswordWarningConfirmed: Boolean = false
val passwordResponseLiveData = SingleEventLiveData<Response<Unit>>() val passwordResponseLiveData = SingleEventLiveData<Response<Unit>>()
val passwordSelectedEventLiveData = SingleEventLiveData<String>()
fun processPasswordStage(password: String) { fun processPasswordStage(password: String) {
launchBg { handlePasswordRequest(password) }
}
fun getCredentials(activityContext: Context) {
launchBg { launchBg {
passwordResponseLiveData.postValue(passwordDataSource.processPasswordStage(password)) tryOrNull {
val credentialManager = CredentialManager.create(activityContext)
val userName = UIADataSourceProvider.getDataSourceOrThrow().userName
val request = GetCredentialRequest(
listOf(GetPasswordOption(allowedUserIds = setOf(userName)))
)
val result = credentialManager.getCredential(
context = activityContext,
request = request
).credential
if (result is PasswordCredential) {
val password = result.password
passwordSelectedEventLiveData.postValue(password)
handlePasswordRequest(password)
}
}
} }
} }
private suspend fun handlePasswordRequest(password: String) {
val result = passwordDataSource.processPasswordStage(password)
passwordResponseLiveData.postValue(result)
}
fun isPasswordWarningConfirmed() = isPasswordWarningConfirmed fun isPasswordWarningConfirmed() = isPasswordWarningConfirmed
fun confirmPasswordWarning() { fun confirmPasswordWarning() {
isPasswordWarningConfirmed = true isPasswordWarningConfirmed = true
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
android:autofillHints="password" android:autofillHints="password"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:inputType="textPassword" android:inputType="textPassword"
android:isCredential="true"
android:padding="8dp" /> android:padding="8dp" />
<org.futo.circles.auth.view.PasswordStrengthView <org.futo.circles.auth.view.PasswordStrengthView
......
...@@ -7,7 +7,6 @@ import android.util.TypedValue ...@@ -7,7 +7,6 @@ import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.doOnLayout
import org.futo.circles.core.R import org.futo.circles.core.R
import org.futo.circles.core.databinding.ViewLoadingButtonBinding import org.futo.circles.core.databinding.ViewLoadingButtonBinding
import org.futo.circles.core.extensions.getAttributes import org.futo.circles.core.extensions.getAttributes
...@@ -31,7 +30,8 @@ class LoadingButton( ...@@ -31,7 +30,8 @@ class LoadingButton(
ViewLoadingButtonBinding.inflate(LayoutInflater.from(context), this) ViewLoadingButtonBinding.inflate(LayoutInflater.from(context), this)
private var buttonText: String = "" private var buttonText: String = ""
private var isLoading: Boolean = false var isLoading: Boolean = false
private set
init { init {
getAttributes(attrs, R.styleable.LoadingButton) { getAttributes(attrs, R.styleable.LoadingButton) {
...@@ -60,7 +60,7 @@ class LoadingButton( ...@@ -60,7 +60,7 @@ class LoadingButton(
override fun onRestoreInstanceState(state: Parcelable?) { override fun onRestoreInstanceState(state: Parcelable?) {
val loadingButtonState = state as? LoadingButtonState val loadingButtonState = state as? LoadingButtonState
super.onRestoreInstanceState(loadingButtonState?.superSavedState ?: state) super.onRestoreInstanceState(loadingButtonState?.superSavedState ?: state)
doOnLayout { post {
setText(loadingButtonState?.text ?: "") setText(loadingButtonState?.text ?: "")
setIsLoading(loadingButtonState?.isLoading ?: false) setIsLoading(loadingButtonState?.isLoading ?: false)
isEnabled = loadingButtonState?.isEnabled ?: true isEnabled = loadingButtonState?.isEnabled ?: true
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment