Skip to content

fix: improve usdt deposit accessibility - #1002

Merged
ovitrif merged 7 commits into
masterfrom
fix/usdt-deposit-accessibility
Oct 20, 2026
Merged

ovitrif merged 7 commits into
masterfrom
fix/usdt-deposit-accessibility

Conversation

@ben-kaufman

@ben-kaufman ben-kaufman commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #983

Targets master, including the merged recipient-screen and shared accessibility fixes from #973.

Related Android follow-up: synonymdev/bitkit-android#1564

Description

  • Stack deposit history fields at accessibility text sizes so the full network, status and amount remain readable. Normal text keeps the existing compact rows.
  • Stack Status and Receiving Network in deposit details at accessibility sizes, avoiding mid-word breaks in narrow columns.
  • Keep request contacts and receipts beside each other when they fit, stacking them when needed so long localized words remain readable on compact screens with enlarged text.
  • Let recipient-screen drags pass through the camera preview to the scroll view while retaining the photo and flashlight controls.

Out of Scope

Design

Adapts the existing bridge details using the accessibility layout pattern already in #973. Request cards reuse the existing payment request layout. The latest handoff page reference for this fix is not confirmed; no normal-size redesign.

Preview

See #983 for the affected layouts. Simulator screenshots of the corrected recipient scroll were captured locally; no screenshot attachment is available yet.

QA Notes

Journeys

  • updated usdt-bridge-details.xml — full history fields and a single-column detail summary at the largest accessibility text size, restoring the compact layout at normal text.
  • updated usdt-payment-links-and-scans.xml — drag over the camera preview to reach recipient controls and the network warning, keeping gallery and flashlight usable.
  • updated contact-request-or-pay.xml — shared contact-resolution loading/retry coverage; iOS already provides this feedback.
  • updated request-summary.xml — shared long-status and exact-amount readability coverage.
  • updated usdt-receive-amount-and-units.xml — shared 3.50 input, 3.5 share text and unchanged QR atomic amount.
  • updated usdt-send-review-and-details.xml — shared Android navigation-inset check, explicitly scoped to Android.

The shared journey prerequisites now explicitly include the linked payment contacts, one-time/subscription requests and completed USDT receipts. The history check compares USD receipts with the request amount and BTC-denominated receipts with the rounded Payment value in the payer’s activity detail, excluding fees. It uses a supported 375-point device on iOS (320 dp on Android); the retry check uses a contact without payment endpoints. XML and cross-platform changed-action parity were checked. This documentation update does not claim a new run of the full funded journeys.

Manual Tests

  • On a physical iPhone with camera permission enabled, scroll from the live preview, import a QR image and toggle the flashlight — a simulator cannot verify live camera capture or the physical torch.

Automated Checks

  • updated ComponentSizingTests.swift — a deposit with a long network name and six-decimal amount grows vertically at accessibility sizes; existing button and title sizing remains covered.
  • ran simulator recipient scrolling at the largest accessibility size: a drag inside the preview moves the screen and exposes the full network warning. No funds sent.

Validation: simulator build and all 2,622 unit tests passed, including the four sizing tests. Synthetic request-card captures at 320pt with normal, XXX Large and accessibility text were checked for USDT, USD and BTC denominations. SwiftFormat reports no changed-file formatting violations. Translation validation has zero errors and the same three untranslated keys inherited from #973; no strings changed here. Full deposit-history fixture and physical-camera journeys remain for reviewer QA.

@greptile-apps

greptile-apps Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes affect USDT deposit readability and shared scanner interactions.

The PR appears safe to merge, with a non-blocking gap in the new sizing test.

Findings

  1. P2 Test measures different text ▶

Summary

This PR stacks deposit history fields and detail summaries at accessibility text sizes. It also lets drags over the camera preview reach the recipient scroll view.

  • USDT deposit details stack at accessibility text sizes.
  • Camera-preview drags now scroll the screen beneath it.
  • Journey notes now cover extra payment paths.

Reviews (1) · Last reviewed commit: "fix: improve usdt deposit accessibility" · Reviewed by Greptile

Comment thread BitkitTests/ComponentSizingTests.swift Outdated

