feat: register-style fiat input on the zap dialog#519
Merged
Conversation
…wording
Mirrors the iOS work (barrydeen/wisp-ios): the zap dialog's custom
amount input is fiat-aware and uses register-style entry — the user
types digits, they fill from the cents place ('21' -> $0.21,
'2100' -> $21.00), and the field renders the formatted dollar string
with the configured currency's symbol.
Implementation notes:
* Field is bound to the raw digit string and a [VisualTransformation]
renders the formatted dollar view. Compose's cursor lives in raw-
string coordinates and the OffsetMapping pegs the cursor to the end
of the formatted view, so backspace removes the rightmost digit
cleanly. The earlier String-only attempt — binding the field to the
formatted string and re-formatting in onValueChange — broke
backspace on Android: when Compose's internal text changed from
'$0.2' to our re-formatted '$0.02', it couldn't map the old cursor
position into the new string and snapped it to the start, so
subsequent backspaces just moved the cursor instead of deleting.
* New ExchangeRateRepository.fiatToSats(majorAmount, currency) — the
inverse of satsToFiat — converts the typed (cents / 100) dollar
amount through the cached BTC-to-fiat rate.
* AmountFormatter.renderCurrency drops trailing zeros for sub-dollar
amounts ('$0.84' instead of '$0.840', '$0.8' instead of
'$0.800') by switching the DecimalFormat patterns to '#' optional
digits past the decimal. Whole-dollar amounts still pad to two
places ('$1.00') matching retail convention.
* zap_x_amount string flips from 'Zap %1$s' to 'Send %1$s' so the
Send button reads 'Send $X.XX' in fiat mode (was 'Zap $X.XX').
* LiveStreamScreen's zap button reads 'Send' / 'Sending...' in fiat
mode, 'Zap' / 'Zapping...' otherwise — matches the surrounding
wallet UX.
Companion to the iOS PR for the same UX (cross-linked at filing time).
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Mirrors the iOS PR (barrydeen/wisp-ios#82). Custom-amount input on the zap dialog is fiat-aware. In fiat mode the user types digits register-style — they fill from the cents place, so
21reads as$0.21and2100reads as$21.00. The hero amount, custom input, and Send button all show the formatted dollar string with the configured currency's symbol. The Send-button label is "Send $X.XX" (was "Zap $X.XX") and the in-progress label on the live-stream zap button is "Sending…" / "Send" instead of "Zapping…" / "Zap" when fiat mode is on. Sub-dollar fiat amounts across the app drop trailing zeros ($0.84instead of$0.840,$0.8instead of$0.800).Implementation notes
VisualTransformationfor the live cursor: the field is bound to the raw digit string ("21") and aCentsVisualTransformationrenders the formatted dollar view ($0.21). Compose's cursor lives in raw-string coordinates and theOffsetMappingpegs it to the end of the formatted view, so backspace removes the rightmost digit cleanly. The earlier String-only attempt — bind the field to the formatted string and re-format inonValueChange— broke backspace on Android: when Compose's internal text changed from$0.2to our re-formatted$0.02, it couldn't map the old cursor position into the new string and snapped it to the start, so subsequent backspaces just moved the cursor instead of deleting.ExchangeRateRepository.fiatToSats(majorAmount, currency)— inverse ofsatsToFiat. Used at the input boundary to convert(cents / 100)dollars → sats via the cached BTC-to-fiat rate.AmountFormatter.renderCurrencypatterns switch to#(optional) past the decimal for sub-dollar tiers so trailing zeros drop. Whole-dollar amounts still pad to two places ($1.00) matching retail convention.zap_x_amountstring changes from"Zap %1\$s"to"Send %1\$s"(English only — other locales fall back to English; this string isn't translated yet).Files
app/src/main/kotlin/com/wisp/app/repo/ExchangeRateRepository.ktapp/src/main/kotlin/com/wisp/app/ui/component/ZapDialog.ktapp/src/main/kotlin/com/wisp/app/ui/screen/LiveStreamScreen.ktapp/src/main/kotlin/com/wisp/app/ui/util/AmountFormatter.ktapp/src/main/res/values/strings.xmlTest plan
21→ field reads$0.21, hero matches, Send button readsSend $0.21.2100→ field reads$21.00. Backspace →$2.10→$0.21. Cursor stays at the end; backspace removes the rightmost digit (no cursor-stuck-left-of-symbol bug).Send/Sending…/Sent!(wasZap/Zapping…/Sent!). Toggle fiat mode off — wording reverts.$0.84(not$0.840); whole-dollar values still render as$1.00.Zap N sats, no behavioural change.