diff --git a/app/src/androidTest/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestAmountLocaleTest.kt b/app/src/androidTest/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestAmountLocaleTest.kt index 4c39e504fc..a97f2a238f 100644 --- a/app/src/androidTest/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestAmountLocaleTest.kt +++ b/app/src/androidTest/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestAmountLocaleTest.kt @@ -168,7 +168,7 @@ class PaymentRequestAmountLocaleTest { val control = composeTestRule.onNodeWithTag(lastControl).getUnclippedBoundsInRoot() assertEquals(divider.left.value, amount.left.value, 0.5f) assertEquals(divider.right.value, control.right.value, 0.5f) - assertTrue(actions.top >= amount.bottom && actions.top - amount.bottom <= 17.dp) + assertTrue(actions.top - amount.bottom >= 12.dp) assertTrue(divider.top >= actions.bottom) val positions = listOf( actions.top.value, diff --git a/app/src/main/java/to/bitkit/ui/screens/paymentrequests/CreatePaymentRequestScreen.kt b/app/src/main/java/to/bitkit/ui/screens/paymentrequests/CreatePaymentRequestScreen.kt index 93872c79d8..be096682dd 100644 --- a/app/src/main/java/to/bitkit/ui/screens/paymentrequests/CreatePaymentRequestScreen.kt +++ b/app/src/main/java/to/bitkit/ui/screens/paymentrequests/CreatePaymentRequestScreen.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -42,6 +43,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag @@ -89,6 +91,7 @@ import to.bitkit.ui.components.PaykitAmountDisplay import to.bitkit.ui.components.PrimaryButton import to.bitkit.ui.components.PubkyContactAvatar import to.bitkit.ui.components.PubkyContactRow +import to.bitkit.ui.components.SHEET_INTRO_IMAGE_WIDTH_FRACTION import to.bitkit.ui.components.TextInput import to.bitkit.ui.components.UnitButton import to.bitkit.ui.components.VerticalSpacer @@ -218,6 +221,7 @@ internal fun PaymentRequestAmountContent( ) CompositionLocalProvider(LocalBringIntoViewSpec provides bringIntoView) { BoxWithConstraints(modifier = Modifier.weight(1f).fillMaxWidth()) { + val maxHeight = this.maxHeight Column( modifier = Modifier.verticalScroll(rememberScrollState()) .heightIn(min = maxHeight).padding(horizontal = 16.dp) @@ -237,7 +241,7 @@ internal fun PaymentRequestAmountContent( ) } } - VerticalSpacer(16.dp) + FillHeight(min = 12.dp) PaymentRequestDenominationLayout(asset, Alignment.Top) { displayAsset -> FlowRow( horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.End), @@ -275,38 +279,32 @@ internal fun PaymentRequestAmountContent( color = Colors.White64 ) } - VerticalSpacer(16.dp) HorizontalDivider( color = Colors.White10, - modifier = Modifier.testTag("PaymentRequestAmountDivider"), + modifier = Modifier.padding(top = 12.dp).testTag("PaymentRequestAmountDivider"), ) - FillHeight() - Box( - contentAlignment = Alignment.Center, - modifier = Modifier.fillMaxWidth().padding(top = 16.dp, bottom = 24.dp), - ) { - val padModifier = Modifier - .onFocusChanged { isNumberPadFocused = it.isFocused } - .testTag("PaymentRequestNumberPad") - if (asset == PaykitAsset.BTC) { - NumberPad( - viewModel = amountInputViewModel, - currencies = currencies, - modifier = padModifier - ) - } else { - NumberPad( - onPress = { - dollars = NumberPadInputHandler.handleInput( - it, dollars, MAX_USD_INPUT_LENGTH, PaykitAsset.USD.decimals - ) - }, - type = NumberPadType.DECIMAL, - modifier = padModifier - ) - } + val padModifier = Modifier + .onFocusChanged { isNumberPadFocused = it.isFocused } + .testTag("PaymentRequestNumberPad") + if (asset == PaykitAsset.BTC) { + NumberPad( + viewModel = amountInputViewModel, + currencies = currencies, + availableHeight = maxHeight, + modifier = padModifier + ) + } else { + NumberPad( + onPress = { + dollars = NumberPadInputHandler.handleInput( + it, dollars, MAX_USD_INPUT_LENGTH, PaykitAsset.USD.decimals + ) + }, + type = NumberPadType.DECIMAL, + availableHeight = maxHeight, + modifier = padModifier + ) } - FillHeight() PrimaryButton( text = stringResource(R.string.common__continue), enabled = (entered?.atomic ?: 0uL) > 0uL, @@ -737,40 +735,57 @@ internal fun PaymentRequestSentContent( .testTag("PaymentRequestSent"), ) { SheetTopBar(titleText = stringResource(R.string.wallet__payment_request_sent_title)) - VerticalSpacer(32.dp) - Image( - painter = painterResource(R.drawable.check), - contentDescription = null, - modifier = Modifier - .align(Alignment.CenterHorizontally) - .size(256.dp) - .testTag("PaymentRequestSentCheck"), - ) - VerticalSpacer(32.dp) - Display( - text = stringResource(R.string.wallet__payment_request_sent_headline) - .withAccent(accentColor = Colors.Purple), - ) - VerticalSpacer(12.dp) - BodyM( - text = stringResource( - if (currentRequest.deliveryStatus == PaykitPaymentRequestDeliveryStatus.Sent) { - R.string.wallet__payment_request_sent_description - } else { - R.string.wallet__payment_request_queued_description + BoxWithConstraints(modifier = Modifier.weight(1f)) { + Column( + modifier = Modifier.verticalScroll(rememberScrollState()).heightIn(min = maxHeight) + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.weight(1f).fillMaxWidth(), + ) { + Image( + painter = painterResource(R.drawable.check), + contentDescription = null, + contentScale = ContentScale.Fit, + modifier = Modifier + .fillMaxWidth(SHEET_INTRO_IMAGE_WIDTH_FRACTION) + .fillMaxHeight() + .testTag("PaymentRequestSentCheck"), + ) } - ), - color = Colors.White64, - textAlign = TextAlign.Start, - modifier = Modifier.fillMaxWidth(), - ) - VerticalSpacer(24.dp) - PaymentRequestCard( - request = currentRequest, - contact = contact, - compactSubtitle = currentRequest.note?.takeIf(String::isNotBlank) ?: paymentRequestStatus(currentRequest), - ) - VerticalSpacer(32.dp) + Display( + text = stringResource(R.string.wallet__payment_request_sent_headline) + .withAccent(accentColor = Colors.Purple), + ) + VerticalSpacer(12.dp) + BodyM( + text = stringResource( + if (currentRequest.deliveryStatus == PaykitPaymentRequestDeliveryStatus.Sent) { + R.string.wallet__payment_request_sent_description + } else { + R.string.wallet__payment_request_queued_description + } + ), + color = Colors.White64, + textAlign = TextAlign.Start, + modifier = Modifier.fillMaxWidth(), + ) + VerticalSpacer(32.dp) + Caption13Up( + text = stringResource(R.string.wallet__payment_request_recipient), + color = Colors.White64, + style = AppTextStyles.CaptionM.copy(letterSpacing = 1.sp), + ) + VerticalSpacer(8.dp) + PaymentRequestCard( + request = currentRequest, + contact = contact, + compactSubtitle = currentRequest.note?.takeIf(String::isNotBlank) + ?: paymentRequestStatus(currentRequest), + ) + VerticalSpacer(16.dp) + } + } PrimaryButton( text = stringResource(R.string.common__ok), onClick = onDone, diff --git a/changelog.d/next/1705.fixed.md b/changelog.d/next/1705.fixed.md new file mode 100644 index 0000000000..d7b2e84c94 --- /dev/null +++ b/changelog.d/next/1705.fixed.md @@ -0,0 +1 @@ +Payment request amount entry keeps the number pad above Continue, and the Payment Requested sheet keeps OK at the bottom with the recipient above it. diff --git a/journeys/paykit-amount-layout.xml b/journeys/paykit-amount-layout.xml index 4053d110e2..df74405ae4 100644 --- a/journeys/paykit-amount-layout.xml +++ b/journeys/paykit-amount-layout.xml @@ -2,7 +2,7 @@ Use an onboarded wallet with USDT enabled, an existing test contact and a current BTC/USD rate. Verify request denomination layout without sending or publishing a request. Open Payment Requests and create a request for the test contact. Open Amount. - Use the denomination toggle to select USD and enter 1.50. Verify the amount is leading-aligned near the header, the denomination toggle is trailing-aligned directly below it, and a divider separates them from the keypad. + Use the denomination toggle to select USD and enter 1.50. Verify the layout matches the Send amount screen: the amount is leading-aligned near the header, spare space sits below it, and the trailing-aligned denomination toggle, the divider, the keypad and Continue sit at the same height and position as on Send. Use the single denomination toggle to switch between BTC and USD several times. Verify the Bitcoin unit control is shown only in BTC. Verify the amount controls, divider and keypad stay at the same vertical positions, including when the Bitcoin unit button wraps below the denomination toggle at enlarged text sizes. Verify every keypad key remains legible and tappable on a short screen at enlarged text sizes, including zero, decimal/000 and Delete. Scroll as needed to reach all keys and Continue. Continue to details and verify the request denomination and amount remain 1.50 USD. Cancel without sending. Open Subscriptions and start creating a subscription for the same contact. Select USDT before opening Amount. Starting from zero, enter 1.50 without deleting first. Continue and verify the subscription amount is 1.50 USD. Reopen Amount and verify the existing cents are preserved. Repeat the layout check in BTC and USD. Verify the controls do not overlap the keypad or Continue. diff --git a/journeys/payment-requests/request-summary.xml b/journeys/payment-requests/request-summary.xml index 03a7964cc2..80aeafbd66 100644 --- a/journeys/payment-requests/request-summary.xml +++ b/journeys/payment-requests/request-summary.xml @@ -4,7 +4,7 @@ On the requester, send the payer contact a Payment Request for 21,000 sats with the note "Lunch last week" - On the requester, verify the Sent receipt shows "Lunch last week", then close it with OK + On the requester, verify the Sent receipt shows "Lunch last week" under a RECIPIENT caption, with OK at the bottom of the sheet and the heading, description and recipient card directly above it, then close it with OK On the payer, verify the Payment Request confirmation screen (testTag "PaymentRequestConfirm") appears with 21,000 sats without opening the pending Payment Requests bell Verify From (testTag "PaymentRequestFrom") shows the requester's contact name Verify For (testTag "PaymentRequestFor") shows "Lunch last week"