@talosmachina talosmachina left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings. Stacks the USDT deposit history row and the deposit detail Status/Receiving Network pair at accessibility text sizes, and lets drags on the scanner preview reach the enclosing scroll view. Reviewed d232d6a, full tier, reasoned from the code and CI (iOS does not build on this reviewer's Linux host).

What I checked, and 4 candidates I ruled out

Read in full: Scanner.swift, ActivityRow.swift, UsdtDepositHistoryView.swift, ComponentSizingTests.swift, and the six journey hunks
Call sites traced: ActivityRowContent (lightning, onchain and USDT activity rows keep the default stacked = false, so their layout is unchanged); Scanner (all six callers: scanner screen and sheet, send options, USDT send, seed QR, probing tool)
CI: Run Tests still pending at review time; Greptile passed

Ruled out

  • Disabling hit testing on the camera drops a camera gesture: QRCodeScannerViewController has no tap-to-focus, pinch or touch handling, and none of the six Scanner callers attaches a gesture to it, so .allowsHitTesting(false) removes nothing. The photo picker and torch sit in ScannerCornerButtons, which stays hit-testable.
  • .contentShape(Rectangle()) on the scanner swallowing the scroll drag: no gesture is attached at that level, so the shape only defines the hit area. It does not compete with the scroll view's pan.
  • Stacked row breaking the other activity rows: stacked is opt-in, and only UsdtDepositRow passes it.
  • Amount truncation at AX sizes: lineLimit(nil) together with .fixedSize(horizontal: false, vertical: true) lets the amount wrap. minimumScaleFactor(0.7) only kicks in when the text cannot grow.

The test's mismatch between measured text and rendered text is already raised in Greptile's inline thread, so it is not repeated here. The physical-camera drag is only covered by the PR's manual test: in the simulator the preview is Color.black, not ScannerCamera.

Merge confidence: 4/5. No findings, but CI was still running and no test covers the device camera path (the simulator renders a placeholder there).

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ⚠️ Not verified: the camera-preview scroll needs a physical iPhone

Findings:

  • LOW Bitkit/Views/Wallets/Activity/ActivityRow.swift:104: at accessibility sizes the stacked deposit cards shrink to their content width. Dropping the Spacer removes the only thing that stretched the row, so each card is as wide as its longest line and left-aligned, with ragged right edges between rows and a narrower tap target. The new sizing test checks heights only, so it does not catch this.

QA for b3e6025:
Tested on an iPhone 17 Pro simulator (iOS 26.5) with four deposits: Ethereum and BNB Smart Chain needing attention, Polygon confirmed, Tron pending.

Test 1: deposit history at the largest text size ✅ Every row shows its full network, status and amount.

At AX5 all four rows stack, including "BNB Smart Chain", "Needs attention" and "1.234,56 USDT", with no ellipsis.

t1.2x.mp4

Test 2: deposit summary at the largest text size ✅ Status and Receiving Network stack in one column.

"RECEIVING NETWORK" wraps between words and "Arbitrum One" stays whole.

t2.2x.mp4

Test 3: default text size ✅ The two-column summary and the compact full-width rows return.

t3.2x.mp4

Test 4: drag on the scanner preview ✅ A drag that starts inside the preview scrolls to Paste, Enter Manually and the network warning.

At AX5 the flashlight button toggles and the photo picker opens. The simulator renders a black placeholder in place of the camera, and the base build 73f2bf4 scrolls from the same drag (second video), so this shows no regression but not the fix.

t4.2x.mp4

t4-base.2x.mp4

Test 5: live camera on a physical iPhone ⏭️ Not run: needs a physical iPhone with a camera.

The PR's manual test (scroll from the live preview, QR image import, torch) is still open.

Not driven: the steps added to contact-request-or-pay.xml, request-summary.xml, usdt-receive-amount-and-units.xml and usdt-send-review-and-details.xml cover the pair PR; this PR changes no iOS code on those paths.

Outside this PR: UsdtActivityRow and the UsdtActivityDetail summary keep one-line rows and the two-column grid, so the USDT activity list still truncates "Received" to "Rec…" at AX5.

Pair PR synonymdev/bitkit-android#1564 shares the journey updates and marks the deposit-history and scanner steps as iOS-only, so there is no Android layout change to match.

Reviewed in full, 73f2bf4 to b3e6025, 11 files. No device case drove the ScannerCamera branch at Bitkit/Components/Scanner.swift:250.

Comment thread Bitkit/Views/Wallets/Activity/ActivityRow.swift

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code scan: no HIGH/MEDIUM. One LOW (journey preconditions) is inline.

Checked and clean:

  • Scanner.swift only changes hit-testing on the placeholder and the ZStack; onScan, parsing and haptics are untouched.
  • The deposit row keeps the masked value in both layouts, and stacking removes the line limit only at accessibility sizes.

Perf: not relevant (AnyLayout switch on dynamicTypeSize only).

The six journey file names and the added action prose match the twin synonymdev/bitkit-android#1564.

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.

Comment thread journeys/payment-requests/request-summary.xml Outdated
@ben-kaufman
ben-kaufman requested a review from jvsena42 October 19, 2026 10:26
@ben-kaufman

Copy link
Copy Markdown
Contributor Author

Applied the matching narrow-card fix from Android #1564 in aff5b7b. Request contacts and amounts remain beside each other when they fit; longer summaries stack so names and localized receipt words remain complete. Checked synthetic USDT/USD/BTC cards at 320pt with normal, XXX Large and accessibility text, plus compact short-status cards. All 2,622 unit tests pass, SwiftFormat is clean across the PR’s Swift diff, and translations report zero errors with the same three keys inherited from #973. The paired journey now specifies the real padded width. All five PR commits are signed and verified locally and on GitHub.

Base automatically changed from fix/usdt-device-feedback-20261016 to master October 19, 2026 18:34

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delta since my last review, edd752a: docs only. My journey thread is fixed. The BTC receipt now rounds to the payer's Payment value, and the 375-pt note is in place.

One LOW is inline (long note stacks the card header), with a failing test.

Device gate (partial): not run yet. Pending: request-summary.xml last action, at 375 pt with enlarged and default text.

Comment thread Bitkit/Views/PaymentRequests/PaymentRequestsView.swift

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ⚠️ Not verified — the live-camera check still needs a test iPhone.

Findings: None. I confirmed the stacked deposit-card width fix at edd752a.

QA for edd752a:

Tested on iPhone SE (3rd generation) simulators, iOS 26.5, 375 pt, dark mode. Recordings play at 2×.

Test 1: deposit history width ✅ Polygon, Tron and BNB Smart Chain cards fill the history width at AX1 and AX5; default text restores compact rows.

Network, status and amount remain readable, including the short Polygon row that previously left unused space on its right.

case1.2x.mp4

Test 2: verified request history ✅ Genuine USD and BTC requests paid in USDT retain complete Polish statuses and exact receipts at AX1 and default text.

The USD request and receipt are both 1.23. The BTC request's receipt is 0,82063 USDT, which rounds to the payer's 0.82 Payment value; its 0.68 fee makes the activity total 1.50. The recording shows both wallets side by side, requester on the left. The short pending card stays horizontal at default text; verified receipts stack when needed.

case2.2x.mp4

Test 3: contact loading and retry ✅ Selection remains on the resolving contact; an endpointless contact shows an error and allows a successful retry with the original contact.

Tapping Empty while Maria is loading leaves Maria selected. After cancelling and reopening Send, Empty shows “Unable To Pay Contact.” Selecting Maria then opens its USDT amount screen. Cancelled without payment.

case4.2x.mp4

Test 4: receive 3.50 precision ✅ The decoded QR and copied/shared URI retain `uint256=3500000`, and sharing identifies Arbitrum One.

Checked the QR with a decoder and compared the copied URI and share-sheet Copy payload through the clipboard. Show Details copies the same wallet address without URI parameters.

case5.2x.mp4

Test 5: live camera and torch ⏭️ Unrun: the available physical iPhone is personal; simulators cannot verify live capture or a physical torch.

A dedicated test iPhone is needed to verify dragging from the live preview, QR photo import and the torch together. The prior simulator result does not prove the live-camera branch.

I carried forward the unchanged deposit-detail AX5 and simulator-preview checks from the prior review.

Coverage: delta b3e6025..edd752a, all eight changed files and their reached code, plus the prior width finding. Device coverage targets the changed journey actions; the Android-only navigation-inset action and documentation prerequisites were reviewed in code.

Twin: synonymdev/bitkit-android#1564 fix: improve usdt payment feedback and layout matches the request-history assertions, with the documented iOS 375 pt / Android 320 dp difference.


Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest

@jvsena42

Copy link
Copy Markdown
Member

Device gate (partial): edd752a, iPhone 17 simulator as requester, synonymdev/bitkit-android#1564 on Android paying in USDT.

request-summary.xml last action, English at default text:

  • "+$3.00 · Payment verified · 3.00 USDT" equals the request amount.
  • "+₿ 3 000 · Payment verified · 2.4603 USDT" rounds to the payer's Payment value of 2.46.
  • Amounts and statuses sit beside the contact.

⚠️ Not evaluated yet:

  • Enlarged Dynamic Type in Polish, and the long-note card. After relaunching the app with new language or text-size arguments (22:04, 22:09, 22:10 UTC), the Payments tab stayed on its empty state ("Brak historii płatności") for over 3 minutes. The Home requests bell (previously "2 pending") was gone, and a new request with a note sent at 22:14:23 didn't appear within 90 s. The same build showed history and requests on its first launch. The log has no errors, only paykit_pending_backup_restore not found every 10 s. Not classified yet: it could be my launch arguments or app state after a relaunch. It needs a clean re-run before I draw any conclusion.
  • The 375-pt check. No 375-pt simulator exists on this Mac.
  • contact-request-or-pay.xml failure/retry.

Observation outside this diff: the Subscriptions tab identifiers are localized (Tab-przegląd / Tab-płatności in Polish), so journeys that tap Tab-overview / Tab-payments break in other locales.

@jvsena42

Copy link
Copy Markdown
Member

Device gate addendum (edd752a):

  • Empty Payments after relaunch: not reproduced in 4 later launches, with and without language arguments, at default and accessibility-large text. History and the requests bell returned about 100 s after a plain launch. The three failing launches are unexplained. Their logs show the same startup sequence but fewer request-refresh reads, so it looks like an intermittent startup refresh stall. Nothing ties it to this diff.
  • request-summary.xml last action, accessibility-large Polish: the contact and every status word are complete, the amount and receipt moved below the contact, and the comma separator is used. Pass.
  • The long-note LOW, on device: with Polish at default text, the pending card shows "Dinner at the Italian place downtown last Friday" in full under the contact, with $1,00 moved to its own line below. That's the stacking the inline comment describes. The fix: stabilize contact selection and amount layouts #1003 build in English truncates the note beside the amount instead.

⚠️ Still not run: contact-request-or-pay.xml failure/retry on iOS, and the 375-pt check (no compact simulator here).

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at edd752a. My journey thread is resolved. One LOW stays open: a long note stacks the pending card header. Fix it here or in a follow-up, your choice, and reply on the thread with which.

Device gate: edd752a — journeys: payment-requests/request-summary.xml last action and payment-requests/contact-request-or-pay.xml pass on the iPhone 17 simulator, with synonymdev/bitkit-android#1564 on Android as the counterparty; perf: not relevant; l10n: Polish checked at accessibility-large.

  • Receipts: "3.00 USDT" for the $3.00 request, and "2.4603 USDT" for the ₿3,000 request, which rounds to the payer's Payment value of 2.46.
  • Layout: at accessibility-large in Polish everything stays complete and wraps below the contact. At default size in English it sits beside the contact.
  • Contact pay: the Pay spinner shows with Request disabled, and the tapped row shows a spinner while the other row is ignored. The endpoint-less contact gives 23:01:04.335 Failed to resolve Paykit contact payment … reason=not_found, then the "Unable To Pay Contact" toast, and both rows are enabled again. Selecting Gate then opens the amount screen (23:05:38.589 Opened private Paykit payment).
  • Step 7 timing: the 3-second target was missed (4–6 s from tap to SendAmount). That time is Paykit resolution against staging, which this PR doesn't touch, and Android shows the same.

⚠️ Not run: the 375-pt layout check. No 375-pt simulator exists here, and the same steps passed at 402 pt.

Observation outside this diff, for a possible follow-up: within one Send sheet, going Back from a contact's amount screen and selecting any contact again resolves (Opened private Paykit payment …) but never navigates. It reproduced 4 times. Closing and reopening Send clears it. SendContactSelectView.openContactPayment returns early on guard app.claimContactPaymentContext(...) with no log, which fits a context still claimed after Back.

CI at edd752a: green apart from e2e-tests-local, which was still running; check it before merge.

@ben-kaufman

Copy link
Copy Markdown
Contributor Author

The long-note layout is already deferred to #1030 (3.1.0), now clarified on its thread. I also verified the Back/reselect context gap in current master and tracked it separately in #1034 with the ownership and regression-test requirements; it is outside this accessibility diff. Android does not use the same claim guard. Both follow-ups are linked under Out of Scope.

@ovitrif ovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utAck

@ovitrif
ovitrif merged commit 1766079 into master Oct 20, 2026
20 checks passed
@ovitrif

ovitrif commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

Merged, as it was approved and green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

usdt deposit history and details break at accessibility text sizes

4 participants