mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 16:10:00 +00:00
PinUnlockEvents -> PinUnlockEvent
This commit is contained in:
committed by
Benoit Marty
parent
668b03f8bc
commit
44baa4a383
+8
-8
@@ -10,12 +10,12 @@ package io.element.android.features.lockscreen.impl.unlock
|
|||||||
|
|
||||||
import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
|
import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
|
||||||
|
|
||||||
sealed interface PinUnlockEvents {
|
sealed interface PinUnlockEvent {
|
||||||
data class OnPinKeypadPressed(val pinKeypadModel: PinKeypadModel) : PinUnlockEvents
|
data class OnPinKeypadPressed(val pinKeypadModel: PinKeypadModel) : PinUnlockEvent
|
||||||
data class OnPinEntryChanged(val entryAsText: String) : PinUnlockEvents
|
data class OnPinEntryChanged(val entryAsText: String) : PinUnlockEvent
|
||||||
data object OnForgetPin : PinUnlockEvents
|
data object OnForgetPin : PinUnlockEvent
|
||||||
data object ClearSignOutPrompt : PinUnlockEvents
|
data object ClearSignOutPrompt : PinUnlockEvent
|
||||||
data object SignOut : PinUnlockEvents
|
data object SignOut : PinUnlockEvent
|
||||||
data object OnUseBiometric : PinUnlockEvents
|
data object OnUseBiometric : PinUnlockEvent
|
||||||
data object ClearBiometricError : PinUnlockEvents
|
data object ClearBiometricError : PinUnlockEvent
|
||||||
}
|
}
|
||||||
+8
-8
@@ -101,28 +101,28 @@ class PinUnlockPresenter(
|
|||||||
isUnlocked.value = true
|
isUnlocked.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleEvent(event: PinUnlockEvents) {
|
fun handleEvent(event: PinUnlockEvent) {
|
||||||
when (event) {
|
when (event) {
|
||||||
is PinUnlockEvents.OnPinKeypadPressed -> {
|
is PinUnlockEvent.OnPinKeypadPressed -> {
|
||||||
pinEntryState.value = pinEntry.process(event.pinKeypadModel)
|
pinEntryState.value = pinEntry.process(event.pinKeypadModel)
|
||||||
}
|
}
|
||||||
PinUnlockEvents.OnForgetPin -> showSignOutPrompt = true
|
PinUnlockEvent.OnForgetPin -> showSignOutPrompt = true
|
||||||
PinUnlockEvents.ClearSignOutPrompt -> showSignOutPrompt = false
|
PinUnlockEvent.ClearSignOutPrompt -> showSignOutPrompt = false
|
||||||
PinUnlockEvents.SignOut -> {
|
PinUnlockEvent.SignOut -> {
|
||||||
if (showSignOutPrompt) {
|
if (showSignOutPrompt) {
|
||||||
showSignOutPrompt = false
|
showSignOutPrompt = false
|
||||||
coroutineScope.signOut(signOutAction)
|
coroutineScope.signOut(signOutAction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PinUnlockEvents.OnUseBiometric -> {
|
PinUnlockEvent.OnUseBiometric -> {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
biometricUnlockResult = biometricUnlock.authenticate()
|
biometricUnlockResult = biometricUnlock.authenticate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PinUnlockEvents.ClearBiometricError -> {
|
PinUnlockEvent.ClearBiometricError -> {
|
||||||
biometricUnlockResult = null
|
biometricUnlockResult = null
|
||||||
}
|
}
|
||||||
is PinUnlockEvents.OnPinEntryChanged -> {
|
is PinUnlockEvent.OnPinEntryChanged -> {
|
||||||
pinEntryState.value = pinEntry.process(event.entryAsText)
|
pinEntryState.value = pinEntry.process(event.entryAsText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ data class PinUnlockState(
|
|||||||
val showBiometricUnlock: Boolean,
|
val showBiometricUnlock: Boolean,
|
||||||
val isUnlocked: Boolean,
|
val isUnlocked: Boolean,
|
||||||
val biometricUnlockResult: BiometricAuthenticator.AuthenticationResult?,
|
val biometricUnlockResult: BiometricAuthenticator.AuthenticationResult?,
|
||||||
val eventSink: (PinUnlockEvents) -> Unit
|
val eventSink: (PinUnlockEvent) -> Unit
|
||||||
) {
|
) {
|
||||||
val isSignOutPromptCancellable = if (pinEntry.isFailure()) {
|
val isSignOutPromptCancellable = if (pinEntry.isFailure()) {
|
||||||
false
|
false
|
||||||
|
|||||||
+8
-8
@@ -69,7 +69,7 @@ fun PinUnlockView(
|
|||||||
) {
|
) {
|
||||||
OnLifecycleEvent { _, event ->
|
OnLifecycleEvent { _, event ->
|
||||||
when (event) {
|
when (event) {
|
||||||
Lifecycle.Event.ON_RESUME -> state.eventSink.invoke(PinUnlockEvents.OnUseBiometric)
|
Lifecycle.Event.ON_RESUME -> state.eventSink.invoke(PinUnlockEvent.OnUseBiometric)
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,8 +78,8 @@ fun PinUnlockView(
|
|||||||
if (state.showSignOutPrompt) {
|
if (state.showSignOutPrompt) {
|
||||||
SignOutPrompt(
|
SignOutPrompt(
|
||||||
isCancellable = state.isSignOutPromptCancellable,
|
isCancellable = state.isSignOutPromptCancellable,
|
||||||
onSignOut = { state.eventSink(PinUnlockEvents.SignOut) },
|
onSignOut = { state.eventSink(PinUnlockEvent.SignOut) },
|
||||||
onDismiss = { state.eventSink(PinUnlockEvents.ClearSignOutPrompt) },
|
onDismiss = { state.eventSink(PinUnlockEvent.ClearSignOutPrompt) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
when (state.signOutAction) {
|
when (state.signOutAction) {
|
||||||
@@ -95,7 +95,7 @@ fun PinUnlockView(
|
|||||||
if (state.showBiometricUnlockError) {
|
if (state.showBiometricUnlockError) {
|
||||||
ErrorDialog(
|
ErrorDialog(
|
||||||
content = state.biometricUnlockErrorMessage ?: "",
|
content = state.biometricUnlockErrorMessage ?: "",
|
||||||
onSubmit = { state.eventSink(PinUnlockEvents.ClearBiometricError) }
|
onSubmit = { state.eventSink(PinUnlockEvent.ClearBiometricError) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,10 +125,10 @@ private fun PinUnlockPage(
|
|||||||
modifier = Modifier.padding(top = 24.dp),
|
modifier = Modifier.padding(top = 24.dp),
|
||||||
showBiometricUnlock = state.showBiometricUnlock,
|
showBiometricUnlock = state.showBiometricUnlock,
|
||||||
onUseBiometric = {
|
onUseBiometric = {
|
||||||
state.eventSink(PinUnlockEvents.OnUseBiometric)
|
state.eventSink(PinUnlockEvent.OnUseBiometric)
|
||||||
},
|
},
|
||||||
onForgotPin = {
|
onForgotPin = {
|
||||||
state.eventSink(PinUnlockEvents.OnForgetPin)
|
state.eventSink(PinUnlockEvent.OnForgetPin)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ private fun PinUnlockPage(
|
|||||||
pinEntry = pinEntry,
|
pinEntry = pinEntry,
|
||||||
isSecured = true,
|
isSecured = true,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
state.eventSink(PinUnlockEvents.OnPinEntryChanged(it))
|
state.eventSink(PinUnlockEvent.OnPinEntryChanged(it))
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.focusRequester(focusRequester)
|
.focusRequester(focusRequester)
|
||||||
@@ -154,7 +154,7 @@ private fun PinUnlockPage(
|
|||||||
} else {
|
} else {
|
||||||
PinKeypad(
|
PinKeypad(
|
||||||
onClick = {
|
onClick = {
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(it))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(it))
|
||||||
},
|
},
|
||||||
maxWidth = constraints.maxWidth,
|
maxWidth = constraints.maxWidth,
|
||||||
maxHeight = constraints.maxHeight,
|
maxHeight = constraints.maxHeight,
|
||||||
|
|||||||
+15
-15
@@ -46,17 +46,17 @@ class PinUnlockPresenterTest {
|
|||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state.pinEntry).isInstanceOf(AsyncData.Success::class.java)
|
assertThat(state.pinEntry).isInstanceOf(AsyncData.Success::class.java)
|
||||||
assertThat(state.remainingAttempts).isInstanceOf(AsyncData.Success::class.java)
|
assertThat(state.remainingAttempts).isInstanceOf(AsyncData.Success::class.java)
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('1')))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('1')))
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('2')))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('2')))
|
||||||
}
|
}
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
state.pinEntry.assertText(halfCompletePin)
|
state.pinEntry.assertText(halfCompletePin)
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('3')))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('3')))
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Back))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Back))
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Empty))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Empty))
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('3')))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('3')))
|
||||||
state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('5')))
|
state.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('5')))
|
||||||
}
|
}
|
||||||
skipItems(4)
|
skipItems(4)
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
@@ -77,10 +77,10 @@ class PinUnlockPresenterTest {
|
|||||||
}
|
}
|
||||||
val numberOfAttempts = initialState.remainingAttempts.dataOrNull() ?: 0
|
val numberOfAttempts = initialState.remainingAttempts.dataOrNull() ?: 0
|
||||||
repeat(numberOfAttempts) {
|
repeat(numberOfAttempts) {
|
||||||
initialState.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('1')))
|
initialState.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('1')))
|
||||||
initialState.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('2')))
|
initialState.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('2')))
|
||||||
initialState.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('3')))
|
initialState.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('3')))
|
||||||
initialState.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('4')))
|
initialState.eventSink(PinUnlockEvent.OnPinKeypadPressed(PinKeypadModel.Number('4')))
|
||||||
}
|
}
|
||||||
skipItems(4 * numberOfAttempts + 2)
|
skipItems(4 * numberOfAttempts + 2)
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
@@ -101,20 +101,20 @@ class PinUnlockPresenterTest {
|
|||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state.pinEntry).isInstanceOf(AsyncData.Success::class.java)
|
assertThat(state.pinEntry).isInstanceOf(AsyncData.Success::class.java)
|
||||||
assertThat(state.remainingAttempts).isInstanceOf(AsyncData.Success::class.java)
|
assertThat(state.remainingAttempts).isInstanceOf(AsyncData.Success::class.java)
|
||||||
state.eventSink(PinUnlockEvents.OnForgetPin)
|
state.eventSink(PinUnlockEvent.OnForgetPin)
|
||||||
}
|
}
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state.showSignOutPrompt).isTrue()
|
assertThat(state.showSignOutPrompt).isTrue()
|
||||||
assertThat(state.isSignOutPromptCancellable).isTrue()
|
assertThat(state.isSignOutPromptCancellable).isTrue()
|
||||||
state.eventSink(PinUnlockEvents.ClearSignOutPrompt)
|
state.eventSink(PinUnlockEvent.ClearSignOutPrompt)
|
||||||
}
|
}
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state.showSignOutPrompt).isFalse()
|
assertThat(state.showSignOutPrompt).isFalse()
|
||||||
state.eventSink(PinUnlockEvents.OnForgetPin)
|
state.eventSink(PinUnlockEvent.OnForgetPin)
|
||||||
}
|
}
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state.showSignOutPrompt).isTrue()
|
assertThat(state.showSignOutPrompt).isTrue()
|
||||||
state.eventSink(PinUnlockEvents.SignOut)
|
state.eventSink(PinUnlockEvent.SignOut)
|
||||||
}
|
}
|
||||||
skipItems(2)
|
skipItems(2)
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
|
|||||||
Reference in New Issue
Block a user