Add "Petal" and "Mint" chat colors, and generalize outgoing text/icon contrast to work with any light chat color - #14910
Add "Petal" and "Mint" chat colors, and generalize outgoing text/icon contrast to work with any light chat color#14910br4yd wants to merge 11 commits into
Conversation
… button The needsDarkText() fallback introduced for the Petal chat color missed two spots: the document/file attachment view's filename and size text (colors were baked into layout XML, not recomputed per recipient), and the confirm (checkmark) button shown when adding a caption to media before sending.
Outgoing polls used the same fixed white/near-white color resources regardless of chat color, so options, vote counts, checkboxes, and progress fill stayed unreadable on the light Petal chat color.
Outgoing audio bubbles always used the same fixed foreground tint (duration text, seek bar, play icon), so voice messages stayed unreadable on the light Petal chat color.
…atus The waveform bar/thumb colors on outgoing audio bubbles were baked into static XML attributes and never updated for the dark-text case, so only the play button and seek thumb (previously fixed) turned black while the waveform itself stayed white. Stickers use a separate footer view (no bubble background) that is colored in setFooter(), which runs after setBubbleState() and was unconditionally overwriting the dark-text color back to white whenever a wallpaper was set.
The button label reused the chat color itself as its text color, which is illegible on the light Petal background since the label sits on a near-white pill.
The per-photo selection number badge and the gallery's send/count button only tinted their background with the chat color, leaving their text a fixed light color that disappears against the light Petal background.
The confirm checkmark's background was tinted with the chat color, but its icon tint was hardcoded white in the layout.
|
While using the app with this color I found some other places where it used the wrong contrast and still used white as the text color or icon color for buttons that send/confirm things. The last commits are fixing this. |
needsDarkText() only matched Petal's exact color, so any future light chat color would silently render with the wrong (light) text/icons everywhere that already checks this flag.
|
While testing Petal I found several more spots that still hardcoded white instead of relying on That made something clear: I replaced that equality check with a relative-luminance threshold ( Concretely, adding another light preset later i.e. a pastel mint green would only need: // ChatColorsPalette.kt
val MINT = ChatColors.forColor(ChatColors.Id.BuiltIn, 0xFFC8F0C0.toInt())
// ...added to the `solids` listplus the usual proto enum value and |
Demonstrates that adding a light preset now only takes a palette entry plus the usual proto/backup mapping, with no changes needed anywhere text/icons are drawn on a chat color, since needsDarkText() is luminance-based rather than Petal-specific.
|
I also added a second light preset, "Mint" (#C8F0C0). Partly because it turned out to look genuinely good in the UI, and partly as a proof of concept for the luminance-based contrast fix from the previous commit. The whole addition is a single commit (1820072): one palette entry, one proto enum value ( That's the concrete payoff of moving If this gets merged I also plan to improve the color picker in the chat design settings to allow using custom chat colors that are lighter making use of the luminance-based contrast check. |
First time contributor checklist
Contributor checklist
Fixes #1234syntaxDescription
A friend of mine asked for this specific pink as a chat color - she uses it on other messengers. Signal's custom color picker can't produce it because it deliberately keeps colors dark enough to guarantee contrast with the white outgoing-bubble text.
This adds Petal (#FCCDD9) as the first light preset in ChatColorsPalette. Since the existing text/icon colors assume a dark bubble, I added ChatColors.needsDarkText(), which switches outgoing body text, footer text/icons, and confirm/send button tints to black wherever the bubble color needs it.
Edit (2026-08-04): needsDarkText() originally only special-cased Petal's exact color. Based on feedback while testing, I generalized it to a relative-luminance check instead. See the commit "Generalize dark-text detection to luminance instead of a specific color" and the comment below. Any future light preset now gets correct contrast automatically, without touching the ~10 places that already call needsDarkText(). I also added "Mint" (#C8F0C0) as a second light preset in a single, self-contained commit to demonstrate exactly what that takes going forward.
I also added SOLID_PETAL = 23 to ChatStyle.BubbleColorPreset in lib/archive/src/main/protowire/Backup.proto so the color round-trips through backup/restore, with a fallback to ULTRAMARINE for unrecognized values on import.
Note for maintainers: Backup.proto is a cross-platform backup format. Each client (Android, iOS, Desktop) maintains its own copy of it rather than a shared source of truth. I checked both the Signal-iOS and Signal-Desktop repos directly: