Browse Source

Lockscreen: renaming

pull/1624/head
ganfra 11 months ago
parent
commit
5b611ed017
  1. 3
      build.gradle.kts
  2. 18
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/LockScreenFlowNode.kt
  3. 2
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/DefaultPinCodeManager.kt
  4. 2
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/PinCodeManager.kt
  5. 8
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinEvents.kt
  6. 8
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinNode.kt
  7. 40
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinPresenter.kt
  8. 12
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinState.kt
  9. 32
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinStateProvider.kt
  10. 48
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinView.kt
  11. 2
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/model/PinDigit.kt
  12. 2
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/model/PinEntry.kt
  13. 8
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/validation/CreatePinFailure.kt
  14. 8
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/validation/PinValidator.kt
  15. 6
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockEvents.kt
  16. 8
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockNode.kt
  17. 14
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenter.kt
  18. 6
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockState.kt
  19. 10
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockStateProvider.kt
  20. 25
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt
  21. 2
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/numpad/PinKeypad.kt
  22. 2
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/numpad/PinKeypadModel.kt
  23. 10
      features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/setup/CreatePinPresenterTest.kt

3
build.gradle.kts

@ -251,8 +251,7 @@ koverMerged {
// Some options can't be tested at the moment // Some options can't be tested at the moment
excludes += "io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*" excludes += "io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*"
// Temporary until we have actually something to test. // Temporary until we have actually something to test.
excludes += "io.element.android.features.lockscreen.impl.auth.PinAuthenticationPresenter" excludes += "io.element.android.features.lockscreen.impl.unlock.PinUnlockPresenter$*"
excludes += "io.element.android.features.lockscreen.impl.auth.PinAuthenticationPresenter$*"
} }
bound { bound {
minValue = 85 minValue = 85

18
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/LockScreenFlowNode.kt

@ -27,8 +27,8 @@ import com.bumble.appyx.navmodel.backstack.BackStack
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.lockscreen.impl.auth.PinAuthenticationNode import io.element.android.features.lockscreen.impl.setup.SetupPinNode
import io.element.android.features.lockscreen.impl.create.CreatePinNode import io.element.android.features.lockscreen.impl.unlock.PinUnlockNode
import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.BackstackNode
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
@ -41,7 +41,7 @@ class LockScreenFlowNode @AssistedInject constructor(
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
) : BackstackNode<LockScreenFlowNode.NavTarget>( ) : BackstackNode<LockScreenFlowNode.NavTarget>(
backstack = BackStack( backstack = BackStack(
initialElement = NavTarget.Auth, initialElement = NavTarget.Unlock,
savedStateMap = buildContext.savedStateMap, savedStateMap = buildContext.savedStateMap,
), ),
buildContext = buildContext, buildContext = buildContext,
@ -50,19 +50,19 @@ class LockScreenFlowNode @AssistedInject constructor(
sealed interface NavTarget : Parcelable { sealed interface NavTarget : Parcelable {
@Parcelize @Parcelize
data object Auth : NavTarget data object Unlock : NavTarget
@Parcelize @Parcelize
data object Create : NavTarget data object Setup : NavTarget
} }
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) { return when (navTarget) {
NavTarget.Auth -> { NavTarget.Unlock -> {
createNode<PinAuthenticationNode>(buildContext) createNode<PinUnlockNode>(buildContext)
} }
NavTarget.Create -> { NavTarget.Setup -> {
createNode<CreatePinNode>(buildContext) createNode<SetupPinNode>(buildContext)
} }
} }
} }

2
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/DefaultPinCodeManager.kt

@ -37,7 +37,7 @@ class DefaultPinCodeManager @Inject constructor(
return pinCodeStore.hasPinCode() return pinCodeStore.hasPinCode()
} }
override suspend fun createPinCode(pinCode: String) { override suspend fun SetupPinCode(pinCode: String) {
val secretKey = secretKeyProvider.getOrCreateKey(SECRET_KEY_ALIAS) val secretKey = secretKeyProvider.getOrCreateKey(SECRET_KEY_ALIAS)
val encryptedPinCode = encryptionDecryptionService.encrypt(secretKey, pinCode.toByteArray()).toBase64() val encryptedPinCode = encryptionDecryptionService.encrypt(secretKey, pinCode.toByteArray()).toBase64()
pinCodeStore.saveEncryptedPinCode(encryptedPinCode) pinCodeStore.saveEncryptedPinCode(encryptedPinCode)

2
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/PinCodeManager.kt

@ -30,7 +30,7 @@ interface PinCodeManager {
* Creates a new encrypted pin code. * Creates a new encrypted pin code.
* @param pinCode the clear pin code to create * @param pinCode the clear pin code to create
*/ */
suspend fun createPinCode(pinCode: String) suspend fun SetupPinCode(pinCode: String)
/** /**
* @return true if the pin code is correct. * @return true if the pin code is correct.

8
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinEvents.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinEvents.kt

@ -14,9 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create package io.element.android.features.lockscreen.impl.setup
sealed interface CreatePinEvents { sealed interface SetupPinEvents {
data class OnPinEntryChanged(val entryAsText: String) : CreatePinEvents data class OnPinEntryChanged(val entryAsText: String) : SetupPinEvents
data object ClearFailure : CreatePinEvents data object ClearFailure : SetupPinEvents
} }

8
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinNode.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinNode.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create package io.element.android.features.lockscreen.impl.setup
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -27,16 +27,16 @@ import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class CreatePinNode @AssistedInject constructor( class SetupPinNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: CreatePinPresenter, private val presenter: SetupPinPresenter,
) : Node(buildContext, plugins = plugins) { ) : Node(buildContext, plugins = plugins) {
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
val state = presenter.present() val state = presenter.present()
CreatePinView( SetupPinView(
state = state, state = state,
onBackClicked = { }, onBackClicked = { },
modifier = modifier modifier = modifier

40
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinPresenter.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinPresenter.kt

@ -14,29 +14,29 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create package io.element.android.features.lockscreen.impl.setup
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import io.element.android.features.lockscreen.impl.create.model.PinEntry import io.element.android.features.lockscreen.impl.setup.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure import io.element.android.features.lockscreen.impl.setup.validation.SetupPinFailure
import io.element.android.features.lockscreen.impl.create.validation.PinValidator import io.element.android.features.lockscreen.impl.setup.validation.PinValidator
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import javax.inject.Inject import javax.inject.Inject
private const val PIN_SIZE = 4 private const val PIN_SIZE = 4
class CreatePinPresenter @Inject constructor( class SetupPinPresenter @Inject constructor(
private val pinValidator: PinValidator, private val pinValidator: PinValidator,
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
) : Presenter<CreatePinState> { ) : Presenter<SetupPinState> {
@Composable @Composable
override fun present(): CreatePinState { override fun present(): SetupPinState {
var choosePinEntry by remember { var choosePinEntry by remember {
mutableStateOf(PinEntry.empty(PIN_SIZE)) mutableStateOf(PinEntry.empty(PIN_SIZE))
} }
@ -46,20 +46,20 @@ class CreatePinPresenter @Inject constructor(
var isConfirmationStep by remember { var isConfirmationStep by remember {
mutableStateOf(false) mutableStateOf(false)
} }
var createPinFailure by remember { var setupPinFailure by remember {
mutableStateOf<CreatePinFailure?>(null) mutableStateOf<SetupPinFailure?>(null)
} }
fun handleEvents(event: CreatePinEvents) { fun handleEvents(event: SetupPinEvents) {
when (event) { when (event) {
is CreatePinEvents.OnPinEntryChanged -> { is SetupPinEvents.OnPinEntryChanged -> {
if (isConfirmationStep) { if (isConfirmationStep) {
confirmPinEntry = confirmPinEntry.fillWith(event.entryAsText) confirmPinEntry = confirmPinEntry.fillWith(event.entryAsText)
if (confirmPinEntry.isPinComplete()) { if (confirmPinEntry.isPinComplete()) {
if (confirmPinEntry == choosePinEntry) { if (confirmPinEntry == choosePinEntry) {
//TODO save in db and navigate to next screen //TODO save in db and navigate to next screen
} else { } else {
createPinFailure = CreatePinFailure.PinsDontMatch setupPinFailure = SetupPinFailure.PinsDontMatch
} }
} }
} else { } else {
@ -67,35 +67,35 @@ class CreatePinPresenter @Inject constructor(
if (choosePinEntry.isPinComplete()) { if (choosePinEntry.isPinComplete()) {
when (val pinValidationResult = pinValidator.isPinValid(choosePinEntry)) { when (val pinValidationResult = pinValidator.isPinValid(choosePinEntry)) {
is PinValidator.Result.Invalid -> { is PinValidator.Result.Invalid -> {
createPinFailure = pinValidationResult.failure setupPinFailure = pinValidationResult.failure
} }
PinValidator.Result.Valid -> isConfirmationStep = true PinValidator.Result.Valid -> isConfirmationStep = true
} }
} }
} }
} }
CreatePinEvents.ClearFailure -> { SetupPinEvents.ClearFailure -> {
when (createPinFailure) { when (setupPinFailure) {
is CreatePinFailure.PinsDontMatch -> { is SetupPinFailure.PinsDontMatch -> {
choosePinEntry = PinEntry.empty(PIN_SIZE) choosePinEntry = PinEntry.empty(PIN_SIZE)
confirmPinEntry = PinEntry.empty(PIN_SIZE) confirmPinEntry = PinEntry.empty(PIN_SIZE)
} }
is CreatePinFailure.PinBlacklisted -> { is SetupPinFailure.PinBlacklisted -> {
choosePinEntry = PinEntry.empty(PIN_SIZE) choosePinEntry = PinEntry.empty(PIN_SIZE)
} }
null -> Unit null -> Unit
} }
isConfirmationStep = false isConfirmationStep = false
createPinFailure = null setupPinFailure = null
} }
} }
} }
return CreatePinState( return SetupPinState(
choosePinEntry = choosePinEntry, choosePinEntry = choosePinEntry,
confirmPinEntry = confirmPinEntry, confirmPinEntry = confirmPinEntry,
isConfirmationStep = isConfirmationStep, isConfirmationStep = isConfirmationStep,
createPinFailure = createPinFailure, SetupPinFailure = setupPinFailure,
appName = buildMeta.applicationName, appName = buildMeta.applicationName,
eventSink = ::handleEvents eventSink = ::handleEvents
) )

12
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinState.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinState.kt

@ -14,18 +14,18 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create package io.element.android.features.lockscreen.impl.setup
import io.element.android.features.lockscreen.impl.create.model.PinEntry import io.element.android.features.lockscreen.impl.setup.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure import io.element.android.features.lockscreen.impl.setup.validation.SetupPinFailure
data class CreatePinState( data class SetupPinState(
val choosePinEntry: PinEntry, val choosePinEntry: PinEntry,
val confirmPinEntry: PinEntry, val confirmPinEntry: PinEntry,
val isConfirmationStep: Boolean, val isConfirmationStep: Boolean,
val createPinFailure: CreatePinFailure?, val SetupPinFailure: SetupPinFailure?,
val appName: String, val appName: String,
val eventSink: (CreatePinEvents) -> Unit val eventSink: (SetupPinEvents) -> Unit
) { ) {
val pinSize = choosePinEntry.size val pinSize = choosePinEntry.size
val activePinEntry = if (isConfirmationStep) { val activePinEntry = if (isConfirmationStep) {

32
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinStateProvider.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinStateProvider.kt

@ -14,47 +14,47 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create package io.element.android.features.lockscreen.impl.setup
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.lockscreen.impl.create.model.PinEntry import io.element.android.features.lockscreen.impl.setup.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure import io.element.android.features.lockscreen.impl.setup.validation.SetupPinFailure
open class CreatePinStateProvider : PreviewParameterProvider<CreatePinState> { open class SetupPinStateProvider : PreviewParameterProvider<SetupPinState> {
override val values: Sequence<CreatePinState> override val values: Sequence<SetupPinState>
get() = sequenceOf( get() = sequenceOf(
aCreatePinState(), aSetupPinState(),
aCreatePinState( aSetupPinState(
choosePinEntry = PinEntry.empty(4).fillWith("12") choosePinEntry = PinEntry.empty(4).fillWith("12")
), ),
aCreatePinState( aSetupPinState(
choosePinEntry = PinEntry.empty(4).fillWith("1789"), choosePinEntry = PinEntry.empty(4).fillWith("1789"),
isConfirmationStep = true, isConfirmationStep = true,
), ),
aCreatePinState( aSetupPinState(
choosePinEntry = PinEntry.empty(4).fillWith("1789"), choosePinEntry = PinEntry.empty(4).fillWith("1789"),
confirmPinEntry = PinEntry.empty(4).fillWith("1788"), confirmPinEntry = PinEntry.empty(4).fillWith("1788"),
isConfirmationStep = true, isConfirmationStep = true,
creationFailure = CreatePinFailure.PinsDontMatch creationFailure = SetupPinFailure.PinsDontMatch
), ),
aCreatePinState( aSetupPinState(
choosePinEntry = PinEntry.empty(4).fillWith("1111"), choosePinEntry = PinEntry.empty(4).fillWith("1111"),
creationFailure = CreatePinFailure.PinBlacklisted creationFailure = SetupPinFailure.PinBlacklisted
), ),
) )
} }
fun aCreatePinState( fun aSetupPinState(
choosePinEntry: PinEntry = PinEntry.empty(4), choosePinEntry: PinEntry = PinEntry.empty(4),
confirmPinEntry: PinEntry = PinEntry.empty(4), confirmPinEntry: PinEntry = PinEntry.empty(4),
isConfirmationStep: Boolean = false, isConfirmationStep: Boolean = false,
creationFailure: CreatePinFailure? = null, creationFailure: SetupPinFailure? = null,
) = CreatePinState( ) = SetupPinState(
choosePinEntry = choosePinEntry, choosePinEntry = choosePinEntry,
confirmPinEntry = confirmPinEntry, confirmPinEntry = confirmPinEntry,
isConfirmationStep = isConfirmationStep, isConfirmationStep = isConfirmationStep,
createPinFailure = creationFailure, SetupPinFailure = creationFailure,
appName = "Element", appName = "Element",
eventSink = {} eventSink = {}
) )

48
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinView.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/SetupPinView.kt

@ -16,7 +16,7 @@
@file:OptIn(ExperimentalMaterial3Api::class) @file:OptIn(ExperimentalMaterial3Api::class)
package io.element.android.features.lockscreen.impl.create package io.element.android.features.lockscreen.impl.setup
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
@ -46,9 +46,9 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.features.lockscreen.impl.R import io.element.android.features.lockscreen.impl.R
import io.element.android.features.lockscreen.impl.create.model.PinDigit import io.element.android.features.lockscreen.impl.setup.model.PinDigit
import io.element.android.features.lockscreen.impl.create.model.PinEntry import io.element.android.features.lockscreen.impl.setup.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure import io.element.android.features.lockscreen.impl.setup.validation.SetupPinFailure
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
@ -61,8 +61,8 @@ import io.element.android.libraries.designsystem.theme.pinDigitBg
import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.ElementTheme
@Composable @Composable
fun CreatePinView( fun SetupPinView(
state: CreatePinState, state: SetupPinState,
onBackClicked: () -> Unit, onBackClicked: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
@ -86,15 +86,15 @@ fun CreatePinView(
.verticalScroll(state = scrollState) .verticalScroll(state = scrollState)
.padding(vertical = 16.dp, horizontal = 20.dp), .padding(vertical = 16.dp, horizontal = 20.dp),
) { ) {
CreatePinHeader(state.isConfirmationStep, state.appName) SetupPinHeader(state.isConfirmationStep, state.appName)
CreatePinContent(state) SetupPinContent(state)
} }
} }
) )
} }
@Composable @Composable
private fun CreatePinHeader( private fun SetupPinHeader(
isValidationStep: Boolean, isValidationStep: Boolean,
appName: String, appName: String,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -116,44 +116,44 @@ private fun CreatePinHeader(
} }
@Composable @Composable
private fun CreatePinContent( private fun SetupPinContent(
state: CreatePinState, state: SetupPinState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
PinEntryTextField( PinEntryTextField(
state.activePinEntry, state.activePinEntry,
onValueChange = { onValueChange = {
state.eventSink(CreatePinEvents.OnPinEntryChanged(it)) state.eventSink(SetupPinEvents.OnPinEntryChanged(it))
}, },
modifier = modifier modifier = modifier
.padding(top = 36.dp) .padding(top = 36.dp)
.fillMaxWidth() .fillMaxWidth()
) )
if (state.createPinFailure != null) { if (state.SetupPinFailure != null) {
ErrorDialog( ErrorDialog(
modifier = modifier, modifier = modifier,
title = state.createPinFailure.title(), title = state.SetupPinFailure.title(),
content = state.createPinFailure.content(), content = state.SetupPinFailure.content(),
onDismiss = { onDismiss = {
state.eventSink(CreatePinEvents.ClearFailure) state.eventSink(SetupPinEvents.ClearFailure)
} }
) )
} }
} }
@Composable @Composable
private fun CreatePinFailure.content(): String { private fun SetupPinFailure.content(): String {
return when (this) { return when (this) {
CreatePinFailure.PinBlacklisted -> stringResource(id = R.string.screen_app_lock_setup_pin_blacklisted_dialog_content) SetupPinFailure.PinBlacklisted -> stringResource(id = R.string.screen_app_lock_setup_pin_blacklisted_dialog_content)
CreatePinFailure.PinsDontMatch -> stringResource(id = R.string.screen_app_lock_setup_pin_mismatch_dialog_content) SetupPinFailure.PinsDontMatch -> stringResource(id = R.string.screen_app_lock_setup_pin_mismatch_dialog_content)
} }
} }
@Composable @Composable
private fun CreatePinFailure.title(): String { private fun SetupPinFailure.title(): String {
return when (this) { return when (this) {
CreatePinFailure.PinBlacklisted -> stringResource(id = R.string.screen_app_lock_setup_pin_blacklisted_dialog_title) SetupPinFailure.PinBlacklisted -> stringResource(id = R.string.screen_app_lock_setup_pin_blacklisted_dialog_title)
CreatePinFailure.PinsDontMatch -> stringResource(id = R.string.screen_app_lock_setup_pin_mismatch_dialog_title) SetupPinFailure.PinsDontMatch -> stringResource(id = R.string.screen_app_lock_setup_pin_mismatch_dialog_title)
} }
} }
@ -225,9 +225,9 @@ private fun PinDigitView(
@Composable @Composable
@PreviewsDayNight @PreviewsDayNight
internal fun CreatePinViewPreview(@PreviewParameter(CreatePinStateProvider::class) state: CreatePinState) { internal fun SetupPinViewPreview(@PreviewParameter(SetupPinStateProvider::class) state: SetupPinState) {
ElementPreview { ElementPreview {
CreatePinView( SetupPinView(
state = state, state = state,
onBackClicked = {}, onBackClicked = {},
) )

2
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/model/PinDigit.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/model/PinDigit.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create.model package io.element.android.features.lockscreen.impl.setup.model
sealed interface PinDigit { sealed interface PinDigit {
data object Empty : PinDigit data object Empty : PinDigit

2
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/model/PinEntry.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/model/PinEntry.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create.model package io.element.android.features.lockscreen.impl.setup.model
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentList

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

@ -14,9 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create.validation package io.element.android.features.lockscreen.impl.setup.validation
sealed interface CreatePinFailure { sealed interface SetupPinFailure {
data object PinBlacklisted : CreatePinFailure data object PinBlacklisted : SetupPinFailure
data object PinsDontMatch : CreatePinFailure data object PinsDontMatch : SetupPinFailure
} }

8
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/create/validation/PinValidator.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/setup/validation/PinValidator.kt

@ -14,10 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create.validation package io.element.android.features.lockscreen.impl.setup.validation
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import io.element.android.features.lockscreen.impl.create.model.PinEntry import io.element.android.features.lockscreen.impl.setup.model.PinEntry
import javax.inject.Inject import javax.inject.Inject
class PinValidator @Inject constructor() { class PinValidator @Inject constructor() {
@ -29,14 +29,14 @@ class PinValidator @Inject constructor() {
sealed interface Result { sealed interface Result {
data object Valid : Result data object Valid : Result
data class Invalid(val failure: CreatePinFailure) : Result data class Invalid(val failure: SetupPinFailure) : Result
} }
fun isPinValid(pinEntry: PinEntry): Result { fun isPinValid(pinEntry: PinEntry): Result {
val pinAsText = pinEntry.toText() val pinAsText = pinEntry.toText()
val isBlacklisted = BLACKLIST.any { it == pinAsText } val isBlacklisted = BLACKLIST.any { it == pinAsText }
return if (isBlacklisted) { return if (isBlacklisted) {
Result.Invalid(CreatePinFailure.PinBlacklisted) Result.Invalid(SetupPinFailure.PinBlacklisted)
} else { } else {
Result.Valid Result.Valid
} }

6
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationEvents.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockEvents.kt

@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth package io.element.android.features.lockscreen.impl.unlock
sealed interface PinAuthenticationEvents { sealed interface PinUnlockEvents {
data object Unlock : PinAuthenticationEvents data object Unlock : PinUnlockEvents
} }

8
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationNode.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockNode.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth package io.element.android.features.lockscreen.impl.unlock
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -27,16 +27,16 @@ import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
@ContributesNode(AppScope::class) @ContributesNode(AppScope::class)
class PinAuthenticationNode @AssistedInject constructor( class PinUnlockNode @AssistedInject constructor(
@Assisted buildContext: BuildContext, @Assisted buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val presenter: PinAuthenticationPresenter, private val presenter: PinUnlockPresenter,
) : Node(buildContext, plugins = plugins) { ) : Node(buildContext, plugins = plugins) {
@Composable @Composable
override fun View(modifier: Modifier) { override fun View(modifier: Modifier) {
val state = presenter.present() val state = presenter.present()
PinAuthenticationView( PinUnlockView(
state = state, state = state,
modifier = modifier modifier = modifier
) )

14
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationPresenter.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenter.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth package io.element.android.features.lockscreen.impl.unlock
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import io.element.android.features.lockscreen.api.LockScreenStateService import io.element.android.features.lockscreen.api.LockScreenStateService
@ -23,20 +23,20 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class PinAuthenticationPresenter @Inject constructor( class PinUnlockPresenter @Inject constructor(
private val pinStateService: LockScreenStateService, private val pinStateService: LockScreenStateService,
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
) : Presenter<PinAuthenticationState> { ) : Presenter<PinUnlockState> {
@Composable @Composable
override fun present(): PinAuthenticationState { override fun present(): PinUnlockState {
fun handleEvents(event: PinAuthenticationEvents) { fun handleEvents(event: PinUnlockEvents) {
when (event) { when (event) {
PinAuthenticationEvents.Unlock -> coroutineScope.launch { pinStateService.unlock() } PinUnlockEvents.Unlock -> coroutineScope.launch { pinStateService.unlock() }
} }
} }
return PinAuthenticationState( return PinUnlockState(
eventSink = ::handleEvents eventSink = ::handleEvents
) )
} }

6
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationState.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockState.kt

@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth package io.element.android.features.lockscreen.impl.unlock
data class PinAuthenticationState( data class PinUnlockState(
val eventSink: (PinAuthenticationEvents) -> Unit val eventSink: (PinUnlockEvents) -> Unit
) )

10
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationStateProvider.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockStateProvider.kt

@ -14,17 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth package io.element.android.features.lockscreen.impl.unlock
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
open class PinAuthenticationStateProvider : PreviewParameterProvider<PinAuthenticationState> { open class PinUnlockStateProvider : PreviewParameterProvider<PinUnlockState> {
override val values: Sequence<PinAuthenticationState> override val values: Sequence<PinUnlockState>
get() = sequenceOf( get() = sequenceOf(
aPinAuthenticationState(), aPinUnlockState(),
) )
} }
fun aPinAuthenticationState() = PinAuthenticationState( fun aPinUnlockState() = PinUnlockState(
eventSink = {} eventSink = {}
) )

25
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationView.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt

@ -14,23 +14,18 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth package io.element.android.features.lockscreen.impl.unlock
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Lock
@ -41,7 +36,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.features.lockscreen.impl.auth.numpad.PinKeypad import io.element.android.features.lockscreen.impl.unlock.numpad.PinKeypad
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -52,13 +47,13 @@ import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.ElementTheme
@Composable @Composable
fun PinAuthenticationView( fun PinUnlockView(
state: PinAuthenticationState, state: PinUnlockState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Surface(modifier) { Surface(modifier) {
HeaderFooterPage( HeaderFooterPage(
header = { PinAuthenticationHeader(modifier = Modifier.padding(top = 60.dp, bottom = 12.dp)) }, header = { PinUnlockHeader(modifier = Modifier.padding(top = 60.dp, bottom = 12.dp)) },
content = { content = {
Box( Box(
modifier = Modifier modifier = Modifier
@ -76,12 +71,12 @@ fun PinAuthenticationView(
} }
@Composable @Composable
private fun PinAuthenticationFooter(state: PinAuthenticationState) { private fun PinUnlockFooter(state: PinUnlockState) {
Button( Button(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
text = "Unlock", text = "Unlock",
onClick = { onClick = {
state.eventSink(PinAuthenticationEvents.Unlock) state.eventSink(PinUnlockEvents.Unlock)
} }
) )
} }
@ -116,7 +111,7 @@ private fun PinDot(
} }
@Composable @Composable
private fun PinAuthenticationHeader( private fun PinUnlockHeader(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column(modifier, horizontalAlignment = Alignment.CenterHorizontally) { Column(modifier, horizontalAlignment = Alignment.CenterHorizontally) {
@ -151,9 +146,9 @@ private fun PinAuthenticationHeader(
@Composable @Composable
@PreviewsDayNight @PreviewsDayNight
internal fun PinAuthenticationViewPreview(@PreviewParameter(PinAuthenticationStateProvider::class) state: PinAuthenticationState) { internal fun PinUnlockViewPreview(@PreviewParameter(PinUnlockStateProvider::class) state: PinUnlockState) {
ElementPreview { ElementPreview {
PinAuthenticationView( PinUnlockView(
state = state, state = state,
) )
} }

2
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/numpad/PinKeypad.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/numpad/PinKeypad.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth.numpad package io.element.android.features.lockscreen.impl.unlock.numpad
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement

2
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/numpad/PinKeypadModel.kt → features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/numpad/PinKeypadModel.kt

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.auth.numpad package io.element.android.features.lockscreen.impl.unlock.numpad
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable

10
features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/create/CreatePinPresenterTest.kt → features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/setup/CreatePinPresenterTest.kt

@ -14,16 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
package io.element.android.features.lockscreen.impl.create package io.element.android.features.lockscreen.impl.setup
import app.cash.molecule.RecompositionMode import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow import app.cash.molecule.moleculeFlow
import app.cash.turbine.test import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.features.lockscreen.impl.create.model.PinDigit import io.element.android.features.lockscreen.impl.setup.model.PinDigit
import io.element.android.features.lockscreen.impl.create.model.PinEntry import io.element.android.features.lockscreen.impl.setup.model.PinEntry
import io.element.android.features.lockscreen.impl.create.validation.CreatePinFailure import io.element.android.features.lockscreen.impl.setup.validation.CreatePinFailure
import io.element.android.features.lockscreen.impl.create.validation.PinValidator import io.element.android.features.lockscreen.impl.setup.validation.PinValidator
import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.tests.testutils.awaitLastSequentialItem import io.element.android.tests.testutils.awaitLastSequentialItem
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
Loading…
Cancel
Save