Skip to content

Commit 14b5326

Browse files
committed
feat: Result screen in PIN flow
1 parent bebae48 commit 14b5326

File tree

3 files changed

+179
-6
lines changed

3 files changed

+179
-6
lines changed

app/src/main/java/to/bitkit/ui/settings/pin/AskForBiometricsScreen.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package to.bitkit.ui.settings.pin
22

33
import android.content.Intent
44
import android.provider.Settings
5+
import androidx.activity.compose.BackHandler
56
import androidx.compose.foundation.Image
67
import androidx.compose.foundation.layout.Arrangement
78
import androidx.compose.foundation.layout.Column
@@ -46,21 +47,24 @@ import to.bitkit.ui.utils.rememberBiometricAuthSupported
4647

4748
@Composable
4849
fun AskForBiometricsScreen(
49-
onContinue: () -> Unit,
50+
onContinue: (isBioOn: Boolean) -> Unit,
5051
onSkip: () -> Unit,
52+
onBack: () -> Unit,
5153
) {
5254
val app = appViewModel ?: return
5355
val isBiometrySupported = rememberBiometricAuthSupported()
5456
var showBiometricPrompt by remember { mutableStateOf(false) }
5557

58+
BackHandler { onBack() }
59+
5660
AskForBiometricsContent(
5761
isBiometrySupported = isBiometrySupported,
5862
onSkip = onSkip,
5963
onContinue = { shouldEnableBiometrics ->
6064
if (shouldEnableBiometrics) {
6165
showBiometricPrompt = true
6266
} else {
63-
onContinue()
67+
onContinue(false)
6468
}
6569
},
6670
)
@@ -69,7 +73,7 @@ fun AskForBiometricsScreen(
6973
BiometricPrompt(
7074
onSuccess = {
7175
app.setIsBiometricEnabled(true)
72-
onContinue()
76+
onContinue(true)
7377
},
7478
onError = {
7579
showBiometricPrompt = false
@@ -139,7 +143,6 @@ private fun AskForBiometricsContent(
139143
stringResource(R.string.security__bio_use).replace("{biometricsName}", biometricsName)
140144
},
141145
)
142-
143146
Switch(
144147
checked = shouldEnableBiometrics,
145148
onCheckedChange = null, // handled by parent

app/src/main/java/to/bitkit/ui/settings/pin/PinNavigationSheet.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,19 @@ fun PinNavigationSheet(
6666
}
6767
composable<PinRoute.AskForBiometrics> {
6868
AskForBiometricsScreen(
69-
onContinue = { onDismiss() }, // TODO nav to result screen
70-
onSkip = onDismiss,
69+
onContinue = { isBioOn ->
70+
navController.navigate(PinRoute.Result(isBioOn))
71+
},
72+
onSkip = { navController.navigate(PinRoute.Result(isBioOn = false)) },
73+
onBack = onDismiss,
74+
)
75+
}
76+
composable<PinRoute.Result> { backStackEntry ->
77+
val route = backStackEntry.toRoute<PinRoute.Result>()
78+
PinResultScreen(
79+
isBioOn = route.isBioOn,
80+
onDismiss = onDismiss,
81+
onBack = onDismiss,
7182
)
7283
}
7384
}
@@ -90,4 +101,7 @@ sealed class PinRoute {
90101

91102
@Serializable
92103
data object AskForBiometrics : PinRoute()
104+
105+
@Serializable
106+
data class Result(val isBioOn: Boolean) : PinRoute()
93107
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package to.bitkit.ui.settings.pin
2+
3+
import androidx.activity.compose.BackHandler
4+
import androidx.compose.foundation.Image
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.Spacer
9+
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.height
12+
import androidx.compose.foundation.layout.navigationBarsPadding
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.layout.size
15+
import androidx.compose.material3.Switch
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.runtime.getValue
18+
import androidx.compose.runtime.mutableStateOf
19+
import androidx.compose.runtime.remember
20+
import androidx.compose.runtime.setValue
21+
import androidx.compose.ui.Alignment
22+
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.res.painterResource
24+
import androidx.compose.ui.res.stringResource
25+
import androidx.compose.ui.tooling.preview.Preview
26+
import androidx.compose.ui.unit.dp
27+
import to.bitkit.R
28+
import to.bitkit.ui.appViewModel
29+
import to.bitkit.ui.components.BodyM
30+
import to.bitkit.ui.components.BodyMSB
31+
import to.bitkit.ui.components.PrimaryButton
32+
import to.bitkit.ui.scaffold.SheetTopBar
33+
import to.bitkit.ui.shared.util.clickableAlpha
34+
import to.bitkit.ui.shared.util.gradientBackground
35+
import to.bitkit.ui.theme.AppSwitchDefaults
36+
import to.bitkit.ui.theme.AppThemeSurface
37+
import to.bitkit.ui.theme.Colors
38+
39+
@Composable
40+
fun PinResultScreen(
41+
isBioOn: Boolean,
42+
onDismiss: () -> Unit,
43+
onBack: () -> Unit,
44+
) {
45+
val app = appViewModel ?: return
46+
var pinForPayments by remember { mutableStateOf(false) }
47+
48+
BackHandler { onBack() }
49+
50+
PinResultContent(
51+
bio = isBioOn,
52+
pinForPayments = pinForPayments,
53+
onTogglePinForPayments = {
54+
pinForPayments = !pinForPayments
55+
// TODO: set pin for payments in settings store, etc.
56+
app.toast(Exception("Pin for payments is not yet implemented"))
57+
},
58+
onContinueClick = onDismiss,
59+
)
60+
}
61+
62+
@Composable
63+
private fun PinResultContent(
64+
bio: Boolean,
65+
pinForPayments: Boolean,
66+
onTogglePinForPayments: () -> Unit,
67+
onContinueClick: () -> Unit,
68+
) {
69+
Column(
70+
modifier = Modifier
71+
.fillMaxSize()
72+
.gradientBackground()
73+
.padding(horizontal = 16.dp)
74+
.navigationBarsPadding()
75+
) {
76+
SheetTopBar(stringResource(R.string.security__success_title))
77+
78+
Column(
79+
horizontalAlignment = Alignment.CenterHorizontally,
80+
modifier = Modifier
81+
.padding(horizontal = 16.dp)
82+
.weight(1f)
83+
) {
84+
BodyM(
85+
text = if (bio) {
86+
stringResource(R.string.security__success_bio)
87+
.replace("{biometricsName}", stringResource(R.string.security__bio))
88+
} else {
89+
stringResource(R.string.security__success_no_bio)
90+
},
91+
color = Colors.White64,
92+
)
93+
94+
Spacer(modifier = Modifier.weight(1f))
95+
96+
Image(
97+
painter = painterResource(R.drawable.check),
98+
contentDescription = null,
99+
modifier = Modifier
100+
.size(256.dp)
101+
)
102+
103+
Spacer(modifier = Modifier.weight(1f))
104+
105+
Row(
106+
horizontalArrangement = Arrangement.SpaceBetween,
107+
verticalAlignment = Alignment.CenterVertically,
108+
modifier = Modifier
109+
.fillMaxWidth()
110+
.clickableAlpha { onTogglePinForPayments() }
111+
) {
112+
BodyMSB(text = stringResource(R.string.security__success_payments))
113+
Switch(
114+
checked = pinForPayments,
115+
onCheckedChange = null, // handled by parent
116+
colors = AppSwitchDefaults.colors,
117+
)
118+
}
119+
120+
Spacer(modifier = Modifier.height(32.dp))
121+
122+
PrimaryButton(
123+
text = stringResource(R.string.common__ok),
124+
onClick = onContinueClick,
125+
)
126+
}
127+
128+
Spacer(modifier = Modifier.height(16.dp))
129+
}
130+
}
131+
132+
@Preview(showBackground = true)
133+
@Composable
134+
private fun Preview() {
135+
AppThemeSurface {
136+
PinResultContent(
137+
bio = true,
138+
pinForPayments = true,
139+
onTogglePinForPayments = {},
140+
onContinueClick = {},
141+
)
142+
}
143+
}
144+
145+
@Preview(showBackground = true)
146+
@Composable
147+
private fun PreviewNoBio() {
148+
AppThemeSurface {
149+
PinResultContent(
150+
bio = false,
151+
pinForPayments = false,
152+
onTogglePinForPayments = {},
153+
onContinueClick = {},
154+
)
155+
}
156+
}

0 commit comments

Comments
 (0)