fix(chat): nest the reply quote concentrically in its bubble - #1433
Merged
Conversation
The citation panel inside a reply drew an 8dp corner inside the bubble's 12, with a 16dp gap down its sides, 10 at the top and 6 under it. Four numbers, none derived from the others, so neither arc ran parallel to the other and there were three different gaps to read the panel against. Derive the panel from the bubble instead. `BubbleDefaults` names the bubble's own geometry, and `surroundInset` is one gap used on the panel's top, leading and trailing edges and again between the panel and the body beneath it, so the corner has a single surround to be concentric with: the bubble's radius less that gap. The bubble hands a reply the surround as its horizontal padding and the body puts the difference back, which is how the panel reaches past the text on both sides. A bubble with no quote passes the bubble's own padding, so the difference is zero and nothing about it moves. The panel also stretches to the bubble's width when it is the narrower of the two. A `Column` left a short quote hanging inside a wider reply, and the panel is a filled surface, so the slack read as a notch cut out of the bubble. `fillMaxWidth` fills the incoming maximum rather than the sibling's width, so `QuotedBody` measures the body first and makes its width the panel's floor. A quote longer than the reply still keeps its own width and carries it out to the bubble. Every measurement that has a token now reads one. `CodeTheme.shapes.medium` and `.tiny` supply the bubble's two radii through a new `CornerBasedShape.cornerRadius()`, and the paddings come off `CodeTheme.dimens.staticGrid`. That grid is 5pt and has no 16dp step, so the bubble's horizontal padding moves to 15. The panel's accent width, flag size and alphas stay as literals; they came from iOS and have no token to come from. iOS landed the same surround in code-payments/code-ios-app#735. One difference is deliberate: the radius is floored at the bubble's flattened corner, because iOS's unfloored 3pt is a continuous curve and the same number as a circular arc draws a hard rectangle inside a rounded one.
bmc08gt
force-pushed
the
fix/reply-quote-corners-spacing
branch
from
September 8, 2026 19:19
377aa0f to
1a14ff2
Compare
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 citation panel inside a reply drew an 8dp corner inside the bubble's 12, with a 16dp gap down its sides, 10 at the top and 6 under it. Four numbers, none derived from the others, so neither arc ran parallel to the other and there were three different gaps to read the panel against.
The surround
BubbleDefaultsnames the bubble's own geometry, andsurroundInsetis one gap used on the panel's top, leading and trailing edges and again between the panel and the body beneath it. The corner then has a single surround to be concentric with: the bubble's radius less that gap.The bubble hands a reply the surround as its horizontal padding and the body puts the difference back, which is how the panel reaches past the text on both sides. A bubble with no quote passes the bubble's own padding, so the difference is zero and nothing about it moves.
Matching the widths
The panel stretches to the bubble's width when it is the narrower of the two. A
Columnleft a short quote hanging inside a wider reply, and the panel is a filled surface, so the slack read as a notch cut out of the bubble.fillMaxWidthis no help: it fills the incoming maximum, not the sibling's width, so every reply would square off against the widest bubble the transcript allows.QuotedBodymeasures the body first and makes its width the panel's floor instead. A quote longer than the reply keeps its own width and carries it out to the bubble, which is what makes this a floor rather than a fixed width. A bubble with no quote never reaches the layout at all, so short messages keep hugging their text.Tokens
Every measurement that has a token now reads one.
CodeTheme.shapes.mediumand.tinysupply the bubble's two radii through a newCornerBasedShape.cornerRadius(), and the paddings come offCodeTheme.dimens.staticGrid.That grid is 5pt and has no 16dp step, so the bubble's horizontal padding moves from 16dp to 15dp — a 1dp change to every bubble in the transcript, not just replies. Say the word and I will keep 16dp as an off-grid literal instead.
The panel's accent width, flag size and alphas stay as literals. They came from iOS and have no token to come from.
Against iOS
iOS landed the same surround in code-payments/code-ios-app#735. One difference here is deliberate: the radius is floored at the bubble's flattened corner. iOS takes 12 − 9 = 3 straight, but that is a
.continuouscurve; the same number as Compose's circular arc draws a hard rectangle inside a rounded one.The other two commits squashed into that PR fix a recycled bubble keeping a stale quote width and a 42pt width floor on quote-less bubbles. Both are UIKit constraint and reuse bugs with no equivalent here, since the panel is not composed at all when there is no quote.