Skip to content

fix(chat): match Android's three-tier gap between bubbles - #737

Merged
bmc08gt merged 1 commit into
mainfrom
fix/chat-bubble-spacing
Sep 8, 2026
Merged

fix(chat): match Android's three-tier gap between bubbles#737
bmc08gt merged 1 commit into
mainfrom
fix/chat-bubble-spacing

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

The transcript ran one gap for every pairing — 8 points, plus 6 where the sender flipped. Android picks from three in bottomSpacingFor: grid.x1 inside a same-sender run, grid.x2 where the grouping window has broken or a date separator sits, grid.x3 on a change of speaker. On a normal-width phone those are 5, 10 and 15, so a thread read at a different density on each platform.

Pairing Was Now
Same sender, grouped 8 5
Same sender, grouping window broken 8 10
Either side of a date separator 8 10
Change of speaker 14 15

The three tiers land as RowGap, and interItemSpacing(_:after:) now answers in Android's order — separators before senders. iOS already computes isContinuedByNext the way Android computes groupedBelow (same sender, inside the grouping window), so the tight tier needs no grouping pass of its own. senderFlipExtraSpacing is gone: the wide gap is a value now rather than a delta on the base.

One deliberate divergence: the profile card has no sender, so it keeps the base gap of 10 rather than the tight one Android hands a non-bubble neighbour. Android has no profile card to match.

The transcript ran one gap for every pairing — 8 points, plus 6 where the sender
flipped. Android picks from three in `bottomSpacingFor`: `grid.x1` inside a
same-sender run, `grid.x2` where the grouping window has broken or a date
separator sits, `grid.x3` on a change of speaker. On a normal-width phone those
are 5, 10 and 15, so a thread read at a different density on each platform.

Port the three tiers as `RowGap` and answer `interItemSpacing(_:after:)` in
Android's order, separators before senders. iOS already computes
`isContinuedByNext` the way Android computes `groupedBelow` — same sender, inside
the grouping window — so the tight tier needs no grouping pass of its own.

The profile card has no sender, so it keeps the base gap rather than the tight
one Android hands a non-bubble neighbour; Android has no profile card to match.
@bmc08gt bmc08gt self-assigned this Sep 8, 2026
@bmc08gt
bmc08gt merged commit 11e0c4b into main Sep 8, 2026
1 check passed
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.

1 participant