Improve logic to trigger LockScreenViewEvents

This commit is contained in:
Jorge Martín 2022-08-09 14:02:26 +02:00
parent cc59b9e695
commit 9888e15f2a
4 changed files with 19 additions and 15 deletions

View File

@ -22,4 +22,5 @@ import im.vector.app.core.platform.VectorViewModelAction
sealed class LockScreenAction : VectorViewModelAction {
data class PinCodeEntered(val value: String) : LockScreenAction()
data class ShowBiometricPrompt(val callingActivity: FragmentActivity) : LockScreenAction()
object OnUIReady : LockScreenAction()
}

View File

@ -23,7 +23,6 @@ import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import dagger.hilt.android.AndroidEntryPoint
@ -34,10 +33,6 @@ import im.vector.app.databinding.FragmentLockScreenBinding
import im.vector.app.features.pin.lockscreen.configuration.LockScreenConfiguration
import im.vector.app.features.pin.lockscreen.configuration.LockScreenMode
import im.vector.app.features.pin.lockscreen.views.LockScreenCodeView
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@AndroidEntryPoint
class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
@ -59,12 +54,7 @@ class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
handleEvent(it)
}
viewModel.stateFlow.distinctUntilChangedBy { it.showBiometricPromptAutomatically }
.filter { it.showBiometricPromptAutomatically }
.onEach {
showBiometricPrompt()
}
.launchIn(viewLifecycleOwner.lifecycleScope)
viewModel.handle(LockScreenAction.OnUIReady)
}
override fun invalidate() = withState(viewModel) { state ->
@ -119,6 +109,7 @@ class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
is LockScreenViewEvent.AuthFailure -> onAuthFailure(viewEvent.method)
is LockScreenViewEvent.AuthError -> onAuthError(viewEvent.method, viewEvent.throwable)
is LockScreenViewEvent.ShowBiometricKeyInvalidatedMessage -> lockScreenListener?.onBiometricKeyInvalidated()
is LockScreenViewEvent.ShowBiometricPromptAutomatically -> showBiometricPrompt()
}
}

View File

@ -25,4 +25,5 @@ sealed class LockScreenViewEvent : VectorViewEvents {
data class AuthFailure(val method: AuthMethod) : LockScreenViewEvent()
data class AuthError(val method: AuthMethod, val throwable: Throwable) : LockScreenViewEvent()
object ShowBiometricKeyInvalidatedMessage : LockScreenViewEvent()
object ShowBiometricPromptAutomatically : LockScreenViewEvent()
}

View File

@ -20,7 +20,6 @@ import android.annotation.SuppressLint
import android.app.KeyguardManager
import android.os.Build
import android.security.keystore.KeyPermanentlyInvalidatedException
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.FragmentActivity
import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted
@ -37,6 +36,7 @@ import im.vector.app.features.pin.lockscreen.pincode.PinCodeHelper
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@ -77,10 +77,20 @@ class LockScreenViewModel @AssistedInject constructor(
lockScreenKeysMigrator.migrateIfNeeded()
// Update initial state with biometric info
updateStateWithBiometricInfo()
}
}
val state = awaitState()
// If when initialized we detect a key invalidation, we should show an error message.
if (state.isBiometricKeyInvalidated) {
private fun observeStateChanges() {
// The first time the state allows it, show the biometric prompt
viewModelScope.launch {
if (stateFlow.firstOrNull { it.showBiometricPromptAutomatically } != null) {
_viewEvents.post(LockScreenViewEvent.ShowBiometricPromptAutomatically)
}
}
// The first time the state allows it, react to biometric key being invalidated
viewModelScope.launch {
if (stateFlow.firstOrNull { it.isBiometricKeyInvalidated } != null) {
onBiometricKeyInvalidated()
}
}
@ -90,6 +100,7 @@ class LockScreenViewModel @AssistedInject constructor(
when (action) {
is LockScreenAction.PinCodeEntered -> onPinCodeEntered(action.value)
is LockScreenAction.ShowBiometricPrompt -> showBiometricPrompt(action.callingActivity)
is LockScreenAction.OnUIReady -> observeStateChanges()
}
}