Browse Source

Create pin : render failures

pull/1608/head
ganfra 11 months ago
parent
commit
caf6d6b674
  1. 2
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinEvents.kt
  2. 22
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinPresenter.kt
  3. 4
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinState.kt
  4. 17
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinStateProvider.kt
  5. 41
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinView.kt
  6. 6
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/validation/CreatePinFailure.kt
  7. 4
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/validation/PinValidator.kt

2
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinEvents.kt

@ -18,5 +18,5 @@ package io.element.android.features.lockscreen.impl.create @@ -18,5 +18,5 @@ package io.element.android.features.lockscreen.impl.create
sealed interface CreatePinEvents {
data class OnPinEntryChanged(val entryAsText: String) : CreatePinEvents
data object OnClearValidationFailure : CreatePinEvents
data object ClearFailure : CreatePinEvents
}

22
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinPresenter.kt

@ -22,7 +22,7 @@ import androidx.compose.runtime.mutableStateOf @@ -22,7 +22,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import io.element.android.features.lockscreen.impl.create.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.PinCreationFailure
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure
import io.element.android.features.lockscreen.impl.create.validation.PinValidator
import io.element.android.libraries.architecture.Presenter
import javax.inject.Inject
@ -44,8 +44,8 @@ class CreatePinPresenter @Inject constructor( @@ -44,8 +44,8 @@ class CreatePinPresenter @Inject constructor(
var isConfirmationStep by remember {
mutableStateOf(false)
}
var creationFailure by remember {
mutableStateOf<PinCreationFailure?>(null)
var createPinFailure by remember {
mutableStateOf<CreatePinFailure?>(null)
}
fun handleEvents(event: CreatePinEvents) {
@ -57,7 +57,7 @@ class CreatePinPresenter @Inject constructor( @@ -57,7 +57,7 @@ class CreatePinPresenter @Inject constructor(
if (confirmPinEntry == choosePinEntry) {
//TODO save in db and navigate to next screen
} else {
creationFailure = PinCreationFailure.ConfirmationPinNotMatching
createPinFailure = CreatePinFailure.ConfirmationPinNotMatching
}
}
} else {
@ -65,26 +65,26 @@ class CreatePinPresenter @Inject constructor( @@ -65,26 +65,26 @@ class CreatePinPresenter @Inject constructor(
if (choosePinEntry.isPinComplete()) {
when (val pinValidationResult = pinValidator.isPinValid(choosePinEntry)) {
is PinValidator.Result.Invalid -> {
creationFailure = pinValidationResult.failure
createPinFailure = pinValidationResult.failure
}
PinValidator.Result.Valid -> isConfirmationStep = true
}
}
}
}
CreatePinEvents.OnClearValidationFailure -> {
when (creationFailure) {
is PinCreationFailure.ConfirmationPinNotMatching -> {
CreatePinEvents.ClearFailure -> {
when (createPinFailure) {
is CreatePinFailure.ConfirmationPinNotMatching -> {
choosePinEntry = PinEntry.empty(PIN_SIZE)
confirmPinEntry = PinEntry.empty(PIN_SIZE)
}
is PinCreationFailure.ChosenPinBlacklisted -> {
is CreatePinFailure.ChosenPinBlacklisted -> {
choosePinEntry = PinEntry.empty(PIN_SIZE)
}
null -> Unit
}
isConfirmationStep = false
creationFailure = null
createPinFailure = null
}
}
}
@ -93,7 +93,7 @@ class CreatePinPresenter @Inject constructor( @@ -93,7 +93,7 @@ class CreatePinPresenter @Inject constructor(
choosePinEntry = choosePinEntry,
confirmPinEntry = confirmPinEntry,
isConfirmationStep = isConfirmationStep,
creationFailure = creationFailure,
createPinFailure = createPinFailure,
eventSink = ::handleEvents
)
}

4
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinState.kt

@ -17,13 +17,13 @@ @@ -17,13 +17,13 @@
package io.element.android.features.lockscreen.impl.create
import io.element.android.features.lockscreen.impl.create.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.PinCreationFailure
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure
data class CreatePinState(
val choosePinEntry: PinEntry,
val confirmPinEntry: PinEntry,
val isConfirmationStep: Boolean,
val creationFailure: PinCreationFailure?,
val createPinFailure: CreatePinFailure?,
val eventSink: (CreatePinEvents) -> Unit
) {
val activePinEntry = if (isConfirmationStep) {

17
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinStateProvider.kt

@ -18,7 +18,7 @@ package io.element.android.features.lockscreen.impl.create @@ -18,7 +18,7 @@ package io.element.android.features.lockscreen.impl.create
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.lockscreen.impl.create.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.PinCreationFailure
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure
open class CreatePinStateProvider : PreviewParameterProvider<CreatePinState> {
override val values: Sequence<CreatePinState>
@ -31,6 +31,17 @@ open class CreatePinStateProvider : PreviewParameterProvider<CreatePinState> { @@ -31,6 +31,17 @@ open class CreatePinStateProvider : PreviewParameterProvider<CreatePinState> {
choosePinEntry = PinEntry.empty(4).fillWith("1789"),
isConfirmationStep = true,
),
aCreatePinState(
choosePinEntry = PinEntry.empty(4).fillWith("1789"),
confirmPinEntry = PinEntry.empty(4).fillWith("1788"),
isConfirmationStep = true,
creationFailure = CreatePinFailure.ConfirmationPinNotMatching
),
aCreatePinState(
choosePinEntry = PinEntry.empty(4).fillWith("1111"),
creationFailure = CreatePinFailure.ChosenPinBlacklisted
),
)
}
@ -38,12 +49,12 @@ fun aCreatePinState( @@ -38,12 +49,12 @@ fun aCreatePinState(
choosePinEntry: PinEntry = PinEntry.empty(4),
confirmPinEntry: PinEntry = PinEntry.empty(4),
isConfirmationStep: Boolean = false,
creationFailure: PinCreationFailure? = null,
creationFailure: CreatePinFailure? = null,
) = CreatePinState(
choosePinEntry = choosePinEntry,
confirmPinEntry = confirmPinEntry,
isConfirmationStep = isConfirmationStep,
creationFailure = creationFailure,
createPinFailure = creationFailure,
eventSink = {}
)

41
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinView.kt

@ -42,12 +42,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameter @@ -42,12 +42,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.features.lockscreen.impl.create.model.PinDigit
import io.element.android.features.lockscreen.impl.create.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TopAppBar
@ -76,7 +77,6 @@ fun CreatePinView( @@ -76,7 +77,6 @@ fun CreatePinView(
.padding(padding)
.consumeWindowInsets(padding),
header = { CreatePinHeader(state.isConfirmationStep) },
footer = { CreatePinFooter() },
content = { CreatePinContent(state) }
)
}
@ -96,17 +96,6 @@ private fun CreatePinHeader( @@ -96,17 +96,6 @@ private fun CreatePinHeader(
)
}
@Composable
private fun CreatePinFooter() {
Button(
modifier = Modifier.fillMaxWidth(),
text = "Continue",
onClick = {
}
)
}
@Composable
private fun CreatePinContent(
state: CreatePinState,
@ -121,6 +110,32 @@ private fun CreatePinContent( @@ -121,6 +110,32 @@ private fun CreatePinContent(
.padding(top = 36.dp)
.fillMaxWidth()
)
if (state.createPinFailure != null) {
ErrorDialog(
modifier = modifier,
title = state.createPinFailure.title(),
content = state.createPinFailure.content(),
onDismiss = {
state.eventSink(CreatePinEvents.ClearFailure)
}
)
}
}
@Composable
private fun CreatePinFailure.content(): String {
return when (this) {
CreatePinFailure.ChosenPinBlacklisted -> "You cannot choose this as your PIN code for security reasons"
CreatePinFailure.ConfirmationPinNotMatching -> "Please enter the same PIN twice"
}
}
@Composable
private fun CreatePinFailure.title(): String {
return when (this) {
CreatePinFailure.ChosenPinBlacklisted -> "Choose a different PIN"
CreatePinFailure.ConfirmationPinNotMatching -> "PINs don't match"
}
}
@Composable

6
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/validation/PinCreationFailure.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/validation/CreatePinFailure.kt

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
package io.element.android.features.lockscreen.impl.create.validation
sealed interface PinCreationFailure {
data object ChosenPinBlacklisted : PinCreationFailure
data object ConfirmationPinNotMatching : PinCreationFailure
sealed interface CreatePinFailure {
data object ChosenPinBlacklisted : CreatePinFailure
data object ConfirmationPinNotMatching : CreatePinFailure
}

4
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/validation/PinValidator.kt

@ -25,14 +25,14 @@ class PinValidator @Inject constructor() { @@ -25,14 +25,14 @@ class PinValidator @Inject constructor() {
sealed interface Result {
data object Valid : Result
data class Invalid(val failure: PinCreationFailure) : Result
data class Invalid(val failure: CreatePinFailure) : Result
}
fun isPinValid(pinEntry: PinEntry): Result {
val pinAsText = pinEntry.toText()
val isBlacklisted = BLACKLIST.any { it == pinAsText }
return if (isBlacklisted) {
Result.Invalid(PinCreationFailure.ChosenPinBlacklisted)
Result.Invalid(CreatePinFailure.ChosenPinBlacklisted)
} else {
Result.Valid
}

Loading…
Cancel
Save