From b6d4fd3cb206f28930f2d6facfc643dfb2f332ec Mon Sep 17 00:00:00 2001 From: avi Date: Thu, 17 Sep 2026 21:25:20 -0500 Subject: [PATCH] Theme + accent settings now apply live (were decorative: ShonarTheme ignored them) --- .../src/main/java/com/shonar/MainActivity.kt | 2 +- .../main/java/com/shonar/ui/theme/Theme.kt | 63 ++++++++++++++----- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/android/app/src/main/java/com/shonar/MainActivity.kt b/android/app/src/main/java/com/shonar/MainActivity.kt index 92b6891..7d81cc4 100644 --- a/android/app/src/main/java/com/shonar/MainActivity.kt +++ b/android/app/src/main/java/com/shonar/MainActivity.kt @@ -49,7 +49,7 @@ class MainActivity : ComponentActivity() { } routeIntent(intent) setContent { - ShonarTheme { + ShonarTheme(settingsManager = (application as com.shonar.ShonarApplication).settingsManager) { val nav = rememberNavController() Surface( modifier = Modifier.fillMaxSize(), diff --git a/android/app/src/main/java/com/shonar/ui/theme/Theme.kt b/android/app/src/main/java/com/shonar/ui/theme/Theme.kt index 4ceeefc..654405f 100644 --- a/android/app/src/main/java/com/shonar/ui/theme/Theme.kt +++ b/android/app/src/main/java/com/shonar/ui/theme/Theme.kt @@ -5,7 +5,15 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.luminance +import com.shonar.settings.SettingsManager // SHONAR palette — deep-sea sonar: dark navy + teal ping. private val Teal = Color(0xFF4FD1C5) @@ -14,29 +22,50 @@ private val DeepNavy = Color(0xFF0B1220) private val NavySurface = Color(0xFF121C2E) private val Ink = Color(0xFF10141A) -private val DarkScheme = darkColorScheme( - primary = Teal, - onPrimary = Ink, - secondary = TealDark, - background = DeepNavy, - surface = NavySurface, - onBackground = Color(0xFFE6EDF3), - onSurface = Color(0xFFE6EDF3), -) - -private val LightScheme = lightColorScheme( - primary = TealDark, - onPrimary = Color.White, - secondary = Teal, -) +private fun schemeFor(accent: Color, dark: Boolean) = if (dark) { + darkColorScheme( + primary = accent, + onPrimary = if (accent.luminance() > 0.4) Ink else Color.White, + secondary = accent.copy(alpha = 0.8f), + background = DeepNavy, + surface = NavySurface, + onBackground = Color(0xFFE6EDF3), + onSurface = Color(0xFFE6EDF3), + ) +} else { + lightColorScheme( + primary = accent, + onPrimary = if (accent.luminance() > 0.4) Ink else Color.White, + secondary = accent.copy(alpha = 0.8f), + ) +} +/** + * Live appearance: reads theme_mode + accent_color and recomposes whenever + * either changes (SettingsManager.valuesChanged bumps on every setValue). + * "System" defers to isSystemInDarkTheme(). Both settings used to be + * decorative — MainActivity called ShonarTheme() with no arguments. + */ @Composable fun ShonarTheme( - darkTheme: Boolean = isSystemInDarkTheme(), + settingsManager: SettingsManager, content: @Composable () -> Unit, ) { + var accent by remember { mutableStateOf(Teal) } + var darkOverride by remember { mutableStateOf(null) } + val version = settingsManager.valuesChanged.collectAsState() + LaunchedEffect(version.value) { + runCatching { settingsManager.ensureLoaded() } + accent = parseColor(settingsManager.string("accent_color")) + darkOverride = when (settingsManager.string("theme_mode")) { + "Light" -> false + "Dark" -> true + else -> null + } + } + val dark = darkOverride ?: isSystemInDarkTheme() MaterialTheme( - colorScheme = if (darkTheme) DarkScheme else LightScheme, + colorScheme = schemeFor(accent, dark), content = content, ) }