🛠️ Reformat Theme (enum)

* Reformatted Theme enum
* More scalable approach, allowing multiple Themes without ThemeContrast
This commit is contained in:
Acclorite 2024-10-24 18:51:28 +03:00
parent a7f2cc6aba
commit aa00a3b088
6 changed files with 50 additions and 74 deletions

View file

@ -1,18 +0,0 @@
package ua.acclorite.book_story.presentation.core.constants
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.UIText
import ua.acclorite.book_story.presentation.ui.Theme
fun Constants.provideThemes() = listOf(
Pair(Theme.DYNAMIC, UIText.StringResource(R.string.dynamic_theme)),
Pair(Theme.BLUE, UIText.StringResource(R.string.blue_theme)),
Pair(Theme.GREEN, UIText.StringResource(R.string.green_theme)),
Pair(Theme.MARSH, UIText.StringResource(R.string.marsh_theme)),
Pair(Theme.RED, UIText.StringResource(R.string.red_theme)),
Pair(Theme.PURPLE, UIText.StringResource(R.string.purple_theme)),
Pair(Theme.LAVENDER, UIText.StringResource(R.string.lavender_theme)),
Pair(Theme.PINK, UIText.StringResource(R.string.pink_theme)),
Pair(Theme.YELLOW, UIText.StringResource(R.string.yellow_theme)),
Pair(Theme.AQUA, UIText.StringResource(R.string.aqua_theme)),
)

View file

@ -2,7 +2,6 @@
package ua.acclorite.book_story.presentation.data
import android.os.Build
import android.os.Parcelable
import androidx.annotation.Keep
import androidx.compose.runtime.Immutable
@ -49,10 +48,7 @@ data class MainState(
else "en"// Default language.
}
},
val theme: Theme = provideDefaultValue {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Theme.DYNAMIC
else Theme.BLUE
},
val theme: Theme = provideDefaultValue { Theme.entries().first() },
val darkTheme: DarkTheme = provideDefaultValue { DarkTheme.FOLLOW_SYSTEM },
val pureDark: PureDark = provideDefaultValue { PureDark.OFF },
val absoluteDark: Boolean = provideDefaultValue { false },

View file

