Repository navigation
feat(chat): send back a DM's opening payment - #1954
Merged
Merged
Conversation
The receiver of an offered cash message gets a Send Back row under the bubble. One GetCashMessageReturnStatus call per DM open decides whether it shows; a return in the transcript marks the original Sent Back for both people without a call. Tapping checks the token-quark balance at today's rate, then opens a confirm sheet or the existing insufficient-balance modal. The swipe pays the original's fiat amount back under the server's payment_intent_id with ReturnPayment metadata. The id stays in memory, is held in LiveSecrets, and is only logged masked.
A returned payment reads "Sent back to <Name>" or "<Name> sent back" and opens the DM it was paid in. The DM is checked first, so a chat the server no longer has opens the row's details instead of an empty chat.
SendBackPaymentDelegate.pay read the rate again and re-priced the return, so the token amount it sent could differ from the one the swipe's balance check approved. It also priced through SharedStatePayment.price, which caps at the balance, while the check priced uncapped. pay now takes the VerifiedFiat from the swipe's check and sends it as is.
Per the Send Back spec's sizes: the Available/Sending row drops from grid.x12 to grid.x11. The Sent Back footer is a grid.x9 band centred along the bubble's bottom edge, in place of the bubble's bottom padding, instead of a caption 16 below the last line inside it.
A tap or swipe with no fresh rate, or before the quark balance has loaded, now shows "Rate Unavailable" instead of "Couldn't Send Back", which stays for a failed submit. These taps reach neither the sheet nor the insufficient-balance modal, so they no longer send Send Back: Tapped. The balance check compares quarks only. The fiat comparison it fell back to before the balance loaded could pass a balance just short of the return, so that case now counts as undetermined.
bmc08gt
force-pushed
the
feat/chat-send-back
branch
from
November 4, 2026 19:08
52a7cac to
73a7251
Compare
The Sent Back footer now has a full-width hairline along its top edge, per the spec change in flipcash-client-orchestrator #115. It is the app's standard section divider, HorizontalDivider in CodeTheme.colors.divider at CodeTheme.dimens.border, as in GroupInviteSheet and CurrencySendScreen. A return bubble's receiver now reads "to You". label_cashToYou ("to you") came in with this branch and only return bubbles used it, so it is replaced by label_cashReturnToYou rather than left unused. SendBackBubbleScreenshotTest checks that only the two Sent Back frames draw the divider and that the return's receiver reads "to You", and renders the Send Back frames to build/screenshots/send_back_bubbles.png.
The footer replaced the bottom padding, so the divider sat 1-2dp under the last line. It now sits below the padding like the Send Back row, with the same modifier the Available and Sending states use (insetH/insetV plus staticGrid.x1), per the spec change in flipcash-client-orchestrator #115. SendBackBubbleScreenshotTest checks that the gap above the divider matches the gap above the Send Back row, that the band is grid.x9, and that a Sent Back bubble is a bare bubble plus the hairline and band.
bmc08gt
marked this pull request as ready for review
November 4, 2026 20:40
The return state can load after the transcript draws. The bubble then drew bare and jumped taller in one frame when the Send Back row or Sent Back footer landed (on a Pixel 7a, 345px to 466px; the width stayed 623px). The footer now sits in an AnimatedVisibility on ChatAnimations.receiptEnter, the transcript's reflow spring. A footer known when the bubble first composes starts visible and draws with no animation. SendBackBubbleScreenshotTest adds a width check for the row and footer, a mid-animation height check for each late arrival, and a first-frame check for a footer known up front.
A cash bubble that had already drawn jumped when its counterpart line and token icon arrived (345 to 403px in one frame on a Pixel 7a), and when a Send Back row gave way to Sent Back after a return. The content column now runs animateContentSize on ChatAnimations' reflow spring, so any late line moves the height. The first measure is taken as is, so state known at first draw is there at full height. The footer no longer expands itself, which would have animated its height twice; it fades in on the reflow spring when it arrives or changes late. The bubble's inset moves inside the animated column in every state, so a row arriving adds only its own height instead of dipping the bubble first. New tests in SendBackBubbleScreenshotTest for a late counterpart line and for the row-to-Sent Back swap failed before this change: the height was already at its final value (153.5dp and 199.5dp) mid-animation.
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.
The person who receives a DM's opening payment can now return it from the chat. The cash bubble gets a Send Back row; tapping it opens a confirm sheet, and a swipe pays the same token and quark amount back to the sender. Spec: code-payments/flipcash-client-orchestrator#111 (
send-back.md). The iOS side is code-payments/code-ios-app#1220.Chat (
messenger,chat-ui,payments)grid.x11). Once returned, the bubble shows a Sent Back footer (36 tall,grid.x9) in place of its bottom padding. The row appears without animation.SendBackFlowprices the return once on tap and once on swipe, and the swipe pays the amount its own check priced.SendBackPaymentDelegate.paytakes that amount and doesn't re-price it.Send Back: Tapped. "Couldn't Send Back" is only for a failed submit.Activity (
transaction-history,balance)ChatCoordinator.hydrateChat. If the DM is gone or can't be loaded, the details screen opens instead. These are the first activity rows that open a chat.Analytics events came in with #1952.