From 7f48b1831978192b3c5f7f26e590a726a770e98a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 27 Apr 2026 19:54:45 +0000 Subject: [PATCH] fix(nests): wrap NestThemedScope in Surface so LocalContentColor flips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NestThemedScope painted `themed.background` on a plain Box. Compose's `LocalContentColor` was never updated, so it stayed at its CompositionLocal default — `Color.Black` — for every Text inside. On the user's dark theme that meant black-on-black for the room title and the chat panel: unreadable. AmethystTheme installs `MaterialTheme(colorScheme = ...)` but does NOT wrap content in a Surface; screens that use Scaffold inherit LocalContentColor via Scaffold's internal Surface. NestFullScreen goes Column → verticalScroll, no Scaffold, no Surface, so the black-default fell through. Replace the bare `Box.background(themed.background)` with a Material Surface that paints `color = themed.background` AND provides `contentColor = themed.onBackground` to LocalContentColor for the inner subtree. The `bg` image still overlays the Surface inside the Box, exactly as before. This was the actual cause of the user's "title impossible to read / chat super dark" report — the event in question shipped no `c` tags (only the unparseable `["color", "gradient-7"]`), so RoomTheme was already Empty. The previous "all-or-nothing palette" gate (commit 15169de7) is still right for half-applied palettes; this Surface fix is what makes empty / un-themed rooms read correctly on dark. https://claude.ai/code/session_01RDpuki4t8StSg1CZcXnV5b --- .../loggedIn/nests/room/NestThemedScope.kt | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/NestThemedScope.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/NestThemedScope.kt index e4744ae91..9d16c4095 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/NestThemedScope.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/NestThemedScope.kt @@ -24,6 +24,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.Typography import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -106,32 +107,44 @@ internal fun NestThemedScope( } MaterialTheme(colorScheme = themed, typography = themedTypography) { - // Paint the themed background COLOR on the Box itself so a room - // that ships `["c", hex, "background"]` but no `bg` image still - // visibly tints the room screen — without this, only consumers - // that explicitly read `MaterialTheme.colorScheme.background` - // would pick the override up, and the room would visually fall - // back to the platform surface. The `bg` image, when present, - // paints on top per EGG-10 rule 3 ("image overlays the color"); - // a partially-transparent image lets the color show through. - Box(modifier = Modifier.fillMaxSize().background(themed.background)) { - theme.backgroundImageUrl?.let { url -> - when (theme.backgroundMode) { - RoomTheme.BackgroundMode.COVER -> { - AsyncImage( - model = url, - contentDescription = null, - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop, - ) - } + // Wrap in a Surface so LocalContentColor flips to + // `themed.onBackground` for everything inside content(). + // Without this, default Text() composables fall through to + // CompositionLocal's default `Color.Black` and become + // unreadable on dark theme — AmethystTheme installs + // MaterialTheme but doesn't itself wrap in a Surface, so any + // screen that doesn't use Scaffold inherits that default. + // + // Surface also paints the background color, which preserves + // the previous behavior (a room with `["c", hex, "background"]` + // visibly tints the screen). The `bg` image, when present, + // paints on top of Surface per EGG-10 rule 3 ("image overlays + // the color"); a partially-transparent image lets the color + // show through. + Surface( + modifier = Modifier.fillMaxSize(), + color = themed.background, + contentColor = themed.onBackground, + ) { + Box(modifier = Modifier.fillMaxSize()) { + theme.backgroundImageUrl?.let { url -> + when (theme.backgroundMode) { + RoomTheme.BackgroundMode.COVER -> { + AsyncImage( + model = url, + contentDescription = null, + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop, + ) + } - RoomTheme.BackgroundMode.TILE -> { - TiledRoomBackground(url = url) + RoomTheme.BackgroundMode.TILE -> { + TiledRoomBackground(url = url) + } } } + content() } - content() } } }