diff --git a/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt b/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt index f76a38725..16effaf6e 100644 --- a/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/components/KeyboardTest.kt @@ -25,7 +25,7 @@ class KeyboardTest { @Test fun keyboard_displaysAllButtons() { composeTestRule.setContent { - Keyboard(onClick = {}) + Keyboard(onClick = {}, onClickBackspace = {}) } composeTestRule.onNodeWithTag("KeyboardButton_1").assertIsDisplayed() @@ -39,13 +39,13 @@ class KeyboardTest { composeTestRule.onNodeWithTag("KeyboardButton_9").assertIsDisplayed() composeTestRule.onNodeWithTag("KeyboardButton_.").assertIsDisplayed() composeTestRule.onNodeWithTag("KeyboardButton_0").assertIsDisplayed() - composeTestRule.onNodeWithTag("KeyboardButton_").assertIsDisplayed() + composeTestRule.onNodeWithTag("KeyboardButton_backspace").assertIsDisplayed() } @Test fun keyboard_tripleZero_when_not_decimal() { composeTestRule.setContent { - Keyboard(onClick = {}, isDecimal = false) + Keyboard(onClick = {}, isDecimal = false, onClickBackspace = {}) } composeTestRule.onNodeWithTag("KeyboardButton_000").assertIsDisplayed() } @@ -53,7 +53,7 @@ class KeyboardTest { @Test fun keyboard_decimal_when_decimal() { composeTestRule.setContent { - Keyboard(onClick = {}, isDecimal = true) + Keyboard(onClick = {}, isDecimal = true, onClickBackspace = {}) } composeTestRule.onNodeWithTag("KeyboardButton_.").assertIsDisplayed() } @@ -62,7 +62,7 @@ class KeyboardTest { fun keyboard_button_click_triggers_callback() { var clickedValue = "" composeTestRule.setContent { - Keyboard(onClick = { clickedValue = it }) + Keyboard(onClick = { clickedValue = it }, onClickBackspace = {}) } composeTestRule.onNodeWithTag("KeyboardButton_5").performClick() @@ -80,7 +80,7 @@ class KeyboardTest { fun keyboard_button_click_tripleZero() { var clickedValue = "" composeTestRule.setContent { - Keyboard(onClick = { clickedValue = it }, isDecimal = false) + Keyboard(onClick = { clickedValue = it }, onClickBackspace = {}, isDecimal = false) } composeTestRule.onNodeWithTag("KeyboardButton_000").performClick() diff --git a/app/src/main/java/to/bitkit/ui/components/Keyboard.kt b/app/src/main/java/to/bitkit/ui/components/Keyboard.kt index 7c7d74775..4b620cfed 100644 --- a/app/src/main/java/to/bitkit/ui/components/Keyboard.kt +++ b/app/src/main/java/to/bitkit/ui/components/Keyboard.kt @@ -6,12 +6,16 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.sizeIn import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign @@ -19,6 +23,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import to.bitkit.R import to.bitkit.ui.theme.AppThemeSurface import to.bitkit.ui.theme.Colors import to.bitkit.ui.theme.InterFontFamily @@ -26,8 +31,9 @@ import to.bitkit.ui.theme.InterFontFamily @Composable fun Keyboard( onClick: (String) -> Unit, - isDecimal: Boolean = true, - modifier: Modifier = Modifier + onClickBackspace: () -> Unit, + modifier: Modifier = Modifier, + isDecimal: Boolean = true ) { LazyVerticalGrid( verticalArrangement = Arrangement.spacedBy(34.dp), @@ -45,7 +51,17 @@ fun Keyboard( item { KeyboardButton(text = "9", onClick = onClick) } item { KeyboardButton(text = if (isDecimal) "." else "000", onClick = onClick) } item { KeyboardButton(text = "0", onClick = onClick) } - item { KeyboardButton(text = "", onClick = onClick) } + item { + Icon( + painter = painterResource(R.drawable.ic_backspace), + contentDescription = stringResource(R.string.common__delete), + modifier = Modifier + .sizeIn(minHeight = 30.dp) + .padding(vertical = 4.dp) + .clickable(onClick = onClickBackspace) + .testTag("KeyboardButton_backspace") + ) + } } } @@ -65,12 +81,14 @@ private fun KeyboardButton( textAlign = TextAlign.Center, color = Colors.White, ), - modifier = Modifier.clickable( - onClick = { - onClick(text) - }, - onClickLabel = text - ).testTag("KeyboardButton_$text"), + modifier = Modifier + .clickable( + onClick = { + onClick(text) + }, + onClickLabel = text + ) + .testTag("KeyboardButton_$text"), ) } @@ -79,7 +97,10 @@ private fun KeyboardButton( private fun Preview() { AppThemeSurface { Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Bottom) { - Keyboard(modifier = Modifier.fillMaxWidth().padding(41.dp), onClick = {}) + Keyboard( + modifier = Modifier + .fillMaxWidth() + .padding(41.dp), onClick = {}, onClickBackspace = {}) } } } @@ -89,7 +110,13 @@ private fun Preview() { private fun Preview2() { AppThemeSurface { Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Bottom) { - Keyboard(isDecimal = false, modifier = Modifier.fillMaxWidth().padding(41.dp), onClick = {}) + Keyboard( + isDecimal = false, + modifier = Modifier + .fillMaxWidth() + .padding(41.dp), + onClick = {}, + onClickBackspace = {}) } } } @@ -99,7 +126,13 @@ private fun Preview2() { private fun Preview3() { AppThemeSurface { Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Bottom) { - Keyboard(isDecimal = false, modifier = Modifier.fillMaxWidth().padding(41.dp), onClick = {}) + Keyboard( + isDecimal = false, + modifier = Modifier + .fillMaxWidth() + .padding(41.dp), + onClick = {}, + onClickBackspace = {}) } } } diff --git a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt index 75fbe225f..bc3a5dbcc 100644 --- a/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/wallets/send/SendAmountScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import okhttp3.internal.toLongOrDefault import to.bitkit.R import to.bitkit.models.NodeLifecycleState import to.bitkit.models.PrimaryDisplay @@ -63,7 +64,7 @@ fun SendAmountScreen( Column( modifier = Modifier.padding(horizontal = 16.dp) ) { - BalanceHeaderView(sats = uiState.amountInput.toLong(), modifier = Modifier.fillMaxWidth()) + BalanceHeaderView(sats = uiState.amountInput.toLongOrDefault(0), modifier = Modifier.fillMaxWidth()) Spacer(modifier = Modifier.height(24.dp)) @@ -117,6 +118,7 @@ fun SendAmountScreen( Keyboard( onClick = { number -> onEvent(SendEvent.AmountChange(number)) }, + onClickBackspace = { onEvent(SendEvent.BackSpaceClick) }, isDecimal = currencyUiState.primaryDisplay == PrimaryDisplay.FIAT, modifier = Modifier.fillMaxWidth(), ) diff --git a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt index 1b20ca3ee..834450654 100644 --- a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt @@ -228,6 +228,7 @@ class AppViewModel @Inject constructor( SendEvent.SpeedAndFee -> toast(Exception("Coming soon: Speed and Fee")) SendEvent.SwipeToPay -> onPay() + SendEvent.BackSpaceClick -> onClickBackspace() } } } @@ -270,11 +271,22 @@ class AppViewModel @Inject constructor( private fun onAmountChange(value: String) { val newInput = if (_sendUiState.value.amountInput == "0") value else _sendUiState.value.amountInput + value - val isAmountValid = validateAmount(newInput) - if (isAmountValid) { - _sendUiState.update { it.copy( amountInput = newInput,) } + _sendUiState.update { + it.copy( + amountInput = newInput, + isAmountInputValid = validateAmount(newInput) + ) + } + } + + private fun onClickBackspace() { + val newInput = if (_sendUiState.value.amountInput.length <= 1) "0" else _sendUiState.value.amountInput.dropLast(1) + _sendUiState.update { + it.copy( + amountInput = newInput, + isAmountInputValid = validateAmount(newInput) + ) } - _sendUiState.update { it.copy(isAmountInputValid = isAmountValid,) } } private fun onPaymentMethodSwitch() { @@ -742,6 +754,7 @@ sealed class SendEvent { data object AmountReset : SendEvent() data class AmountContinue(val amount: String) : SendEvent() data class AmountChange(val value: String) : SendEvent() + data object BackSpaceClick : SendEvent() data object SwipeToPay : SendEvent() data object SpeedAndFee : SendEvent() diff --git a/app/src/main/res/drawable/ic_backspace.xml b/app/src/main/res/drawable/ic_backspace.xml new file mode 100644 index 000000000..6f46d5cbf --- /dev/null +++ b/app/src/main/res/drawable/ic_backspace.xml @@ -0,0 +1,13 @@ + + + +