Skip to content

Commit 005e5cc

Browse files
authored
Merge pull request #1624 from vector-im/feature/fga/pin_auth_ui
PIN : unlock screen ui
2 parents a6b4b71 + 20eed4f commit 005e5cc

File tree

61 files changed

+1210
-461
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1210
-461
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.element.android.appconfig
18+
19+
object LockScreenConfig {
20+
21+
/**
22+
* Whether the PIN is mandatory or not.
23+
*/
24+
const val IS_PIN_MANDATORY: Boolean = false
25+
26+
/**
27+
* Some PINs are blacklisted.
28+
*/
29+
val PIN_BLACKLIST = setOf("0000", "1234")
30+
31+
/**
32+
* The size of the PIN.
33+
*/
34+
const val PIN_SIZE = 4
35+
}

build.gradle.kts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,6 @@ koverMerged {
250250
excludes += "io.element.android.appnav.loggedin.LoggedInPresenter$*"
251251
// Some options can't be tested at the moment
252252
excludes += "io.element.android.features.preferences.impl.developer.DeveloperSettingsPresenter$*"
253-
// Temporary until we have actually something to test.
254-
excludes += "io.element.android.features.lockscreen.impl.auth.PinAuthenticationPresenter"
255-
excludes += "io.element.android.features.lockscreen.impl.auth.PinAuthenticationPresenter$*"
256253
}
257254
bound {
258255
minValue = 85

features/lockscreen/impl/build.gradle.kts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,19 @@ anvil {
3030
}
3131

3232
dependencies {
33+
ksp(libs.showkase.processor)
3334
implementation(projects.anvilannotations)
3435
anvil(projects.anvilcodegen)
3536
api(projects.features.lockscreen.api)
37+
implementation(projects.appconfig)
3638
implementation(projects.libraries.core)
3739
implementation(projects.libraries.architecture)
3840
implementation(projects.libraries.matrix.api)
3941
implementation(projects.libraries.matrixui)
4042
implementation(projects.libraries.designsystem)
4143
implementation(projects.libraries.featureflag.api)
4244
implementation(projects.libraries.cryptography.api)
45+
implementation(projects.libraries.uiStrings)
4346

4447
testImplementation(libs.test.junit)
4548
testImplementation(libs.coroutines.test)
@@ -50,6 +53,5 @@ dependencies {
5053
testImplementation(projects.tests.testutils)
5154
testImplementation(projects.libraries.cryptography.test)
5255
testImplementation(projects.libraries.cryptography.impl)
53-
54-
ksp(libs.showkase.processor)
56+
testImplementation(projects.libraries.featureflag.test)
5557
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ import com.bumble.appyx.navmodel.backstack.BackStack
2727
import dagger.assisted.Assisted
2828
import dagger.assisted.AssistedInject
2929
import io.element.android.anvilannotations.ContributesNode
30-
import io.element.android.features.lockscreen.impl.auth.PinAuthenticationNode
31-
import io.element.android.features.lockscreen.impl.create.CreatePinNode
30+
import io.element.android.features.lockscreen.impl.setup.SetupPinNode
31+
import io.element.android.features.lockscreen.impl.unlock.PinUnlockNode
3232
import io.element.android.libraries.architecture.BackstackNode
3333
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
3434
import io.element.android.libraries.architecture.createNode
@@ -41,7 +41,7 @@ class LockScreenFlowNode @AssistedInject constructor(
4141
@Assisted plugins: List<Plugin>,
4242
) : BackstackNode<LockScreenFlowNode.NavTarget>(
4343
backstack = BackStack(
44-
initialElement = NavTarget.Auth,
44+
initialElement = NavTarget.Unlock,
4545
savedStateMap = buildContext.savedStateMap,
4646
),
4747
buildContext = buildContext,
@@ -50,19 +50,19 @@ class LockScreenFlowNode @AssistedInject constructor(
5050

5151
sealed interface NavTarget : Parcelable {
5252
@Parcelize
53-
data object Auth : NavTarget
53+
data object Unlock : NavTarget
5454

5555
@Parcelize
56-
data object Create : NavTarget
56+
data object Setup : NavTarget
5757
}
5858

5959
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
6060
return when (navTarget) {
61-
NavTarget.Auth -> {
62-
createNode<PinAuthenticationNode>(buildContext)
61+
NavTarget.Unlock -> {
62+
createNode<PinUnlockNode>(buildContext)
6363
}
64-
NavTarget.Create -> {
65-
createNode<CreatePinNode>(buildContext)
64+
NavTarget.Setup -> {
65+
createNode<SetupPinNode>(buildContext)
6666
}
6767
}
6868
}

features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationPresenter.kt

Lines changed: 0 additions & 43 deletions
This file was deleted.

features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationStateProvider.kt

Lines changed: 0 additions & 30 deletions
This file was deleted.

features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/auth/PinAuthenticationView.kt

Lines changed: 0 additions & 84 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright (c) 2023 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.element.android.features.lockscreen.impl.components
18+
19+
import androidx.compose.foundation.background
20+
import androidx.compose.foundation.border
21+
import androidx.compose.foundation.layout.Arrangement
22+
import androidx.compose.foundation.layout.Box
23+
import androidx.compose.foundation.layout.Row
24+
import androidx.compose.foundation.layout.size
25+
import androidx.compose.foundation.shape.RoundedCornerShape
26+
import androidx.compose.foundation.text.BasicTextField
27+
import androidx.compose.foundation.text.KeyboardOptions
28+
import androidx.compose.material3.Text
29+
import androidx.compose.runtime.Composable
30+
import androidx.compose.ui.Alignment
31+
import androidx.compose.ui.Modifier
32+
import androidx.compose.ui.text.input.KeyboardType
33+
import androidx.compose.ui.text.input.TextFieldValue
34+
import androidx.compose.ui.unit.dp
35+
import io.element.android.features.lockscreen.impl.pin.model.PinDigit
36+
import io.element.android.features.lockscreen.impl.pin.model.PinEntry
37+
import io.element.android.libraries.designsystem.preview.ElementPreview
38+
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
39+
import io.element.android.libraries.designsystem.theme.pinDigitBg
40+
import io.element.android.libraries.theme.ElementTheme
41+
42+
@Composable
43+
fun PinEntryTextField(
44+
pinEntry: PinEntry,
45+
onValueChange: (String) -> Unit,
46+
modifier: Modifier = Modifier,
47+
) {
48+
BasicTextField(
49+
modifier = modifier,
50+
value = TextFieldValue(pinEntry.toText()),
51+
onValueChange = {
52+
onValueChange(it.text)
53+
},
54+
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
55+
decorationBox = {
56+
PinEntryRow(pinEntry = pinEntry)
57+
}
58+
)
59+
}
60+
61+
@Composable
62+
private fun PinEntryRow(
63+
pinEntry: PinEntry,
64+
modifier: Modifier = Modifier,
65+
) {
66+
Row(
67+
modifier = modifier,
68+
horizontalArrangement = Arrangement.spacedBy(8.dp, alignment = Alignment.CenterHorizontally),
69+
verticalAlignment = Alignment.CenterVertically,
70+
) {
71+
for (digit in pinEntry.digits) {
72+
PinDigitView(digit = digit)
73+
}
74+
}
75+
}
76+
77+
@Composable
78+
private fun PinDigitView(
79+
digit: PinDigit,
80+
modifier: Modifier = Modifier,
81+
) {
82+
val shape = RoundedCornerShape(8.dp)
83+
val appearanceModifier = when (digit) {
84+
PinDigit.Empty -> {
85+
Modifier.border(1.dp, ElementTheme.colors.iconPrimary, shape)
86+
}
87+
is PinDigit.Filled -> {
88+
Modifier.background(ElementTheme.colors.pinDigitBg, shape)
89+
}
90+
}
91+
Box(
92+
modifier = modifier
93+
.size(48.dp)
94+
.then(appearanceModifier),
95+
contentAlignment = Alignment.Center,
96+
97+
) {
98+
if (digit is PinDigit.Filled) {
99+
Text(
100+
text = digit.toText(),
101+
style = ElementTheme.typography.fontHeadingMdBold
102+
)
103+
}
104+
105+
}
106+
}
107+
108+
@PreviewsDayNight
109+
@Composable
110+
internal fun PinEntryTextFieldPreview() {
111+
ElementPreview {
112+
PinEntryTextField(
113+
pinEntry = PinEntry.createEmpty(4).fillWith("12"),
114+
onValueChange = {},
115+
)
116+
}
117+
}

0 commit comments

Comments
 (0)