From eaf3602bbae71c4debd5bc2529c54b7c73a36c07 Mon Sep 17 00:00:00 2001 From: vesp Date: Sat, 22 Nov 2025 22:44:40 +0100 Subject: [PATCH] Add dynamic color palette support Use Material You dynamic colors derived from wallpaper on Android 12+. Shows gradient indicator in settings, disabled on older Android versions. --- .../bugsy/karemote/data/model/AppSettings.kt | 1 + .../ui/screens/settings/SettingsScreen.kt | 49 ++++++++++++++----- .../java/cz/bugsy/karemote/ui/theme/Theme.kt | 8 +++ 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/cz/bugsy/karemote/data/model/AppSettings.kt b/app/src/main/java/cz/bugsy/karemote/data/model/AppSettings.kt index c5d5007..777798b 100644 --- a/app/src/main/java/cz/bugsy/karemote/data/model/AppSettings.kt +++ b/app/src/main/java/cz/bugsy/karemote/data/model/AppSettings.kt @@ -5,6 +5,7 @@ enum class ThemeMode { } enum class ColorTheme(val displayName: String) { + DYNAMIC("Dynamic"), DEFAULT("Default"), BLUE("Blue"), GREEN("Green"), diff --git a/app/src/main/java/cz/bugsy/karemote/ui/screens/settings/SettingsScreen.kt b/app/src/main/java/cz/bugsy/karemote/ui/screens/settings/SettingsScreen.kt index ff07e2d..c5ff49f 100644 --- a/app/src/main/java/cz/bugsy/karemote/ui/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/cz/bugsy/karemote/ui/screens/settings/SettingsScreen.kt @@ -1,5 +1,6 @@ package cz.bugsy.karemote.ui.screens.settings +import android.os.Build import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable @@ -44,6 +45,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.font.FontWeight @@ -253,24 +255,48 @@ private fun ColorThemeOption( isSelected: Boolean, onClick: () -> Unit ) { - val color = when (theme) { - ColorTheme.DEFAULT -> DefaultPrimaryLight - ColorTheme.BLUE -> BluePrimaryLight - ColorTheme.GREEN -> GreenPrimaryLight - ColorTheme.ORANGE -> OrangePrimaryLight - ColorTheme.PURPLE -> PurplePrimaryLight - ColorTheme.RED -> RedPrimaryLight - } + val isDynamicSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S + val isEnabled = theme != ColorTheme.DYNAMIC || isDynamicSupported Column( horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.clickable { onClick() } + modifier = Modifier + .clickable(enabled = isEnabled) { onClick() } + .then(if (!isEnabled) Modifier.background(Color.Transparent) else Modifier) ) { Box( modifier = Modifier .size(48.dp) .clip(CircleShape) - .background(color) + .then( + if (theme == ColorTheme.DYNAMIC) { + Modifier.background( + brush = Brush.sweepGradient( + colors = listOf( + BluePrimaryLight, + PurplePrimaryLight, + RedPrimaryLight, + OrangePrimaryLight, + GreenPrimaryLight, + DefaultPrimaryLight, + BluePrimaryLight + ) + ), + alpha = if (isEnabled) 1f else 0.4f + ) + } else { + val color = when (theme) { + ColorTheme.DYNAMIC -> Color.Transparent // won't reach here + ColorTheme.DEFAULT -> DefaultPrimaryLight + ColorTheme.BLUE -> BluePrimaryLight + ColorTheme.GREEN -> GreenPrimaryLight + ColorTheme.ORANGE -> OrangePrimaryLight + ColorTheme.PURPLE -> PurplePrimaryLight + ColorTheme.RED -> RedPrimaryLight + } + Modifier.background(color) + } + ) .then( if (isSelected) { Modifier.border(3.dp, MaterialTheme.colorScheme.outline, CircleShape) @@ -292,7 +318,8 @@ private fun ColorThemeOption( Spacer(modifier = Modifier.height(4.dp)) Text( text = theme.displayName, - style = MaterialTheme.typography.labelSmall + style = MaterialTheme.typography.labelSmall, + color = if (isEnabled) Color.Unspecified else MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) ) } } diff --git a/app/src/main/java/cz/bugsy/karemote/ui/theme/Theme.kt b/app/src/main/java/cz/bugsy/karemote/ui/theme/Theme.kt index 8011e5c..23c44be 100644 --- a/app/src/main/java/cz/bugsy/karemote/ui/theme/Theme.kt +++ b/app/src/main/java/cz/bugsy/karemote/ui/theme/Theme.kt @@ -254,7 +254,15 @@ fun KaRemoteTheme( ThemeMode.SYSTEM -> isSystemInDarkTheme() } + val context = LocalContext.current val colorScheme = when (colorTheme) { + ColorTheme.DYNAMIC -> { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } else { + if (darkTheme) DefaultDarkColorScheme else DefaultLightColorScheme + } + } ColorTheme.DEFAULT -> if (darkTheme) DefaultDarkColorScheme else DefaultLightColorScheme ColorTheme.BLUE -> if (darkTheme) BlueDarkColorScheme else BlueLightColorScheme ColorTheme.GREEN -> if (darkTheme) GreenDarkColorScheme else GreenLightColorScheme