Repository navigation
fix: improve usdt payment feedback and layout - #1564
ben-kaufman wants to merge 9 commits into
Conversation
[Medium impact] The changes affect several payment and USDT screens within the wallet app. The PR appears safe to merge, with non-blocking improvements needed for accessible loading feedback and regression coverage. FindingsSummaryThis PR improves USDT payment feedback, request-card layout, and receive sharing.
Two non-blocking improvements remain: expose loading to TalkBack and test the new receive-amount conversion. Reviews (1) · Last reviewed commit: "fix: improve usdt payment feedback and l..." · Reviewed by Greptile |
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
talosmachina
left a comment
There was a problem hiding this comment.
No findings. Shows per-contact progress while a contact payment resolves and blocks a second selection, gives the request card's amount/status column bounded width, pads USDT confirmation and incoming activity actions above the navigation bar, and shares the direct-receive amount from its parsed atomic value. Reviewed 9112565, full tier, reasoned from the code and CI: Bitkit Android branches are not built here.
What I checked, and 6 candidates I ruled out
Read in full: SendContactSelectViewModel.kt, SendContactSelectScreen.kt, PubkyContactRow.kt, PaykitAmountView.kt, Money.kt (MoneyCell), PaymentRequestCard in PaymentRequestsScreen.kt, PaykitUsdtReview.kt, UsdtActivityDetail.kt, the ADDRESS page of UsdtDepositReceiveScreen.kt, UsdtReceiveContent.kt
Call sites traced: PubkyContactRow (send contact select, create request, create subscription), PaykitAmountCell / MoneyCell (request card, create request, subscription row), UsdtActivityDetail (wallet screen route, send review), PaykitUsdtReview (SendRoute.UsdtReview)
CI: lint, detekt, build-local and Greptile green; build and the local e2e matrix still running when this was posted
Ruled out
- Double tap starts two resolutions: the null check and
resolvingPublicKeyupdate happen synchronously beforelaunch, so a second tap returns early;finallyclears it on success, failure and cancellation. - Selection stays locked after navigating to the amount screen: the state clears in
finallyright after the effect is emitted, so returning to the list allows another pick, which the new view model test asserts. - Other
PaykitAmountCellcallers change width:modifierdefaults toModifier, and only the request card passesweight(1f);TextAlign.EndinMoneyCellonly changes wrapped lines. - Double navigation-bar inset: neither
BottomSheetnor the nav host applies navigation-bar insets, and sibling send screens in the same sheet (SendAmountScreen,SendAddressScreen) pad themselves the same way. - Share text drops a typed amount: an unparsable amount now shares no amount, but the QR then carries no
uint256either, so share and QR agree. - Contact rows gain a role they should not have: rows with
isSelected == nullare clickable, soRole.Buttondescribes them; radio semantics are unchanged whereisSelectedis set.
Merge confidence: 4/5, the navigation-bar fixes are covered only by device journeys, and CI's build and e2e had not finished.
There was a problem hiding this comment.
Verdict: 💬 Comment. Two MEDIUM findings: the contact picker unlocks before the amount screen opens, and payment request rows now cut off contact names. Test 4 did not run before 95f57d4 was pushed.
The PR moved to 95f57d4 after this run; these results are for 9112565.
Findings: 2 MEDIUM, 1 LOW. 95f57d4 does not touch these lines.
-
MEDIUM
app/src/main/java/to/bitkit/ui/screens/wallets/send/SendContactSelectViewModel.kt:98: the picker unlocks before the payment opens.finallyclearsresolvingPublicKeyas soon asOpenPaymentis emitted.openContactPaymentthen runs a scan job that decodes the endpoints and refreshes USDT before it navigates.- In Test 1 the spinner disappeared about 0.5 s before the amount screen slid in. Per the code, every row is enabled again in that gap.
- #1525 asks to keep selection locked until navigation.
-
MEDIUM
app/src/main/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestsScreen.kt:628: the secondweight(1f)splits every request row 50/50, even for a short amount with no long status.- Contact names and subtitles that fit next to a short amount can now end in "…" on every
PaymentRequestCardcaller. - At 130% text on a Pixel 7, "Alexandra Payer" shows as "Alexandra P…" beside
$2.00 pending, with half the row empty.
- Contact names and subtitles that fit next to a short amount can now end in "…" on every
-
LOW
app/src/main/java/to/bitkit/ui/screens/wallets/usdt/UsdtActivityDetail.kt:182: only the footer gets the navigation-bar inset.- The summary view still scrolls to the bottom of the screen.
- On the compact emulator at 200% text with three-button navigation, Details stays behind the bar when scrolled to the end.
QA for 9112565: two Android 16 emulators, a compact Small Phone (360dp) as payer and a Pixel 7 as requester, on a local USDT stack (Arbitrum fork and bundler).
Test 1: Contact picker progress and retry ✅ The tapped contact shows a spinner while the other rows are disabled. A failed lookup re-enables them, and a retry opens the amount screen.
- A contact with no payment endpoint:
- The spinner showed on its row, and both rows were disabled.
- After about 12 s the lookup failed with "No compatible payment endpoint is available." Both rows were then enabled.
- Bartholomew Requester then showed the spinner and opened the amount screen.
- Back from the amount screen returned to the picker with both rows enabled. Nothing was paid.
- I read the spinner and the rows' enabled state from UI dumps taken during resolution.
test1-contact-picker.2x.mp4
Test 2: USDT receive of 3.50 ✅ The QR keeps uint256=3500000. Both Shares send 3.5 USDT.
- After entering 3.50, the QR encodes
ethereum:0xFd08…@42161/transfer?address=0xe72D…eD9c&uint256=3500000. - Share on the QR and Share in Show Details both preview "Network: Arbitrum One", the address and "3.5 USDT".
- The QR content comes from its content description on screen. The share text comes from the system share sheet's preview.
test2-receive-share.2x.mp4
Test 3: USDT confirmations and incoming Details above system navigation ✅ Swipe To Pay and Cross-Network Deposits stay above the bar in three-button and gesture modes.
- All on the compact emulator, in three-button and gesture modes:
- the contact USDT payment, with details collapsed and expanded
- a one-time $2 USDT request, with details collapsed and expanded
- the first installment of a $3 monthly USDT subscription, collapsed and expanded in three-button mode and expanded in gesture mode
- In received USDT activity Details, Cross-Network Deposits sits above the bar in both modes.
- Each payment was cancelled without paying.
test3-confirmations-and-details.2x.mp4
Test 4: Payments list with a long verified-USDT status ⏭️ Not run: 95f57d4 was pushed while Test 3 ran.
- It needs a USD request and a BTC request, each paid in USDT and verified, then the Payments list in Polish at 130% text.
Not tested on device:
- The iOS-only actions added to
usdt-bridge-details.xmlandusdt-payment-links-and-scans.xml. - The long verified-USDT status from #1537 (Test 4 did not run).
Reviews I relied on:
- Greptile raised the TalkBack loading state in this comment. 95f57d4 addresses it, so it is not repeated here.
- Talos's review found no findings. The fix asked for in the first finding keeps the behaviour that review checked: the picker unlocks again after Back from the amount screen.
Scope: a full review of diff, 19 files.
No pair PR: synonymdev/bitkit-ios#1002 is a separate iOS accessibility fix. iOS already shows the contact spinner and shares 3.5 USDT.
There was a problem hiding this comment.
Verdict: ⛔️ Request changes. Request cards now cut a long amount to "…" (Test 5). The three findings from our last review are fixed.
Findings: 1 MEDIUM, 1 LOW.
-
MEDIUM
app/src/main/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestsScreen.kt:631: request cards cut a long amount to "…".- The amount column is capped at half of the free width, and its amount is held to one line with an ellipsis.
- Before this PR the amount took the width it needed.
- On a 360dp phone at 130% text, the incoming 1,000,000-sat request reads "₿ 1 000 0…" next to Pay. At 100% the same amount just fits.
- The cap applies to every
PaymentRequestCard: the Payment Requests sheet, the Payments tab, a subscription's payment history and the Sent receipt.
-
LOW
app/src/main/java/to/bitkit/ui/components/Money.kt:99: the status that replaces a BTC request's fiat amount breaks words.- With fiat as the primary unit, the receipt status takes the fiat amount's bold style and wraps inside the capped column.
- On a Pixel 7 in Polish at 130% text, the 5,000-sat request paid in USDT reads "Płatność / zweryfikowan / a · 4,12485 / USDT".
- With Bitcoin as the primary unit, the same status is the smaller second line and wraps between words.
Earlier findings, checked at fccb1f9: all three are fixed. The replies are in their threads.
- The contact picker keeps the spinner until the amount screen slides in (Test 1).
- A short amount leaves the rest of the row to the contact: "Alexandra Payer" shows in full beside "$2,00" at 130% text (Test 4).
- Activity details get the navigation-bar inset in the summary view too: Details clears three-button navigation at 200% text (Test 3).
QA for fccb1f9: two Android 16 emulators, a compact Small Phone (360dp) as payer and a Pixel 7 as requester, on a local USDT stack (Arbitrum fork and bundler).
Test 1: Contact picker progress and retry ✅ The tapped contact keeps its spinner until the amount screen slides over it. A failed lookup re-enables the rows for a retry.
- A contact with no payment endpoint:
- The spinner showed on its row and both rows were disabled. A tap on the other row did nothing.
- After about 10 s "Unable To Pay Contact" showed, and both rows were enabled.
- Bartholomew Requester, three times:
- The spinner stayed on until the amount screen started sliding in. No frame shows the picker idle in between.
- A tap on the other row during resolution started nothing.
- Back returned to the picker with both rows enabled. Nothing was paid.
- I read the rows' state from UI dumps and the handoff from 10 fps frames of the recording. The still shows four frames 0.1 s apart.
test1-contact-picker.2x.mp4
Test 2: USDT receive of 3.50 ✅ The QR keeps uint256=3500000. Both Shares send 3.5 USDT.
- After entering $ 3.50, the QR encodes
ethereum:0xFd08…@42161/transfer?address=0xB771…963b&uint256=3500000. - Share on the QR and Share in Show Details both preview "Network: Arbitrum One", the address and "3.5 USDT".
- The QR content comes from its content description on screen. The share text comes from the system share sheet's preview.
test2-receive-share.2x.mp4
Test 3: USDT activity Details above system navigation ✅ In both navigation modes and both hosts, the last button sits above the bar, also at 200% text.
- The received $1,500 USDT, opened from the USDT wallet on the compact phone:
- Summary scrolled to the end: Details clears the bar in gesture and three-button modes, at 100% and 200% text.
- Expanded: Cross-Network Deposits clears the bar in both modes, at 100% and 200% text.
- The sent $5 payment, opened from Details on "USDT Sent" in the send sheet:
- Details and Open Block Explorer clear the bar in both modes.
- The gap under the last button is 16dp at most, so neither host gets the inset twice.
- I read the button and bar edges from full-resolution screenshots.
test3-activity-details.2x.mp4
Test 4: Payments list with a long verified-USDT status ✅ In Polish at 130% text, both verified statuses wrap in full inside the amount column and the contact stays readable.
- On the requester (Pixel 7), with a $5 request and a 5,000-sat request, both paid in USDT:
- "Płatność zweryfikowana · 5,00 USDT" and "Płatność zweryfikowana · 4,12485 USDT" wrap in full under "+$5,00" and "+₿ 5 000".
- The contact shows as "Alexandra P…".
- The pending "$2,00" and "₿ 1 000 000" requests show "Alexandra Payer" in full.
- With fiat as the primary unit, the BTC request's status breaks "zweryfikowana" mid-word (the LOW finding).
test4-payments-list-b.2x.mp4
Test 5: Request card amounts at large text on a compact phone ❌ The 1,000,000-sat request card shows "₿ 1 000 0…" at 130% text.
- On the payer (360dp) at 130% text, in English:
- The $2.00 card shows its amount in full.
- The 1,000,000-sat card shows "₿ 1 000 0…" above "$ 824.70", next to Pay.
- At 100% text the same amount just fits.
- I added this case for the new one-line amount cap, which no journey covers.
test5-request-cards-a.2x.mp4
Not tested on device:
- USDT confirmations (Swipe To Pay) above system navigation: our earlier review proved them at 9112565, and
PaykitUsdtReview.ktis unchanged since. - The TalkBack progress state on the loading contact: checked in
PubkyContactRow.ktandSendContactSelectScreenTest.kt. - The iOS-only actions added to
usdt-bridge-details.xmlandusdt-payment-links-and-scans.xml.
Scope: a delta review of 9112565...fccb1f9, 12 files, plus the three findings our last review left open.
No twin PR: synonymdev/bitkit-ios#1002 is the related iOS accessibility and journey follow-up, not a port of these fixes.
jvsena42
left a comment
There was a problem hiding this comment.
Code scan: no HIGH/MEDIUM. One LOW (journey preconditions) is inline.
Checked and clean:
- The receive share text and the QR
uint256now come from the same parsedatomic, so they always agree. maxAmountLines = 1is passed only byPaymentRequestCard, never on review or confirm screens.OpenPaymentcarries the resolvedpublicKey, so no other contact can be paid, and every exit ofopenContactPaymentreleases the row lock.PaykitUsdtReviewonly adds a nav-bar inset; the auth gate and Swipe To Pay order are unchanged.- The hidden-balance path in
UsdtReceivePrivacyTestis untouched.
Perf-relevant: BoxWithConstraints now wraps every PaymentRequestCard in lazy lists. I'll measure Payments-tab scroll with a long list against master.
The six journey file names and the added action prose match the twin synonymdev/bitkit-ios#1002.
Device gate (partial): not run yet. Pending: the six changed journeys, a perf check and Check 5. The device result follows in a second review.
piotr-iohk
left a comment
There was a problem hiding this comment.
QA review
Scope: Full review of the complete PR diff against merge base 402aecb, at 79d2089.
1 actionable finding — resolve or provide an evidence-backed rebuttal.
Contact selection stays locked until the scan job from openContactPayment finishes, including the gap after OpenPayment, and unlocks on failure, cancellation, and completion. USDT confirmation and incoming activity details pad the outer column for the navigation bar. Arbitrum receive sharing formats the parsed atomic amount with usdt_format_amount from bitkit-core v0.8.0-rc6, so an entered 3.50 shares as 3.5 while the QR keeps uint256. The amount line is no longer held to half the card, so the truncation in the earlier amount comment does not apply at this revision.
iOS contact loading was compared at 7b3f093: the spinner lasts through scan and navigation, and a second tap is ignored. Android also disables the other rows. bitkit-ios#1002 is the related accessibility follow-up, not a port of these fixes, and was not reviewed in full.
CI build, lint, and detekt succeeded on this head. This review did not run unit or Compose tests and did not start a device.
Device testing: not performed in this review.
Recommended before device testing: The new steps in request-summary.xml, usdt-send-review-and-details.xml, and contact-request-or-pay.xml depend on wallet state their descriptions never create. See the open journey comment.
Suggested additional test cases
- Android, 360dp-wide display, text size 130%, Polish. Open Payments on a verified USDT receipt whose status contains "Płatność zweryfikowana". Expected: "zweryfikowana" is fully visible, the status wraps only between words, and the contact name stays readable. Repeat with Bitcoin as the primary unit for a BTC request paid in USDT.
Findings
- [LOW] Long verification words still clip in the amount column — inline at
app/src/main/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestsScreen.kt:602.
piotr-iohk
left a comment
There was a problem hiding this comment.
QA review
Scope: Follow-up at 595951a0 since 79d2089e, using the inherited baseline previous QA review. The merge base is unchanged at 402aecb6. This pass inspected receipt-status sizing, the payment-request layout assertions added in this commit, and the journey text updates. Inherited coverage is contact selection through cancellation, contact-row disabled and progress state, USDT navigation-bar insets, Arbitrum share text versus the QR amount, contact tests and journey steps unchanged in this delta, and the iOS contact-loading comparison at 7b3f093be6643a3075634f57d5d980f2c58912c2.
1 actionable finding — resolve or provide an evidence-backed rebuttal.
Device testing: not performed in this review. The Compose payment-request tests were not executed. Widths below were measured offline from the repo's Inter Tight fonts. iOS receipt-card layout was not compared in this pass.
Suggested additional test cases
- Android. Use a 320dp-wide window, font scale 1.3, and a USD-denominated payment-request history row whose verified receipt is "Płatność zweryfikowana · 1,234567 USDT" and whose contact is named "Maria". Open that history. The contact name is fully visible, and each word of the receipt status stays on one line.
Earlier findings reconciled at this revision: 9 verified fixed.
Findings
- [MEDIUM] Keep a readable contact name beside long receipt words — inline at
app/src/main/java/to/bitkit/ui/screens/paymentrequests/PaymentRequestsScreen.kt:631.
piotr-iohk
left a comment
There was a problem hiding this comment.
QA review
Scope: Follow-up of 140c2b91 since 595951a0, using baseline review 5570564230. Comparison base and merge base remain 402aecb6. This pass inspected the receipt-card layout delta, its Compose tests, and the request-summary journey step. Inherited coverage is the unchanged contact-selection lock, contact-row disabled state, USDT navigation-bar insets, direct Arbitrum share text, contact-selection tests and journeys, and the iOS contact-loading comparison.
No new actionable code findings.
PaymentRequestCard now lays the contact and amount out in a FlowRow. The contact row is weighted and reports its minimum intrinsic width (avatar plus the longest name or subtitle word). The receipt status uses IntrinsicSize.Max, so USD/USDT BodyS and BTC CaptionB prefer a full status line and move below the contact when that line does not fit beside the contact minimum. Foundation 1.11.4 measures weighted flow children by that minimum, then expands the weight inside the card's finite width, which keeps short amounts beside the contact and gives a wrapped receipt the card width. SubscriptionRow and the create-request amount cell do not pass statusModifier. History, the payment-request sheet, the sent confirmation, and subscription payments all use this card.
The updated test places the card in a 320dp or 375dp box with 16dp horizontal padding, at 130% and 200% text, and checks Maria plus the Polish status for USDT, USD, and BTC: displayed, no visual overflow, and no word split. It does not assert whether the amount is beside or below the contact. The journey step matches bitkit-ios aff5b7b. contact-request-or-pay.xml, usdt-send-review-and-details.xml, and journeys/payment-requests/README.md are unchanged since the baseline. The full PR adds no other paths.
Validation: source inspection of the pinned delta and Compose 1.11.4 flow and intrinsic measurement. PaymentRequestsScreenTest was not executed here. Device testing: not performed in this review. This follow-up did not re-check earlier review threads.
Non-blocking consistency suggestion: iOS keeps the side-by-side row only when the contact's full ideal width fits (ViewThatFits in PaymentRequestsView.swift at the same iOS commit). Android can ellipsize a multi-word name when its longest word still fits beside the receipt. The shared journey requires that behavior only for a short name such as Maria.
Earlier findings reconciled at this revision: 9 verified fixed.
There was a problem hiding this comment.
Verdict: ✅ Approve.
Findings: None. The earlier amount-truncation and Polish-status findings are fixed, and the compact-width contact-name check passes.
QA for 140c2b9: Android 16 emulator. I built the app and instrumentation at this head. The layout checks use deterministic request and receipt fixtures with the production Payments screen, card and receipt formatter. No funds were sent.
Test 1: Request-card regressions ✅ All 14 PaymentRequestsScreenTest checks passed on device.
The instrumentation runner confirmed the large-amount, short-amount/contact-space, padded compact-card, whole-word and both-unit-setting assertions. These read the rendered text layouts for overflow and line boundaries.
test1-card-regressions.2x.mp4
Test 2: Compact Payments list with Polish receipts ✅ Maria and the full 1,234567 USDT receipt remain readable at 130% and 200% text.
- The production Payments list is constrained to 320dp and retains its 16dp horizontal list padding.
- USD-, USDT- and BTC-denominated requests show “Płatność zweryfikowana · 1,234567 USDT” in both primary unit settings. Long receipt content moves below the contact and wraps between words.
- At default text size, the short pending card keeps its amount beside Maria.
- I checked the recording and rendered-text assertions for complete words, no overflow and the default row's positions.
test2-polish-exact-receipts.2x.mp4
Test 3: Whole amounts and contact space ✅ Long amounts stay complete, and Alexandra Payer fits beside $2.00 pending.
- At padded 320dp and 130% text,
₿ 1 000 000and$10,000.00each fit on one line beside Alice. - At padded 375dp and 130% text, Alexandra Payer remains whole beside
$2.00 pending, with the avatar and subtitle visible. - Pay and Dismiss each invoked their supplied callback once, checked by instrumentation assertions. This did not dispatch a payment.
test3-whole-amounts-and-actions.2x.mp4
Earlier device evidence remains applicable to unchanged paths:
- Our fccb1f9 review proved contact loading/failure/retry, receive sharing and QR amounts, and activity Details above system navigation.
- Our 9112565 review proved contact, one-time and recurring USDT confirmations above system navigation; that confirmation component is unchanged.
Scope: the contiguous fccb1f9…140c2b9 delta, eight files, plus prior open findings. Journey prerequisite edits were checked in source; the complete funded two-wallet journeys and iOS-only deposit/scanner actions were not driven here.
Related synonymdev/bitkit-ios#1002 fix: improve usdt deposit accessibility matches the receipt stacking behavior and the changed receipt-layout journey step; iOS device QA is outside this Android run.
ovitrif
left a comment
There was a problem hiding this comment.
Approved per the ovi-reviewer review.
ovitrif
left a comment
There was a problem hiding this comment.
Approved per the ovi-reviewer review.
|
Integrated current master and resolved the receive-screen conflict in 371478a. The new receive-tab swipe handling remains intact, alongside this PR's layout, loading and sharing fixes. All 4,375 unit tests pass; compilation, Detekt (0 findings) and Android Lint (unchanged baseline only) pass. All PR commit signatures are verified locally and on GitHub. Re-requested review. |
jvsena42
left a comment
There was a problem hiding this comment.
Approving at 371478a. My journey threads are resolved, and no HIGH/MEDIUM is open. The only change since the gate build a8c5682 is a merge of master. Its one conflict in UsdtDepositReceiveScreen.kt keeps this PR's UsdtDepositReceiveContent callbacks (draft amount, network reset, clearError, prepare) inside master's swipeToChangeTab wrapper from #1582.
Device gate: a8c5682 — journeys: payment-requests/request-summary.xml last action and contact-request-or-pay.xml failure/retry pass on Pixel_9 against an iOS twin; perf: Payments-tab scroll 0.96% / 0.46% janky frames, p90 23 / 18 ms (master 1.10%, 19 ms) on the 10 rows available; Figma: not compared; l10n: Polish checked.
- Receipts: a $3.00 USD request showed "Payment verified · 3.00 USDT". A ₿3,000 request paid in USDT showed "2.46375 USDT", which rounds to the payer's Payment value of 2.46. Polish showed "2,46375".
- Narrow width: at 320 dp with font 1.3 in Polish, the contact and every status word stayed complete and the amount wrapped below. At default size it sits beside the contact.
- Contact pay: the tapped row showed a spinner while other rows were ignored. A contact with no endpoints showed "Unable To Pay Contact" and the list stayed selectable, then retrying the payable contact opened the amount screen.
- Perf: the first PR scroll after install was 40% janky with one
Skipped 63 frames. It didn't repeat in the next runs, so it was cold start, not the change.
The USDT review now pads the navigation bar, which fixes #1523. #1568 edits the same Column, so whichever lands second must keep the padding.
CI at 371478a: green apart from the ovi-reviewer check still running.
There was a problem hiding this comment.
Verdict: ✅ Approve.
Findings: None.
QA for 371478a: Android 16 emulators, with app and instrumentation built at this head. Payments used an isolated Arbitrum fork and test funds. Recordings play at 2×.
Test 1: Receive, contact and request-card regressions ✅ The existing rendered assertions pass.
Instrumentation checked shared text and decoded QR images for entered 3.50 and 0.000001, hidden balances, contact progress and disabled-row semantics, complete Polish receipt words, long amounts and contact space. The compact receipt assertions cover padded 320dp cards at 130% and 200% text; the 375dp contact-space fixture ran in a sufficiently wide window.
component-regressions.2x.mp4
Test 2: Receive swipes and page navigation ✅ Swipes change tabs without copying; a QR tap still copies.
A right swipe on the USDT QR selects Spending, and a return swipe selects USDT. A left swipe on the final tab stays there without the copy tooltip. Tapping the QR shows the tooltip. Horizontal swipes leave Amount and Network on their pages.
receive-navigation.2x.mp4
Test 3: Receive 3.50 and share ✅ Both Shares show 3.5 USDT, while the QR retains uint256=3500000.
The entered amount and BTC equivalent are visible. I checked the QR URI through its content description and both share texts through the system previews. Cancelling an edited amount preserves the committed QR amount. Test 1 independently decodes the shared QR images.
receive-amount.2x.mp4
Test 4: Genuine USD and BTC receipts ✅ Verified receipts match the corrected journey comparisons and remain readable in Polish at 320dp.
- The USD request and receipt are both
1.23. - The 1,000-sat request's receipt is
0,82096 USDT, which rounds to the payer's Payment value0.82. Its0.68fee makes the activity total1.50. - At 130% text, Alex and every verification-status word remain complete. The recording also checks the same genuine receipts at default text size.
Requester is on the left; payer is on the right. The comparison uses the Payment field, excluding the fee-inclusive total.
receipt-comparison.2x.mp4
Test 5: Contact loading and USDT confirmation ✅ The contact opens its funded amount screen, and confirmation clears both navigation modes.
The selected saved contact shows progress through resolution. I opened ordinary contact USDT review, checked collapsed and expanded views with gesture and three-button navigation, then cancelled without paying. Test 1 checks the other row's disabled state; the current-head review separately confirms endpointless-contact failure and successful retry.
contact-confirmation.2x.mp4
Earlier device evidence remains applicable to unchanged paths:
- The activity-details review covers summary and expanded actions above both system navigation modes.
- The confirmation review covers recurring USDT confirmation in the same unchanged component.
Scope: the contiguous 140c2b9…371478a delta, including the receive merge resolution and revised receipt assertions. The complete unchanged journey sequences and iOS-only bridge/scanner actions were not rerun; receive Fees-page behavior was inspected in source.
Related synonymdev/bitkit-ios#1002 fix: improve usdt deposit accessibility matches the revised receipt assertions, with the documented iOS 375-point / Android 320-dp difference. Its device QA is outside this Android run.
Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest
Fixes #1523
Fixes #1525
Fixes #1537
Fixes #1561
Related iOS accessibility and shared-journey follow-up: synonymdev/bitkit-ios#1002
Description
3.50shares as3.5 USDT. QR amounts and selected bridge deposit addresses remain unchanged.Out of Scope
Design
Uses the existing payment request layouts and shared contact spinner. No redesign. The latest handoff page reference for these small fixes is not confirmed.
Preview
The linked issues show the affected screens. The focused Compose device tests exercise contact loading and a long translated receipt at 320dp including the list’s outer padding, at 130% and 200% text; no screenshot attachment is available yet.
QA Notes
Journeys
contact-request-or-pay.xml— selected-contact progress, duplicate-selection prevention and retry after failure.request-summary.xml— readable contact and exact amount with a long translated verification status.usdt-receive-amount-and-units.xml— enter3.50, share3.5, and retainuint256=3500000in the QR.usdt-send-review-and-details.xml— confirmation and incoming-activity actions stay above gesture and three-button navigation.usdt-bridge-details.xml— shared iOS accessibility checks; Android behavior is unchanged by that step.usdt-payment-links-and-scans.xml— shared iOS scanner-scroll check; Android behavior is unchanged by that step.Journey prerequisites include completed USDT receipts, linked payment contacts and unpaid requests. USD receipts are compared with their request amount; BTC-denominated receipts keep up to six decimals and are compared with the rounded Payment field in the payer’s activity detail, excluding fees. Layout checks use iOS 375 points / Android 320 dp. The failure/retry step uses a contact without payment endpoints.
Manual Tests
N/A
Automated Checks
SendContactSelectViewModelTest.kt— resolution and navigation keep the selected contact locked, including the effect handoff gap; completion/cancellation/failure allow retry.SendContactSelectScreenTest.kt— progress, disabled contact semantics and selection after resolution.PaymentRequestsScreenTest.kt— contact/status text remains fully laid out, with no split words, at narrow width with enlarged text for USDT-, USD- and BTC-denominated requests; short amounts leave room for longer contact names. Regressions cover a 1,000,000-sat amount, a large USD amount, and a Polish BTC-request status in both unit settings.PaymentRequestsScreenTest.kt— all 14 Compose device tests passed on the review emulator, including actual padded 320dp cards at 130% and 200% text. Existing contact, bridge and receive-sharing checks also passed. No funds were sent.Validation:
just compile, all 4,375 unit tests, andjust lintpassed after integrating current master. Complete Detekt diagnostics contain no findings; Android Lint reports only the unchanged baseline (280 suppressed findings). Receive-tab swipes from master are preserved. Full three-button/gesture journeys remain for reviewer device QA.