From be721c987c0809b23c860bc86f484ca6c5405309 Mon Sep 17 00:00:00 2001 From: FunkyMuse Date: Mon, 24 Jul 2023 15:27:39 +0200 Subject: [PATCH] refactor: tidy up files --- app/build.gradle.kts | 1 + .../compose/extensions/ComposeExtensions.kt | 3 +- .../compose/extensions/LifecycleExtensions.kt | 27 +++ .../compose/screens/SettingsScreen.kt | 5 +- .../calculator/compose/theme/AppModifiers.kt | 47 ++++ .../calculator/compose/theme/AppTheme.kt | 41 ++++ .../calculator/compose/theme/ColorSchemes.kt | 9 + .../compose/theme/ColorsExtensions.kt | 34 +++ .../calculator/compose/theme/DynamicTheme.kt | 6 +- .../calculator/compose/theme/Theme.kt | 229 +----------------- .../compose/theme/ThemeExtensions.kt | 34 +++ .../compose/theme/model/CommonTheme.kt | 18 ++ .../calculator/compose/theme/model/Theme.kt | 60 +++++ 13 files changed, 287 insertions(+), 227 deletions(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/LifecycleExtensions.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppModifiers.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppTheme.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorSchemes.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorsExtensions.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ThemeExtensions.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/CommonTheme.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/Theme.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 199a63ea..64a912d5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,6 +18,7 @@ android { compileSdk = project.libs.versions.app.build.compileSDKVersion.get().toInt() defaultConfig { + applicationId = libs.versions.app.version.appId.get() minSdk = project.libs.versions.app.build.minimumSDK.get().toInt() targetSdk = project.libs.versions.app.build.targetSDK.get().toInt() versionName = project.libs.versions.app.version.versionName.get() diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt index 04c6ea28..70cc7bb2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/ComposeExtensions.kt @@ -8,7 +8,6 @@ import androidx.compose.runtime.* import androidx.compose.ui.graphics.Color import androidx.lifecycle.Lifecycle import com.google.accompanist.systemuicontroller.rememberSystemUiController -import com.simplemobiletools.calculator.compose.theme.OnLifecycleEvent fun Context.getActivity(): Activity { if (this is Activity) return this @@ -21,7 +20,7 @@ fun TransparentSystemBars() { val systemUiController = rememberSystemUiController() val isSystemInDarkTheme = isSystemInDarkTheme() SideEffect { - systemUiController.setSystemBarsColor(Color.Transparent, darkIcons = isSystemInDarkTheme) + systemUiController.setSystemBarsColor(Color.Transparent, darkIcons = !isSystemInDarkTheme) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/LifecycleExtensions.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/LifecycleExtensions.kt new file mode 100644 index 00000000..c5711c9e --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/extensions/LifecycleExtensions.kt @@ -0,0 +1,27 @@ +package com.simplemobiletools.calculator.compose.extensions + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner + +@Composable +fun OnLifecycleEvent( + lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, + onEvent: (event: Lifecycle.Event) -> Unit +) { + val currentOnEvent by rememberUpdatedState(onEvent) + DisposableEffect(lifecycleOwner) { + val observer = LifecycleEventObserver { _, event -> + currentOnEvent(event) + } + lifecycleOwner.lifecycle.addObserver(observer) + onDispose { + lifecycleOwner.lifecycle.removeObserver(observer) + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/screens/SettingsScreen.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/screens/SettingsScreen.kt index 069dcc6c..2c964aad 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/screens/SettingsScreen.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/screens/SettingsScreen.kt @@ -23,7 +23,10 @@ import com.simplemobiletools.calculator.compose.settings.SettingsCheckBoxCompone import com.simplemobiletools.calculator.compose.settings.SettingsGroup import com.simplemobiletools.calculator.compose.settings.SettingsPreferenceComponent import com.simplemobiletools.calculator.compose.settings.SettingsTitleTextComponent -import com.simplemobiletools.calculator.compose.theme.* +import com.simplemobiletools.calculator.compose.theme.AppThemeSurface +import com.simplemobiletools.calculator.compose.theme.divider_grey +import com.simplemobiletools.calculator.compose.theme.isNotLitWell +import com.simplemobiletools.calculator.compose.theme.isSurfaceLitWell import com.simplemobiletools.commons.R import com.simplemobiletools.commons.helpers.isTiramisuPlus import java.util.Locale diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppModifiers.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppModifiers.kt new file mode 100644 index 00000000..20ade471 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppModifiers.kt @@ -0,0 +1,47 @@ +package com.simplemobiletools.calculator.compose.theme + +import android.app.Activity +import android.app.ActivityManager +import android.content.Context +import android.graphics.BitmapFactory +import com.simplemobiletools.calculator.compose.extensions.getActivity +import com.simplemobiletools.calculator.helpers.Config +import com.simplemobiletools.commons.R +import com.simplemobiletools.commons.helpers.APP_ICON_IDS +import com.simplemobiletools.commons.helpers.APP_LAUNCHER_NAME + +fun Activity.getAppIconIds(): ArrayList = ArrayList(intent.getIntegerArrayListExtra(APP_ICON_IDS).orEmpty()) +fun Activity.getAppLauncherName(): String = intent.getStringExtra(APP_LAUNCHER_NAME).orEmpty() +internal fun updateRecentsAppIcon(baseConfig: Config, context: Context) { + if (baseConfig.isUsingModifiedAppIcon) { + val appIconIDs = context.getAppIconIds() + val currentAppIconColorIndex = baseConfig.getCurrentAppIconColorIndex(context) + if (appIconIDs.size - 1 < currentAppIconColorIndex) { + return + } + + val recentsIcon = BitmapFactory.decodeResource(context.resources, appIconIDs[currentAppIconColorIndex]) + val title = context.getAppLauncherName() + val color = baseConfig.primaryColor + + val description = ActivityManager.TaskDescription(title, recentsIcon, color) + context.getActivity().setTaskDescription(description) + } +} + +private fun Config.getCurrentAppIconColorIndex(context: Context): Int { + val appIconColor = appIconColor + context.getAppIconColors().forEachIndexed { index, color -> + if (color == appIconColor) { + return index + } + } + return 0 +} + +private fun Context.getAppIconColors() = resources.getIntArray(R.array.md_app_icon_colors).toCollection(ArrayList()) + +private fun Context.getAppIconIds(): List = getActivity().getAppIconIds() + +private fun Context.getAppLauncherName(): String = getActivity().getAppLauncherName() + diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppTheme.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppTheme.kt new file mode 100644 index 00000000..19d5ddd6 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/AppTheme.kt @@ -0,0 +1,41 @@ +package com.simplemobiletools.calculator.compose.theme + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Surface +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.lifecycle.Lifecycle +import com.simplemobiletools.calculator.compose.extensions.OnLifecycleEvent +import com.simplemobiletools.calculator.compose.theme.model.Theme.Companion.systemDefaultMaterialYou + + +@Composable +fun AppThemeSurface( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + val view = LocalView.current + + val context = LocalContext.current + val materialYouTheme = systemDefaultMaterialYou() + var currentTheme by remember { + mutableStateOf( + if (view.isInEditMode) materialYouTheme else getTheme( + context = context, + materialYouTheme = materialYouTheme + ) + ) + } + OnLifecycleEvent { event -> + if (event == Lifecycle.Event.ON_START && !view.isInEditMode) { + currentTheme = getTheme(context = context, materialYouTheme = materialYouTheme) + } + } + Theme(theme = currentTheme) { + Surface(modifier = modifier.fillMaxSize()) { + content() + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorSchemes.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorSchemes.kt new file mode 100644 index 00000000..23261aeb --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorSchemes.kt @@ -0,0 +1,9 @@ +package com.simplemobiletools.calculator.compose.theme + +import androidx.compose.material3.darkColorScheme + +internal val darkColorScheme = darkColorScheme( + primary = color_primary, + secondary = color_primary_dark, + tertiary = color_accent, +) diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorsExtensions.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorsExtensions.kt new file mode 100644 index 00000000..a3851721 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ColorsExtensions.kt @@ -0,0 +1,34 @@ +package com.simplemobiletools.calculator.compose.theme + +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.luminance + +@get:ReadOnlyComposable +val disabledTextColor @Composable get() = if (isInDarkThemeAndSurfaceIsNotLitWell()) Color.DarkGray else Color.LightGray + +@get:ReadOnlyComposable +val textSubTitleColor + @Composable get() = if (isInDarkThemeAndSurfaceIsNotLitWell()) { + Color.White.copy(0.5f) + } else { + Color.Black.copy( + 0.5f, + ) + } + + +@Composable +@ReadOnlyComposable +fun preferenceSummaryColor(isEnabled: Boolean) = + if (isEnabled) textSubTitleColor else disabledTextColor + +@Composable +@ReadOnlyComposable +fun preferenceTitleColor(isEnabled: Boolean) = if (isEnabled) MaterialTheme.colorScheme.onSurface else disabledTextColor + +fun Color.isLitWell(threshold : Float = LUMINANCE_THRESHOLD) = luminance() > threshold + +fun Color.isNotLitWell(threshold: Float = LUMINANCE_THRESHOLD) = luminance() < threshold diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/DynamicTheme.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/DynamicTheme.kt index 450f9066..8a466446 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/DynamicTheme.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/DynamicTheme.kt @@ -1,17 +1,13 @@ package com.simplemobiletools.calculator.compose.theme import android.content.Context -import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext +import com.simplemobiletools.calculator.compose.theme.model.Theme import com.simplemobiletools.calculator.extensions.config import com.simplemobiletools.commons.extensions.isBlackAndWhiteTheme import com.simplemobiletools.commons.extensions.isWhiteTheme -@Composable -fun getCurrentTheme() = getTheme(LocalContext.current, Theme.systemDefaultMaterialYou()) - fun getTheme(context: Context, materialYouTheme: Theme.SystemDefaultMaterialYou): Theme { val baseConfig = context.config val primaryColorInt = baseConfig.primaryColor diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt index 83b82b37..e2300835 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/Theme.kt @@ -1,148 +1,24 @@ package com.simplemobiletools.calculator.compose.theme -import android.app.Activity -import android.app.ActivityManager -import android.content.Context -import android.content.res.Configuration -import android.graphics.BitmapFactory import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.remember import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.luminance -import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalView -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.LifecycleOwner import com.google.accompanist.systemuicontroller.rememberSystemUiController -import com.simplemobiletools.calculator.compose.extensions.getActivity -import com.simplemobiletools.calculator.compose.theme.Theme.Companion.systemDefaultMaterialYou +import com.simplemobiletools.calculator.compose.theme.model.Theme +import com.simplemobiletools.calculator.compose.theme.model.Theme.Companion.systemDefaultMaterialYou import com.simplemobiletools.calculator.extensions.config -import com.simplemobiletools.calculator.helpers.Config -import com.simplemobiletools.commons.R -import com.simplemobiletools.commons.helpers.APP_ICON_IDS -import com.simplemobiletools.commons.helpers.APP_LAUNCHER_NAME - -private val darkColorScheme = darkColorScheme( - primary = color_primary, - secondary = color_primary_dark, - tertiary = color_accent, -) - -@get:ReadOnlyComposable -val disabledTextColor @Composable get() = if (isInDarkThemeAndSurfaceIsNotLitWell()) Color.DarkGray else Color.LightGray - -@get:ReadOnlyComposable -val textSubTitleColor - @Composable get() = if (isInDarkThemeAndSurfaceIsNotLitWell()) { - Color.White.copy(0.5f) - } else { - Color.Black.copy( - 0.5f, - ) - } - @Composable -@ReadOnlyComposable -fun preferenceSummaryColor(isEnabled: Boolean) = - if (isEnabled) textSubTitleColor else disabledTextColor - -@Composable -@ReadOnlyComposable -fun preferenceTitleColor(isEnabled: Boolean) = if (isEnabled) MaterialTheme.colorScheme.onSurface else disabledTextColor - -interface CommonTheme { - val primaryColorInt: Int - val backgroundColorInt: Int - val appIconColorInt: Int - val textColorInt: Int - - val primaryColor get() = Color(primaryColorInt) - val backgroundColor get() = Color(backgroundColorInt) - val appIconColor get() = Color(appIconColorInt) - val textColor get() = Color(textColorInt) - -} - -@Stable -sealed class Theme : CommonTheme { - data class SystemDefaultMaterialYou( - override val primaryColorInt: Int, - override val backgroundColorInt: Int, - override val appIconColorInt: Int, - override val textColorInt: Int - ) : Theme() - - data class White( - val accentColor: Int, - override val primaryColorInt: Int, - override val backgroundColorInt: Int, - override val appIconColorInt: Int, - override val textColorInt: Int - ) : Theme() - - data class Dark( - override val primaryColorInt: Int, - override val backgroundColorInt: Int, - override val appIconColorInt: Int, - override val textColorInt: Int - ) : Theme() - - data class BlackAndWhite( - val accentColor: Int, - override val primaryColorInt: Int, - override val backgroundColorInt: Int, - override val appIconColorInt: Int, - override val textColorInt: Int - ) : Theme() - - data class Custom( - override val primaryColorInt: Int, - override val backgroundColorInt: Int, - override val appIconColorInt: Int, - override val textColorInt: Int - ) : Theme() - - - companion object { - @Composable - fun systemDefaultMaterialYou() = SystemDefaultMaterialYou( - appIconColorInt = LocalContext.current.config.appIconColor, - primaryColorInt = LocalContext.current.config.primaryColor, - backgroundColorInt = LocalContext.current.config.backgroundColor, - textColorInt = (if (isInDarkThemeAndSurfaceIsNotLitWell()) Color.White else Color.Black).toArgb() - ) - } -} - -@Composable -@ReadOnlyComposable -fun isInDarkThemeAndSurfaceIsNotLitWell() = isSystemInDarkTheme() || isSurfaceNotLitWell() - -private const val LUMINANCE_THRESHOLD = 0.5f - -@Composable -@ReadOnlyComposable -fun isSurfaceNotLitWell() = MaterialTheme.colorScheme.surface.luminance() < LUMINANCE_THRESHOLD - -@Composable -@ReadOnlyComposable -fun isSurfaceLitWell() = MaterialTheme.colorScheme.surface.luminance() > LUMINANCE_THRESHOLD - -fun Color.isLitWell() = luminance() > LUMINANCE_THRESHOLD - -fun Color.isNotLitWell() = luminance() < LUMINANCE_THRESHOLD - - -@Composable -private fun Theme( +internal fun Theme( theme: Theme = systemDefaultMaterialYou(), content: @Composable () -> Unit, ) { @@ -199,88 +75,3 @@ private fun Theme( ) } -private fun Context.getAppIconIds(): List = getActivity().getAppIconIds() -fun Activity.getAppIconIds(): ArrayList = ArrayList(intent.getIntegerArrayListExtra(APP_ICON_IDS).orEmpty()) -private fun Context.getAppLauncherName(): String = getActivity().getAppLauncherName() -fun Activity.getAppLauncherName(): String = intent.getStringExtra(APP_LAUNCHER_NAME).orEmpty() -private fun updateRecentsAppIcon(baseConfig: Config, context: Context) { - if (baseConfig.isUsingModifiedAppIcon) { - val appIconIDs = context.getAppIconIds() - val currentAppIconColorIndex = baseConfig.getCurrentAppIconColorIndex(context) - if (appIconIDs.size - 1 < currentAppIconColorIndex) { - return - } - - val recentsIcon = BitmapFactory.decodeResource(context.resources, appIconIDs[currentAppIconColorIndex]) - val title = context.getAppLauncherName() - val color = baseConfig.primaryColor - - val description = ActivityManager.TaskDescription(title, recentsIcon, color) - context.getActivity().setTaskDescription(description) - } -} - -private fun Config.getCurrentAppIconColorIndex(context: Context): Int { - val appIconColor = appIconColor - context.getAppIconColors().forEachIndexed { index, color -> - if (color == appIconColor) { - return index - } - } - return 0 -} - -private fun Context.getAppIconColors() = resources.getIntArray(R.array.md_app_icon_colors).toCollection(ArrayList()) - -@Composable -fun AppThemeSurface( - modifier: Modifier = Modifier, - content: @Composable () -> Unit, -) { - val view = LocalView.current - - val context = LocalContext.current - val materialYouTheme = systemDefaultMaterialYou() - var currentTheme by remember { - mutableStateOf( - if (view.isInEditMode) materialYouTheme else getTheme( - context = context, - materialYouTheme = materialYouTheme - ) - ) - } - OnLifecycleEvent { event -> - if (event == Lifecycle.Event.ON_START && !view.isInEditMode) { - currentTheme = getTheme(context = context, materialYouTheme = materialYouTheme) - } - } - Theme(theme = currentTheme) { - Surface(modifier = modifier.fillMaxSize()) { - content() - } - } -} - -internal fun Context.isDarkMode(): Boolean { - val darkModeFlag = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK - return darkModeFlag == Configuration.UI_MODE_NIGHT_YES -} - -@Composable -fun OnLifecycleEvent( - lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, - onEvent: (event: Lifecycle.Event) -> Unit -) { - val currentOnEvent by rememberUpdatedState(onEvent) - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - currentOnEvent(event) - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { - lifecycleOwner.lifecycle.removeObserver(observer) - } - } -} - - diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ThemeExtensions.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ThemeExtensions.kt new file mode 100644 index 00000000..f936fb03 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/ThemeExtensions.kt @@ -0,0 +1,34 @@ +package com.simplemobiletools.calculator.compose.theme + +import android.content.Context +import android.content.res.Configuration +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.graphics.luminance +import androidx.compose.ui.platform.LocalContext +import com.simplemobiletools.calculator.compose.theme.model.Theme.Companion.systemDefaultMaterialYou + + +@Composable +fun getCurrentTheme() = getTheme(LocalContext.current, systemDefaultMaterialYou()) + +@Composable +@ReadOnlyComposable +fun isInDarkThemeAndSurfaceIsNotLitWell() = isSystemInDarkTheme() || isSurfaceNotLitWell() + +internal const val LUMINANCE_THRESHOLD = 0.5f + +@Composable +@ReadOnlyComposable +fun isSurfaceNotLitWell(threshold: Float = LUMINANCE_THRESHOLD) = MaterialTheme.colorScheme.surface.luminance() < threshold + +@Composable +@ReadOnlyComposable +fun isSurfaceLitWell(threshold: Float = LUMINANCE_THRESHOLD) = MaterialTheme.colorScheme.surface.luminance() > threshold + +fun Context.isDarkMode(): Boolean { + val darkModeFlag = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK + return darkModeFlag == Configuration.UI_MODE_NIGHT_YES +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/CommonTheme.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/CommonTheme.kt new file mode 100644 index 00000000..e4541a6e --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/CommonTheme.kt @@ -0,0 +1,18 @@ +package com.simplemobiletools.calculator.compose.theme.model + +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color + +@Immutable +interface CommonTheme { + val primaryColorInt: Int + val backgroundColorInt: Int + val appIconColorInt: Int + val textColorInt: Int + + val primaryColor get() = Color(primaryColorInt) + val backgroundColor get() = Color(backgroundColorInt) + val appIconColor get() = Color(appIconColorInt) + val textColor get() = Color(textColorInt) + +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/Theme.kt b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/Theme.kt new file mode 100644 index 00000000..146f2cce --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calculator/compose/theme/model/Theme.kt @@ -0,0 +1,60 @@ +package com.simplemobiletools.calculator.compose.theme.model + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import com.simplemobiletools.calculator.compose.theme.isInDarkThemeAndSurfaceIsNotLitWell +import com.simplemobiletools.calculator.extensions.config + +@Stable +sealed class Theme : CommonTheme { + data class SystemDefaultMaterialYou( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class White( + val accentColor: Int, + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class Dark( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class BlackAndWhite( + val accentColor: Int, + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + data class Custom( + override val primaryColorInt: Int, + override val backgroundColorInt: Int, + override val appIconColorInt: Int, + override val textColorInt: Int + ) : Theme() + + + companion object { + @Composable + fun systemDefaultMaterialYou() = SystemDefaultMaterialYou( + appIconColorInt = LocalContext.current.config.appIconColor, + primaryColorInt = LocalContext.current.config.primaryColor, + backgroundColorInt = LocalContext.current.config.backgroundColor, + textColorInt = (if (isInDarkThemeAndSurfaceIsNotLitWell()) Color.White else Color.Black).toArgb() + ) + } +}