Skip to content

feat(chat): one cash bubble layout for DMs and group sends - #1944

Merged
bmc08gt merged 5 commits into
code/cashfrom
feat/standard-cash-bubbles
Nov 3, 2026
Merged

bmc08gt merged 5 commits into
code/cashfrom
feat/standard-cash-bubbles

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Cash bubbles in DMs and group chats now share one layout, per docs/specs/cash-bubbles.md in the orchestrator (design section node 13266:348). Top to bottom: caption, amount, total (group sends to two or more only), token, then "to A" or "from A".

Viewer Send to 2+ Send to 1 / DM
Sender You sent / $X each / $Y total / to A and N others You sent / $X / to A
Recipient You and N others received / $X each / $Y total / from Sender You received / $X / from Sender (or the DM's other member)
Member not paid Sender sent / $X each / $Y total / to A and N others Sender sent / $X / to A
  • A is the first recipient in selection order. Before, the foot line put "You" first when the viewer was paid.
  • " each" sits on the amount line at 0.5.em in the secondary color, in Avenir Next Medium (the caption's family). The amount's family maps Medium to Demi on Android, so " each" can't take Medium from it. In em, the auto-size shrinks it along with the amount.
  • When the parts in multi_receiver differ, as in sends from before every recipient got the same amount, every viewer (sender, recipient, member not paid) sees "~$X each" for the smallest part, e.g. "You and 2 others received / $0.33 each / $1.00 total". The "" draws at 0.7.em in the amount's weight and color, on its baseline. Equal parts keep "$X each". The parts decide it per message, not the date.
  • The total sits right under the amount, and the currency row sits grid.x3 below the money, with or without a total. Before, amount, total and currency were all grid.x1 apart.
  • A group send to one person draws the DM layout but still opens the group send details on tap.
  • DM bubbles name the other member. That name enters the transcript pipeline through ChatFacts, so the line updates when the profile resolves.
  • Sent tips stay "You tipped"; received tips read "You received".
  • An unresolved name reads "Someone", including a group sender with neither a name nor a handle, who other rows still call "Flipcash User". An unresolved lead recipient in a send to two or more keeps "to N people". While the chat type is unknown, the bubble shows its caption only.
  • GroupSendBubble is folded into CashBubble; the duplicate label_groupBubbleEach is removed.

The line logic is a plain function, CashBubbleLines.kt in chat-ui, with tests against the real strings for every case above. CashBubbleScreenshotTest renders all ten frames, plus the three uneven-parts viewers, to build/screenshots/cash_bubbles.png.

Every cash bubble now reads, top to bottom: caption, amount, total (group
sends to two or more only), token, then "to A" or "from A". A group send to
two or more shows "$X each" as the large line with "$Y total" under it; the
"~$X each" form is gone. A group send to one person draws the DM layout but
still opens the group send details on tap.

Captions and foot lines by viewer:
- sender: "You sent" / "to A and N others"
- recipient: "You and N others received" / "from <Sender>"
- member not paid: "<Sender> sent" / "to A and N others"
- DM: "You sent" / "to A", "You received" / "from A"

A is the first recipient in the order the sender picked, no longer "You"
when the viewer was paid. A DM bubble names the other member, which enters
the transcript pipeline through ChatFacts so the line updates when the
profile resolves. An unresolved name reads "Someone"; an unresolved lead
recipient in a send to two or more keeps "to N people".

The line logic is a plain function in chat-ui (CashBubbleLines.kt), tested
against the real strings. CashBubbleScreenshotTest renders all ten frames
of the design (section node 13266:348) to build/screenshots.
@bmc08gt bmc08gt self-assigned this Nov 3, 2026
@github-actions github-actions Bot added the type: feature New functionality label Nov 3, 2026
A group send whose parts in multi_receiver differ, as sends from before
every recipient got the same amount do, now reads by viewer: a recipient
sees their own part with no "each" ("$0.34 / $1.00 total"), and the
sender and members not paid see "~$X each" for the smallest part. The
"~" takes the amount's style; only " each" is lighter. Equal parts keep
"$X each". The parts decide it, not the message's date.

The amount line is CashBubbleLines.amountLine, tested for each viewer
with uneven parts and for equal parts against the real strings, and the
screenshot test renders the three uneven cases.

Two view model tests check that a group sender or DM member whose profile
has neither a name nor a handle reaches the bubble as null, which reads
"Someone", rather than the "Flipcash User" other rows use.
The total sits right under the amount, the tightest pair of lines in the
bubble, and the currency row sits grid.x3 below the money, more than the
amount-to-total gap and less than the grid.x4 above the amount and below
the currency. A bubble with no total uses the same grid.x3 between the
amount and the currency. Before, all three lines were grid.x1 apart, so
the total sat as far from the amount as from the currency.
A recipient of a send whose parts differ now reads "~$X each" for the
smallest part like the sender and members not paid, instead of their own
part. CashAmountLine.Own and amountLine's viewerPart are gone.

The "~" draws at 0.7.em in the amount's weight and color, on its
baseline, so the auto-size shrinks it with the amount. " each" is now
Medium weight; its size (0.5.em) and secondary color are unchanged.
The amount's Avenir family maps FontWeight.Medium to avenir_next_demi on
Android, so " each" at Medium rendered in the amount's own Demi face and
looked heavier than on iOS. The span now takes the caption's family,
whose Medium is avenir_next_medium. Weight, 0.5.em and the secondary
color are unchanged; the "~" stays in the amount's style.

The builder moves to eachAmountText in CashBubbleLines.kt, and a test
pins the " each" span to the avenir_next_medium resource at Medium.
@bmc08gt
bmc08gt merged commit d5f4841 into code/cash Nov 3, 2026
4 of 5 checks passed
bmc08gt added a commit that referenced this pull request Nov 3, 2026
Cash bubble layout (#1944) and the system-message glyph change (#1937) are
taken as code/cash has them, then moved onto the KMP source sets:
CashBubbleLines resolves its wording through Res (composable stringResource,
or blocking lookups passed in by a test) and sits in commonMain.

code/cash's selectBuildTypeFrom made jvmMainCompileClasspath ambiguous for
libraries that publish android and jvm variants, which broke
:apps:flipcash:core:compileJvmMainJava and so the desktop build and jvmTest.
Both KMP convention plugins now ask that classpath for the jvm platform type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant