From 98ec38f2724c11e8cbced77611783514c82c6370 Mon Sep 17 00:00:00 2001 From: OneWay Date: Thu, 24 Sep 2026 09:00: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 b91f4fe..22be825 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.testTag import androidx.compose.ui.res.painterResource @@ -178,11 +179,21 @@ fun ArticleContent( val isHeavyArticle = articleState.dslContent.size > HEAVY_ARTICLE_BLOCK_COUNT + val darkTheme = MaterialTheme.colorScheme.background.luminance() < 0.5f val displayBlocks = remember( articleState.dslContent, - baseTextStyle + baseTextStyle, + darkTheme ) { - mergeDslBlocks(articleState.dslContent) + val merged = + mergeDslBlocks(articleState.dslContent) + 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()