Theme + accent settings now apply live (were decorative: ShonarTheme ignored them)

This commit is contained in:
avi 2026-09-17 21:25:20 -05:00
commit b6d4fd3cb2
2 changed files with 47 additions and 18 deletions

View file

@ -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(),

View file

@ -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,
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),
)
private val LightScheme = lightColorScheme(
primary = TealDark,
onPrimary = Color.White,
secondary = Teal,
)
)
} 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<Boolean?>(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,
)
}