Skip to content

Commit edeb6a1

Browse files
committed
fix: clear input on backspace hold
1 parent 520c8a1 commit edeb6a1

3 files changed

Lines changed: 54 additions & 9 deletions

File tree

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

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ fun NumberPad(
7575
decimalSeparator: String = KEY_DECIMAL,
7676
errorKey: String? = null,
7777
includeNavigationBarsPadding: Boolean = false,
78+
onDeleteLongPress: (() -> Unit)? = null,
7879
) {
7980
val focusRequester = remember { FocusRequester() }
8081
LaunchedEffect(Unit) { focusRequester.requestFocus() }
@@ -152,6 +153,7 @@ fun NumberPad(
152153
item {
153154
NumberPadDeleteButton(
154155
onPress = { onPress(KEY_DELETE) },
156+
onLongPress = onDeleteLongPress,
155157
height = buttonHeight,
156158
modifier = Modifier.testTag("NRemove"),
157159
)
@@ -182,6 +184,7 @@ fun NumberPad(
182184
decimalSeparator = decimalSeparator,
183185
errorKey = uiState.errorKey,
184186
includeNavigationBarsPadding = includeNavigationBarsPadding,
187+
onDeleteLongPress = viewModel::clearInput,
185188
)
186189
}
187190

@@ -242,13 +245,15 @@ internal fun NumberPadDeleteButton(
242245
onPress: () -> Unit,
243246
height: Dp,
244247
modifier: Modifier = Modifier,
248+
onLongPress: (() -> Unit)? = null,
245249
) {
246250
NumberPadKeyIcon(
247251
icon = R.drawable.ic_backspace,
248252
contentDescription = stringResource(R.string.common__delete),
249253
onClick = onPress,
254+
onLongClick = onLongPress,
250255
height = height,
251-
modifier = modifier,
256+
modifier = modifier
252257
)
253258
}
254259

@@ -259,11 +264,13 @@ fun NumberPadKeyIcon(
259264
onClick: () -> Unit,
260265
height: Dp,
261266
modifier: Modifier = Modifier,
267+
onLongClick: (() -> Unit)? = null,
262268
) {
263269
NumberPadKey(
264270
onClick = onClick,
271+
onLongClick = onLongClick,
265272
height = height,
266-
modifier = modifier,
273+
modifier = modifier
267274
) {
268275
Icon(
269276
painter = painterResource(icon),
@@ -278,6 +285,7 @@ fun NumberPadKey(
278285
height: Dp,
279286
modifier: Modifier = Modifier,
280287
haptic: HapticFeedbackType = pressHaptic,
288+
onLongClick: (() -> Unit)? = null,
281289
content: @Composable (BoxScope.() -> Unit),
282290
) {
283291
val haptics = LocalHapticFeedback.current
@@ -287,10 +295,20 @@ fun NumberPadKey(
287295
modifier = modifier
288296
.height(height)
289297
.fillMaxWidth()
290-
.clickableAlpha(ALPHA_PRESSED, debounce = Duration.ZERO) {
291-
haptics.performHapticFeedback(haptic)
292-
onClick()
293-
},
298+
.clickableAlpha(
299+
pressedAlpha = ALPHA_PRESSED,
300+
debounce = Duration.ZERO,
301+
onLongClick = onLongClick?.let {
302+
{
303+
haptics.performHapticFeedback(haptic)
304+
it()
305+
}
306+
},
307+
onClick = {
308+
haptics.performHapticFeedback(haptic)
309+
onClick()
310+
},
311+
),
294312
)
295313
}
296314

app/src/main/java/to/bitkit/ui/screens/widgets/calculator/components/CalculatorCard.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,13 @@ private fun ColumnScope.Numpad(
309309
decimalSeparator = calculatorDecimalSeparator(),
310310
errorKey = state.errorKey,
311311
includeNavigationBarsPadding = true,
312+
onDeleteLongPress = {
313+
state.clearError()
314+
when (input) {
315+
MoneyType.BITCOIN -> onBtcChange("")
316+
MoneyType.FIAT -> onFiatChange("")
317+
}
318+
},
312319
modifier = Modifier
313320
.testTag("CalculatorNumberPad")
314321
)

app/src/main/java/to/bitkit/ui/shared/modifiers/ClickableAlpha.kt

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import androidx.compose.runtime.remember
1010
import androidx.compose.runtime.rememberCoroutineScope
1111
import androidx.compose.runtime.rememberUpdatedState
1212
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.geometry.Offset
1314
import androidx.compose.ui.graphics.graphicsLayer
1415
import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
1516
import androidx.compose.ui.input.pointer.pointerInput
@@ -29,6 +30,7 @@ import androidx.compose.ui.unit.Constraints
2930
import kotlinx.coroutines.launch
3031
import kotlin.time.Duration
3132
import kotlin.time.Duration.Companion.milliseconds
33+
import androidx.compose.ui.semantics.onLongClick as semanticsOnLongClick
3234

3335
private val CLICK_DEBOUNCE = 500.milliseconds
3436

@@ -69,41 +71,46 @@ fun Modifier.clickableAlpha(
6971
enabled: Boolean = true,
7072
ripple: Boolean = false,
7173
debounce: Duration = CLICK_DEBOUNCE,
74+
onLongClick: (() -> Unit)? = null,
7275
onClick: (() -> Unit)?,
7376
): Modifier = when {
7477
onClick == null || !enabled -> this
75-
ripple ->
78+
ripple && onLongClick == null ->
7679
this
7780
.alphaFeedback(pressedAlpha)
7881
.clickable(onClick = rememberDebouncedClick(debounce, onClick))
7982

80-
else -> this.then(ClickableAlphaElement(pressedAlpha, debounce, onClick))
83+
else -> this.then(ClickableAlphaElement(pressedAlpha, debounce, onLongClick, onClick))
8184
}
8285

8386
private data class ClickableAlphaElement(
8487
val pressedAlpha: Float,
8588
val debounce: Duration,
89+
val onLongClick: (() -> Unit)?,
8690
val onClick: () -> Unit,
8791
) : ModifierNodeElement<ClickableAlphaNode>() {
88-
override fun create(): ClickableAlphaNode = ClickableAlphaNode(pressedAlpha, debounce, onClick)
92+
override fun create(): ClickableAlphaNode = ClickableAlphaNode(pressedAlpha, debounce, onLongClick, onClick)
8993

9094
override fun update(node: ClickableAlphaNode) {
9195
node.pressedAlpha = pressedAlpha
9296
node.debounce = debounce
97+
node.onLongClick = onLongClick
9398
node.onClick = onClick
9499
}
95100

96101
override fun InspectorInfo.inspectableProperties() {
97102
name = "clickableAlpha"
98103
properties["pressedAlpha"] = pressedAlpha
99104
properties["debounce"] = debounce
105+
properties["onLongClick"] = onLongClick
100106
properties["onClick"] = onClick
101107
}
102108
}
103109

104110
private class ClickableAlphaNode(
105111
var pressedAlpha: Float,
106112
var debounce: Duration,
113+
var onLongClick: (() -> Unit)?,
107114
var onClick: () -> Unit,
108115
) : DelegatingNode(), LayoutModifierNode, SemanticsModifierNode {
109116

@@ -121,6 +128,7 @@ private class ClickableAlphaNode(
121128
coroutineScope.launch { animatable.animateTo(1f) }
122129
}
123130
},
131+
onLongPress = if (onLongClick == null) null else ::handleLongPress,
124132
onTap = {
125133
if (debouncer.tryClick(debounce, onClick)) {
126134
coroutineScope.launch {
@@ -136,6 +144,12 @@ private class ClickableAlphaNode(
136144
)
137145
}
138146

147+
@Suppress("UNUSED_PARAMETER")
148+
private fun handleLongPress(offset: Offset) {
149+
onLongClick?.invoke()
150+
coroutineScope.launch { animatable.animateTo(1f) }
151+
}
152+
139153
override fun MeasureScope.measure(measurable: Measurable, constraints: Constraints): MeasureResult {
140154
val placeable = measurable.measure(constraints)
141155

@@ -152,6 +166,12 @@ private class ClickableAlphaNode(
152166
debouncer.tryClick(debounce, onClick)
153167
true
154168
}
169+
onLongClick?.let {
170+
semanticsOnLongClick {
171+
it()
172+
true
173+
}
174+
}
155175
}
156176
}
157177

0 commit comments

Comments
 (0)