From ec28d63656f370a8697c1eeceee82c94593f0929 Mon Sep 17 00:00:00 2001 From: OneWay Date: Wed, 23 Sep 2026 10:30:00 +0800 Subject: [PATCH] fix(ui): remap dark article colors in dark theme Colors set by dictionaries such as navy, dark red and brown are nearly invisible on the dark background. Swap the dark named colors for lighter tones when rendering in the dark theme; the light theme keeps the original colors. --- .../research/ui/article/ArticleScreen.kt | 15 ++++++++-- .../research/ui/article/DslAnnotatedParser.kt | 29 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/example/research/ui/article/ArticleScreen.kt b/app/src/main/java/com/example/research/ui/article/ArticleScreen.kt index ae89818..401ce21 100644 --- a/app/src/main/java/com/example/research/ui/article/ArticleScreen.kt +++ b/app/src/main/java/com/example/research/ui/article/ArticleScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.luminance import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag @@ -197,12 +198,22 @@ fun ArticleContent( articleState.dslContent.size > HEAVY_ARTICLE_BLOCK_COUNT val density = LocalDensity.current + val darkTheme = MaterialTheme.colorScheme.background.luminance() < 0.5f val displayBlocks = remember( articleState.dslContent, density, - baseTextStyle + baseTextStyle, + darkTheme ) { - mergeDslBlocks(articleState.dslContent, density, baseTextStyle) + val merged = + mergeDslBlocks(articleState.dslContent, density, baseTextStyle) + if (darkTheme) { + merged.map { + it.copy(text = DslAnnotatedParser.remapForDarkTheme(it.text)) + } + } else { + merged + } } val articleList: @Composable (Modifier) -> Unit = { listModifier -> LazyColumn( diff --git a/app/src/main/java/com/example/research/ui/article/DslAnnotatedParser.kt b/app/src/main/java/com/example/research/ui/article/DslAnnotatedParser.kt index 13f6159..1227370 100644 --- a/app/src/main/java/com/example/research/ui/article/DslAnnotatedParser.kt +++ b/app/src/main/java/com/example/research/ui/article/DslAnnotatedParser.kt @@ -411,6 +411,35 @@ object DslAnnotatedParser { linkText = Color(0xFF1E88E5), ) + private val DARK_THEME_COLORS: Map = mapOf( + Color(0xFF000000) to Color(0xFFE8E6E3), + Color(0xFF000080) to Color(0xFF8FA8E0), + Color(0xFF00008B) to Color(0xFF8FA8E0), + Color(0xFF0000FF) to Color(0xFF7C9CE8), + Color(0xFF006400) to Color(0xFF66BB6A), + Color(0xFF008000) to Color(0xFF66BB6A), + Color(0xFF8B0000) to Color(0xFFE57373), + Color(0xFF800000) to Color(0xFFE57373), + Color(0xFF800080) to Color(0xFFBA68C8), + Color(0xFFA52A2A) to Color(0xFFBCAAA4), + Color(0xFF008080) to Color(0xFF4DB6AC), + Color(0xFF808000) to Color(0xFFC0CA33), + ) + + fun remapForDarkTheme(text: AnnotatedString): AnnotatedString { + if (text.spanStyles.none { it.item.color in DARK_THEME_COLORS }) return text + val builder = AnnotatedString.Builder(text.text) + text.spanStyles.forEach { range -> + val style = DARK_THEME_COLORS[range.item.color] + ?.let { range.item.copy(color = it) } ?: range.item + builder.addStyle(style, range.start, range.end) + } + text.paragraphStyles.forEach { range -> + builder.addStyle(range.item, range.start, range.end) + } + return builder.toAnnotatedString() + } + // Allow external cache clearing (e.g., when dictionaries change) fun clearRefCache() { refCache.evictAll()