@ -14,7 +14,6 @@ import ua.acclorite.book_story.presentation.data.MainEvent
import ua.acclorite.book_story.presentation.data.MainViewModel
import ua.acclorite.book_story.presentation.ui.BookStoryTheme
import ua.acclorite.book_story.presentation.ui.ExpandingTransition
import ua.acclorite.book_story.presentation.ui.Theme
import ua.acclorite.book_story.presentation.ui.ThemeContrast
import ua.acclorite.book_story.presentation.ui.isDark
import ua.acclorite.book_story.presentation.ui.isPureDark
@ -31,7 +30,7 @@ fun ThemeContrastSetting() {
val themeContrastTheme = remember { mutableStateOf(state.value.theme) }
LaunchedEffect(state.value.theme) {
if (themeContrastTheme.value != state.value.theme && state.value.theme != Theme.DYNAMIC) {
if (state.value.theme.hasThemeContrast) {
themeContrastTheme.value = state.value.theme
}
}
@ -42,10 +41,10 @@ fun ThemeContrastSetting() {
isPureDark = state.value.pureDark.isPureDark(context = LocalContext.current),
themeContrast = state.value.themeContrast
) {
ExpandingTransition(visible = state.value.theme != Theme.DYNAMIC) {
ExpandingTransition(visible = state.value.theme.hasThemeContrast) {
SegmentedButtonWithTitle(
title = stringResource(id = R.string.theme_contrast_option),
enabled = state.value.theme != Theme.DYNAMIC,
enabled = state.value.theme.hasThemeContrast,
buttons = ThemeContrast.entries.map {
ButtonItem(
id = it.toString(),

View file

@ -1,6 +1,5 @@
package ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.settings
import android.os.Build
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
@ -11,6 +10,7 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
@ -19,7 +19,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
@ -28,7 +28,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -38,10 +37,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.UIText
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.constants.provideThemes
import ua.acclorite.book_story.presentation.data.MainEvent
import ua.acclorite.book_story.presentation.data.MainViewModel
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryTitle
@ -53,7 +49,7 @@ import ua.acclorite.book_story.presentation.ui.isPureDark
/**
* Theme setting.
* Lets user change app's theme from available in [provideThemes].
* Lets user change app's theme from available in [Theme.entries].
*/
@Composable
fun ThemeSetting(
@ -63,11 +59,6 @@ fun ThemeSetting(
val state = MainViewModel.getState()
val onMainEvent = MainViewModel.getEvent()
val themes = remember {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Constants.provideThemes()
else Constants.provideThemes().dropWhile { it.first == Theme.DYNAMIC }
}
Column(
Modifier
.fillMaxWidth()
@ -80,28 +71,21 @@ fun ThemeSetting(
Spacer(modifier = Modifier.height(10.dp))
LazyRow(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
horizontalArrangement = Arrangement.spacedBy(8.dp),
contentPadding = PaddingValues(horizontal = horizontalPadding)
) {
itemsIndexed(
themes,
key = { _, themeEntry -> themeEntry.first.name }
) { index, themeEntry ->
if (index == 0) {
Spacer(modifier = Modifier.width(horizontalPadding))
}
items(
Theme.entries(),
key = { theme -> theme.name }
) { theme ->
ThemeSettingItem(
theme = themeEntry,
theme = theme,
darkTheme = state.value.darkTheme.isDark(),
themeContrast = state.value.themeContrast,
isPureDark = state.value.pureDark.isPureDark(context = LocalContext.current),
selected = state.value.theme == themeEntry.first
selected = state.value.theme == theme
) {
onMainEvent(MainEvent.OnChangeTheme(themeEntry.first.toString()))
}
if (index == themes.lastIndex) {
Spacer(modifier = Modifier.width(horizontalPadding))
onMainEvent(MainEvent.OnChangeTheme(theme.name))
}
}
}
@ -121,7 +105,7 @@ fun ThemeSetting(
*/
@Composable
private fun ThemeSettingItem(
theme: Pair<Theme, UIText>,
theme: Theme,
darkTheme: Boolean,
isPureDark: Boolean,
themeContrast: ThemeContrast,
@ -129,10 +113,10 @@ private fun ThemeSettingItem(
onClick: () -> Unit
) {
val colorScheme = animatedColorScheme(
theme.first,
darkTheme,
isPureDark,
themeContrast
theme = theme,
isDark = darkTheme,
isPureDark = isPureDark,
themeContrast = themeContrast
)
Column(
@ -227,7 +211,7 @@ private fun ThemeSettingItem(
}
Spacer(modifier = Modifier.height(6.dp))
Text(
text = theme.second.asString(),
text = stringResource(id = theme.title),
color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.labelLarge,
overflow = TextOverflow.Ellipsis,

View file

@ -1,8 +1,11 @@
package ua.acclorite.book_story.presentation.ui
import android.os.Build
import androidx.annotation.StringRes
import androidx.compose.material3.ColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.ui.theme.aquaTheme
import ua.acclorite.book_story.presentation.ui.theme.blackTheme
import ua.acclorite.book_story.presentation.ui.theme.blueTheme
@ -15,18 +18,31 @@ import ua.acclorite.book_story.presentation.ui.theme.purpleTheme
import ua.acclorite.book_story.presentation.ui.theme.redTheme
import ua.acclorite.book_story.presentation.ui.theme.yellowTheme
@Immutable
enum class Theme {
DYNAMIC,
BLUE,
GREEN,
RED,
PURPLE,
PINK,
YELLOW,
AQUA,
MARSH,
LAVENDER,
enum class Theme(
val hasThemeContrast: Boolean,
@StringRes val title: Int
) {
DYNAMIC(hasThemeContrast = false, title = R.string.dynamic_theme),
BLUE(hasThemeContrast = true, title = R.string.blue_theme),
GREEN(hasThemeContrast = true, title = R.string.green_theme),
MARSH(hasThemeContrast = true, title = R.string.marsh_theme),
RED(hasThemeContrast = true, title = R.string.red_theme),
PURPLE(hasThemeContrast = true, title = R.string.purple_theme),
LAVENDER(hasThemeContrast = true, title = R.string.lavender_theme),
PINK(hasThemeContrast = false, title = R.string.pink_theme),
YELLOW(hasThemeContrast = true, title = R.string.yellow_theme),
AQUA(hasThemeContrast = true, title = R.string.aqua_theme);
companion object {
fun entries(): List<Theme> {
return when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> Theme.entries
else -> Theme.entries.dropWhile { it == DYNAMIC }
}
}
}
}
/**

View file

@ -113,8 +113,7 @@ fun BookStoryTheme(
}
val colorScheme = colorScheme(
theme = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) theme
else if (theme != Theme.DYNAMIC) theme else Theme.BLUE,
theme = Theme.entries().find { it == theme } ?: Theme.BLUE,
darkTheme = isDark,
isPureDark = isPureDark,
themeContrast = themeContrast