Skip to content

Commit 97ab876

Browse files
authored
Merge pull request #388 from synonymdev/refactor/replace-numberpadsimple
feat: use custom numberpad for pin entry
2 parents 07f9480 + f23ee1c commit 97ab876

File tree

18 files changed

+167
-143
lines changed

18 files changed

+167
-143
lines changed

app/src/main/java/to/bitkit/ui/ContentView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ private fun NavGraphBuilder.qrScanner(
970970
private fun NavGraphBuilder.authCheck(
971971
navController: NavHostController,
972972
) {
973-
composable<Routes.AuthCheck> {
973+
composableWithDefaultTransitions<Routes.AuthCheck> {
974974
val route = it.toRoute<Routes.AuthCheck>()
975975
AuthCheckScreen(
976976
route = route,

app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ private fun PinPad(
205205
pin = pin,
206206
modifier = Modifier.padding(vertical = 16.dp),
207207
)
208-
NumberPadSimple(
209-
modifier = Modifier.height(310.dp),
208+
NumberPad(
210209
onPress = { key ->
211210
if (key == KEY_DELETE) {
212211
if (pin.isNotEmpty()) {
@@ -216,6 +215,8 @@ private fun PinPad(
216215
pin += key
217216
}
218217
},
218+
type = NumberPadType.SIMPLE,
219+
modifier = Modifier.height(310.dp),
219220
)
220221
}
221222
}

app/src/main/java/to/bitkit/ui/components/NumberPad.kt

Lines changed: 103 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import to.bitkit.viewmodels.previewAmountInputViewModel
4242
const val KEY_DELETE = "delete"
4343
const val KEY_000 = "000"
4444
const val KEY_DECIMAL = "."
45-
private val maxKeyboardHeight = 300.dp
45+
private val defaultHeight = 300.dp
4646
private val idealButtonHeight = 75.dp
4747
private val minButtonHeight = 50.dp
4848
private const val ROWS = 4
@@ -52,34 +52,20 @@ private val pressHaptic = HapticFeedbackType.VirtualKey
5252
private val errorHaptic = HapticFeedbackType.Reject
5353

5454
/**
55-
* Numeric keyboard. Can be used together with [NumberPadTextField] for amounts.
55+
* Numeric keyboard.
5656
*/
5757
@Composable
5858
fun NumberPad(
59-
viewModel: AmountInputViewModel,
59+
onPress: (String) -> Unit,
6060
modifier: Modifier = Modifier,
61-
currencies: CurrencyState = LocalCurrencies.current,
62-
type: NumberPadType = viewModel.getNumberPadType(currencies),
63-
availableHeight: Dp? = null,
61+
type: NumberPadType = NumberPadType.SIMPLE,
62+
availableHeight: Dp = defaultHeight,
63+
errorKey: String? = null,
6464
) {
65-
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
66-
val errorKey: String? = uiState.errorKey
67-
val onPress: (String) -> Unit = { key -> viewModel.handleNumberPadInput(key, currencies) }
68-
6965
BoxWithConstraints(modifier = modifier) {
70-
val constraintsHeight = this.maxHeight
71-
val effectiveHeight = availableHeight ?: constraintsHeight
72-
val idealTotalHeight = idealButtonHeight * ROWS
73-
74-
val maxAllowedHeight = minOf(maxKeyboardHeight, effectiveHeight)
75-
7666
val buttonHeight = when {
77-
// If we have plenty of space, use ideal height
78-
maxAllowedHeight >= idealTotalHeight -> idealButtonHeight
79-
// If space is limited, calculate proportional height but ensure minimum
80-
maxAllowedHeight >= (minButtonHeight * ROWS) -> maxAllowedHeight / ROWS
81-
// If extremely limited, use absolute minimum
82-
else -> minButtonHeight
67+
constraints.hasFixedHeight -> maxHeight / ROWS
68+
else -> (availableHeight / ROWS).coerceIn(minButtonHeight, idealButtonHeight)
8369
}
8470

8571
val totalKeyboardHeight = buttonHeight * ROWS
@@ -141,6 +127,27 @@ fun NumberPad(
141127
}
142128
}
143129

130+
/**
131+
* Numeric keyboard for amount input. Can be used together with [NumberPadTextField].
132+
*/
133+
@Composable
134+
fun NumberPad(
135+
viewModel: AmountInputViewModel,
136+
modifier: Modifier = Modifier,
137+
currencies: CurrencyState = LocalCurrencies.current,
138+
type: NumberPadType = viewModel.getNumberPadType(currencies),
139+
availableHeight: Dp = defaultHeight,
140+
) {
141+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
142+
NumberPad(
143+
onPress = { key -> viewModel.handleNumberPadInput(key, currencies) },
144+
modifier = modifier,
145+
type = type,
146+
availableHeight = availableHeight,
147+
errorKey = uiState.errorKey,
148+
)
149+
}
150+
144151
enum class NumberPadType { SIMPLE, INTEGER, DECIMAL }
145152

146153
@Composable
@@ -236,7 +243,6 @@ private fun Preview() {
236243
FillHeight()
237244
NumberPad(
238245
viewModel = previewAmountInputViewModel(),
239-
modifier = Modifier.fillMaxWidth(),
240246
)
241247
}
242248
}
@@ -286,3 +292,77 @@ private fun PreviewSmall() {
286292
}
287293
}
288294
}
295+
296+
@Preview(showSystemUi = true)
297+
@Composable
298+
private fun PreviewSimple() {
299+
AppThemeSurface {
300+
ScreenColumn {
301+
FillHeight()
302+
NumberPad(
303+
onPress = {},
304+
type = NumberPadType.SIMPLE,
305+
)
306+
}
307+
}
308+
}
309+
310+
@Preview(showSystemUi = true)
311+
@Composable
312+
private fun PreviewHeight() {
313+
AppThemeSurface {
314+
ScreenColumn {
315+
FillHeight()
316+
NumberPad(
317+
onPress = {},
318+
type = NumberPadType.SIMPLE,
319+
modifier = Modifier.height(350.dp),
320+
)
321+
}
322+
}
323+
}
324+
325+
@Preview(showSystemUi = true)
326+
@Composable
327+
private fun PreviewMaxHeight() {
328+
AppThemeSurface {
329+
ScreenColumn {
330+
FillHeight()
331+
NumberPad(
332+
onPress = {},
333+
type = NumberPadType.SIMPLE,
334+
availableHeight = 350.dp,
335+
)
336+
}
337+
}
338+
}
339+
340+
@Preview(showSystemUi = true)
341+
@Composable
342+
private fun PreviewHeightXs() {
343+
AppThemeSurface {
344+
ScreenColumn {
345+
FillHeight()
346+
NumberPad(
347+
onPress = {},
348+
type = NumberPadType.SIMPLE,
349+
modifier = Modifier.height(100.dp),
350+
)
351+
}
352+
}
353+
}
354+
355+
@Preview(showSystemUi = true)
356+
@Composable
357+
private fun PreviewMaxHeightXs() {
358+
AppThemeSurface {
359+
ScreenColumn {
360+
FillHeight()
361+
NumberPad(
362+
onPress = {},
363+
type = NumberPadType.SIMPLE,
364+
availableHeight = 100.dp,
365+
)
366+
}
367+
}
368+
}

app/src/main/java/to/bitkit/ui/components/NumberPadSimple.kt

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

app/src/main/java/to/bitkit/ui/screens/transfer/external/ExternalFeeCustomScreen.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import to.bitkit.ui.components.Display
3131
import to.bitkit.ui.components.FillHeight
3232
import to.bitkit.ui.components.KEY_DELETE
3333
import to.bitkit.ui.components.LargeRow
34-
import to.bitkit.ui.components.NumberPadSimple
34+
import to.bitkit.ui.components.NumberPad
35+
import to.bitkit.ui.components.NumberPadType
3536
import to.bitkit.ui.components.PrimaryButton
3637
import to.bitkit.ui.components.VerticalSpacer
3738
import to.bitkit.ui.currencyViewModel
@@ -159,8 +160,9 @@ private fun Content(
159160

160161
FillHeight()
161162

162-
NumberPadSimple(
163+
NumberPad(
163164
onPress = onKeyPress,
165+
type = NumberPadType.SIMPLE,
164166
modifier = Modifier
165167
.height(350.dp)
166168
.testTag("FeeCustomNumberPad")

app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fun SendAmountScreen(
103103
onClickMax = { maxSats ->
104104
if (uiState.lnurl == null) {
105105
app?.toast(
106-
type = Toast.ToastType.WARNING,
106+
type = Toast.ToastType.INFO,
107107
title = context.getString(R.string.wallet__send_max_spending__title),
108108
description = context.getString(R.string.wallet__send_max_spending__description)
109109
)

app/src/main/java/to/bitkit/ui/screens/wallets/send/SendConfirmScreen.kt

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import androidx.compose.runtime.getValue
2525
import androidx.compose.runtime.mutableStateOf
2626
import androidx.compose.runtime.remember
2727
import androidx.compose.runtime.rememberCoroutineScope
28+
import androidx.compose.runtime.rememberUpdatedState
2829
import androidx.compose.runtime.saveable.rememberSaveable
2930
import androidx.compose.runtime.setValue
3031
import androidx.compose.ui.Alignment
@@ -95,9 +96,9 @@ fun SendConfirmScreen(
9596
onNavigateToPin: () -> Unit,
9697
) {
9798
val scope = rememberCoroutineScope()
98-
// TODO handle loading via uiState?
9999
var isLoading by rememberSaveable { mutableStateOf(false) }
100100
var showBiometrics by remember { mutableStateOf(false) }
101+
val currentOnEvent by rememberUpdatedState(onEvent)
101102

102103
val settings = settingsViewModel ?: return
103104
val isPinEnabled by settings.isPinEnabled.collectAsStateWithLifecycle()
@@ -115,18 +116,18 @@ fun SendConfirmScreen(
115116
}
116117
}
117118

118-
// Handle pay confirm with auth check if needed
119+
// Confirm with pin or bio if required
119120
LaunchedEffect(uiState.shouldConfirmPay) {
120-
if (uiState.shouldConfirmPay) {
121-
if (isPinEnabled && pinForPayments) {
122-
if (isBiometricEnabled && isBiometrySupported) {
123-
showBiometrics = true
124-
} else {
125-
onNavigateToPin()
126-
}
121+
if (!uiState.shouldConfirmPay) return@LaunchedEffect
122+
if (isPinEnabled && pinForPayments) {
123+
currentOnEvent(SendEvent.ClearPayConfirmation)
124+
if (isBiometricEnabled && isBiometrySupported) {
125+
showBiometrics = true
127126
} else {
128-
onEvent(SendEvent.PayConfirmed)
127+
onNavigateToPin()
129128
}
129+
} else {
130+
currentOnEvent(SendEvent.PayConfirmed)
130131
}
131132
}
132133

app/src/main/java/to/bitkit/ui/screens/wallets/send/SendFeeCustomScreen.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import to.bitkit.ui.components.BodyM
2323
import to.bitkit.ui.components.BottomSheetPreview
2424
import to.bitkit.ui.components.FillHeight
2525
import to.bitkit.ui.components.LargeRow
26-
import to.bitkit.ui.components.NumberPadSimple
26+
import to.bitkit.ui.components.NumberPad
27+
import to.bitkit.ui.components.NumberPadType
2728
import to.bitkit.ui.components.PrimaryButton
2829
import to.bitkit.ui.components.VerticalSpacer
2930
import to.bitkit.ui.components.settings.SectionHeader
@@ -95,8 +96,9 @@ private fun Content(
9596

9697
FillHeight()
9798

98-
NumberPadSimple(
99+
NumberPad(
99100
onPress = onKeyPress,
101+
type = NumberPadType.SIMPLE,
100102
modifier = Modifier.height(350.dp)
101103
)
102104
PrimaryButton(

app/src/main/java/to/bitkit/ui/screens/wallets/send/SendPinCheckScreen.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import to.bitkit.ui.components.BodyM
2828
import to.bitkit.ui.components.BodyS
2929
import to.bitkit.ui.components.BottomSheetPreview
3030
import to.bitkit.ui.components.KEY_DELETE
31-
import to.bitkit.ui.components.NumberPadSimple
31+
import to.bitkit.ui.components.NumberPad
32+
import to.bitkit.ui.components.NumberPadType
3233
import to.bitkit.ui.components.PinDots
3334
import to.bitkit.ui.scaffold.SheetTopBar
3435
import to.bitkit.ui.shared.modifiers.sheetHeight
@@ -139,8 +140,9 @@ private fun PinCheckContent(
139140

140141
Spacer(modifier = Modifier.weight(1f))
141142

142-
NumberPadSimple(
143+
NumberPad(
143144
onPress = onKeyPress,
145+
type = NumberPadType.SIMPLE,
144146
modifier = Modifier
145147
.height(350.dp)
146148
.background(Colors.Black)

0 commit comments

Comments
 (0)