🚀 Elevate Settings category icon background
* Material3 style Settings items * Reformatted code
This commit is contained in:
parent
30a0febf03
commit
a6b340c0c8
34 changed files with 261 additions and 182 deletions
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
package ua.acclorite.book_story.domain.browse
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class BrowseLayout {
|
||||
LIST, GRID
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
package ua.acclorite.book_story.domain.browse
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class BrowseSortOrder {
|
||||
NAME,
|
||||
FILE_FORMAT,
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@
|
|||
|
||||
package ua.acclorite.book_story.domain.library.category
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import ua.acclorite.book_story.domain.library.book.SelectableBook
|
||||
import ua.acclorite.book_story.domain.ui.UIText
|
||||
|
||||
@Immutable
|
||||
data class CategoryWithBooks(
|
||||
val category: Category,
|
||||
val title: UIText,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
package ua.acclorite.book_story.domain.reader
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class ReaderColorEffects {
|
||||
OFF,
|
||||
GRAYSCALE,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
package ua.acclorite.book_story.domain.reader
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class ReaderHorizontalGesture {
|
||||
OFF,
|
||||
ON,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
package ua.acclorite.book_story.domain.reader
|
||||
|
||||
import android.content.pm.ActivityInfo
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class ReaderScreenOrientation(val code: Int) {
|
||||
DEFAULT(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED),
|
||||
FREE(ActivityInfo.SCREEN_ORIENTATION_USER),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Book's Story — free and open-source Material You eBook reader.
|
||||
* Copyright (C) 2024-2025 Acclorite
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
package ua.acclorite.book_story.domain.ui
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class DarkTheme {
|
||||
FOLLOW_SYSTEM,
|
||||
OFF,
|
||||
ON
|
||||
}
|
||||
|
||||
fun String.toDarkTheme(): DarkTheme {
|
||||
return DarkTheme.valueOf(this)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DarkTheme.isDark(): Boolean {
|
||||
return when (this) {
|
||||
DarkTheme.FOLLOW_SYSTEM -> isSystemInDarkTheme()
|
||||
DarkTheme.ON -> true
|
||||
DarkTheme.OFF -> false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Book's Story — free and open-source Material You eBook reader.
|
||||
* Copyright (C) 2024-2025 Acclorite
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
package ua.acclorite.book_story.domain.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.os.PowerManager
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class PureDark {
|
||||
OFF,
|
||||
ON,
|
||||
SAVER
|
||||
}
|
||||
|
||||
fun String.toPureDark(): PureDark {
|
||||
return PureDark.valueOf(this)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PureDark.isPureDark(context: Context): Boolean {
|
||||
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
|
||||
return when (this) {
|
||||
PureDark.OFF -> false
|
||||
PureDark.ON -> true
|
||||
PureDark.SAVER -> powerManager.isPowerSaveMode
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Book's Story — free and open-source Material You eBook reader.
|
||||
* Copyright (C) 2024-2025 Acclorite
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
package ua.acclorite.book_story.domain.ui
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class ThemeContrast {
|
||||
STANDARD,
|
||||
MEDIUM,
|
||||
HIGH
|
||||
}
|
||||
|
||||
fun String.toThemeContrast(): ThemeContrast {
|
||||
return ThemeContrast.valueOf(this)
|
||||
}
|
||||
|
|
@ -38,8 +38,8 @@ import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
|||
import ua.acclorite.book_story.presentation.core.components.common.StyledText
|
||||
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||
import ua.acclorite.book_story.ui.reader.ReaderEvent
|
||||
import ua.acclorite.book_story.ui.theme.Colors
|
||||
import ua.acclorite.book_story.ui.theme.HorizontalExpandingTransition
|
||||
import ua.acclorite.book_story.ui.theme.readerBarsColor
|
||||
|
||||
@Composable
|
||||
fun ReaderBottomBar(
|
||||
|
|
@ -75,7 +75,7 @@ fun ReaderBottomBar(
|
|||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.background(Colors.readerSystemBarsColor)
|
||||
.background(MaterialTheme.colorScheme.readerBarsColor)
|
||||
.noRippleClickable(onClick = {})
|
||||
.navigationBarsPadding()
|
||||
.padding(horizontal = 18.dp),
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import ua.acclorite.book_story.presentation.core.util.LocalActivity
|
|||
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||
import ua.acclorite.book_story.ui.reader.ReaderEvent
|
||||
import ua.acclorite.book_story.ui.settings.SettingsEvent
|
||||
import ua.acclorite.book_story.ui.theme.Colors
|
||||
import ua.acclorite.book_story.ui.theme.readerBarsColor
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
|
|
@ -64,7 +64,7 @@ fun ReaderTopBar(
|
|||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.background(Colors.readerSystemBarsColor)
|
||||
.background(MaterialTheme.colorScheme.readerBarsColor)
|
||||
.readerColorPresetChange(
|
||||
colorPresetChangeEnabled = fastColorPresetChange,
|
||||
isLoading = isLoading,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ fun SettingsLayout(
|
|||
) {
|
||||
item {
|
||||
SettingsLayoutItem(
|
||||
index = 0,
|
||||
icon = Icons.Outlined.DisplaySettings,
|
||||
title = stringResource(id = R.string.general_settings),
|
||||
description = stringResource(id = R.string.general_settings_desc)
|
||||
|
|
@ -50,6 +51,7 @@ fun SettingsLayout(
|
|||
|
||||
item {
|
||||
SettingsLayoutItem(
|
||||
index = 1,
|
||||
icon = Icons.Outlined.Palette,
|
||||
title = stringResource(id = R.string.appearance_settings),
|
||||
description = stringResource(id = R.string.appearance_settings_desc)
|
||||
|
|
@ -60,6 +62,7 @@ fun SettingsLayout(
|
|||
|
||||
item {
|
||||
SettingsLayoutItem(
|
||||
index = 2,
|
||||
icon = Icons.Outlined.LocalLibrary,
|
||||
title = stringResource(id = R.string.reader_settings),
|
||||
description = stringResource(id = R.string.reader_settings_desc)
|
||||
|
|
@ -70,6 +73,7 @@ fun SettingsLayout(
|
|||
|
||||
item {
|
||||
SettingsLayoutItem(
|
||||
index = 3,
|
||||
icon = Icons.Outlined.Explore,
|
||||
title = stringResource(id = R.string.browse_settings),
|
||||
description = stringResource(id = R.string.browse_settings_desc)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
package ua.acclorite.book_story.presentation.settings
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
|
@ -13,6 +14,7 @@ import androidx.compose.foundation.layout.Row
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -24,9 +26,11 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import ua.acclorite.book_story.presentation.core.components.common.StyledText
|
||||
import ua.acclorite.book_story.ui.theme.dynamicListItemColor
|
||||
|
||||
@Composable
|
||||
fun SettingsLayoutItem(
|
||||
index: Int,
|
||||
icon: ImageVector,
|
||||
title: String,
|
||||
description: String,
|
||||
|
|
@ -37,16 +41,21 @@ fun SettingsLayoutItem(
|
|||
.fillMaxWidth()
|
||||
.clip(MaterialTheme.shapes.extraLarge)
|
||||
.clickable { onClick() }
|
||||
.padding(vertical = 20.dp, horizontal = 24.dp),
|
||||
.padding(vertical = 18.dp, horizontal = 24.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(18.dp)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.dynamicListItemColor(index))
|
||||
.padding(12.dp)
|
||||
.size(24.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
|
||||
Column {
|
||||
StyledText(
|
||||
text = title,
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.ui.isDark
|
||||
import ua.acclorite.book_story.domain.ui.isPureDark
|
||||
import ua.acclorite.book_story.presentation.core.components.settings.SwitchWithTitle
|
||||
import ua.acclorite.book_story.ui.main.MainEvent
|
||||
import ua.acclorite.book_story.ui.main.MainModel
|
||||
import ua.acclorite.book_story.ui.theme.ExpandingTransition
|
||||
import ua.acclorite.book_story.ui.theme.isDark
|
||||
import ua.acclorite.book_story.ui.theme.isPureDark
|
||||
|
||||
@Composable
|
||||
fun AbsoluteDarkOption() {
|
||||
|
|
|
|||
|
|
@ -42,16 +42,16 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.isDark
|
||||
import ua.acclorite.book_story.domain.ui.isPureDark
|
||||
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||
import ua.acclorite.book_story.presentation.core.components.common.StyledText
|
||||
import ua.acclorite.book_story.presentation.settings.components.SettingsSubcategoryTitle
|
||||
import ua.acclorite.book_story.ui.main.MainEvent
|
||||
import ua.acclorite.book_story.ui.main.MainModel
|
||||
import ua.acclorite.book_story.ui.theme.Theme
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.ui.theme.animatedColorScheme
|
||||
import ua.acclorite.book_story.ui.theme.isDark
|
||||
import ua.acclorite.book_story.ui.theme.isPureDark
|
||||
|
||||
@Composable
|
||||
fun AppThemeOption() {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.ui.ButtonItem
|
||||
import ua.acclorite.book_story.domain.ui.DarkTheme
|
||||
import ua.acclorite.book_story.presentation.core.components.settings.SegmentedButtonWithTitle
|
||||
import ua.acclorite.book_story.ui.main.MainEvent
|
||||
import ua.acclorite.book_story.ui.main.MainModel
|
||||
import ua.acclorite.book_story.ui.theme.DarkTheme
|
||||
|
||||
@Composable
|
||||
fun DarkThemeOption() {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.ui.ButtonItem
|
||||
import ua.acclorite.book_story.domain.ui.PureDark
|
||||
import ua.acclorite.book_story.domain.ui.isDark
|
||||
import ua.acclorite.book_story.presentation.core.components.settings.SegmentedButtonWithTitle
|
||||
import ua.acclorite.book_story.ui.main.MainEvent
|
||||
import ua.acclorite.book_story.ui.main.MainModel
|
||||
import ua.acclorite.book_story.ui.theme.ExpandingTransition
|
||||
import ua.acclorite.book_story.ui.theme.PureDark
|
||||
import ua.acclorite.book_story.ui.theme.isDark
|
||||
|
||||
@Composable
|
||||
fun PureDarkOption() {
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.ui.ButtonItem
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.isDark
|
||||
import ua.acclorite.book_story.domain.ui.isPureDark
|
||||
import ua.acclorite.book_story.presentation.core.components.settings.SegmentedButtonWithTitle
|
||||
import ua.acclorite.book_story.ui.main.MainEvent
|
||||
import ua.acclorite.book_story.ui.main.MainModel
|
||||
import ua.acclorite.book_story.ui.theme.BookStoryTheme
|
||||
import ua.acclorite.book_story.ui.theme.ExpandingTransition
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.ui.theme.isDark
|
||||
import ua.acclorite.book_story.ui.theme.isPureDark
|
||||
|
||||
@Composable
|
||||
fun ThemeContrastOption() {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import okhttp3.internal.immutableListOf
|
|||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.navigator.NavigatorItem
|
||||
import ua.acclorite.book_story.domain.navigator.StackEvent
|
||||
import ua.acclorite.book_story.domain.ui.isDark
|
||||
import ua.acclorite.book_story.domain.ui.isPureDark
|
||||
import ua.acclorite.book_story.presentation.core.components.navigation_bar.NavigationBar
|
||||
import ua.acclorite.book_story.presentation.core.components.navigation_rail.NavigationRail
|
||||
import ua.acclorite.book_story.presentation.main.MainActivityKeyboardManager
|
||||
|
|
@ -40,8 +42,6 @@ import ua.acclorite.book_story.ui.settings.SettingsModel
|
|||
import ua.acclorite.book_story.ui.start.StartScreen
|
||||
import ua.acclorite.book_story.ui.theme.BookStoryTheme
|
||||
import ua.acclorite.book_story.ui.theme.Transitions
|
||||
import ua.acclorite.book_story.ui.theme.isDark
|
||||
import ua.acclorite.book_story.ui.theme.isPureDark
|
||||
import java.lang.reflect.Field
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ import ua.acclorite.book_story.domain.reader.toHorizontalGesture
|
|||
import ua.acclorite.book_story.domain.reader.toProgressCount
|
||||
import ua.acclorite.book_story.domain.reader.toReaderScreenOrientation
|
||||
import ua.acclorite.book_story.domain.reader.toTextAlignment
|
||||
import ua.acclorite.book_story.domain.ui.toDarkTheme
|
||||
import ua.acclorite.book_story.domain.ui.toPureDark
|
||||
import ua.acclorite.book_story.domain.ui.toThemeContrast
|
||||
import ua.acclorite.book_story.domain.use_case.data_store.ChangeLanguage
|
||||
import ua.acclorite.book_story.domain.use_case.data_store.GetAllSettings
|
||||
import ua.acclorite.book_story.domain.use_case.data_store.SetDatastore
|
||||
|
|
@ -38,10 +41,7 @@ import ua.acclorite.book_story.presentation.core.constants.Constants
|
|||
import ua.acclorite.book_story.presentation.core.constants.DataStoreConstants
|
||||
import ua.acclorite.book_story.presentation.core.constants.provideFonts
|
||||
import ua.acclorite.book_story.presentation.core.constants.provideMainState
|
||||
import ua.acclorite.book_story.ui.theme.toDarkTheme
|
||||
import ua.acclorite.book_story.ui.theme.toPureDark
|
||||
import ua.acclorite.book_story.ui.theme.toTheme
|
||||
import ua.acclorite.book_story.ui.theme.toThemeContrast
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,20 +29,20 @@ import ua.acclorite.book_story.domain.reader.toHorizontalGesture
|
|||
import ua.acclorite.book_story.domain.reader.toProgressCount
|
||||
import ua.acclorite.book_story.domain.reader.toReaderScreenOrientation
|
||||
import ua.acclorite.book_story.domain.reader.toTextAlignment
|
||||
import ua.acclorite.book_story.domain.ui.DarkTheme
|
||||
import ua.acclorite.book_story.domain.ui.PureDark
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.toDarkTheme
|
||||
import ua.acclorite.book_story.domain.ui.toPureDark
|
||||
import ua.acclorite.book_story.domain.ui.toThemeContrast
|
||||
import ua.acclorite.book_story.domain.util.HorizontalAlignment
|
||||
import ua.acclorite.book_story.domain.util.toHorizontalAlignment
|
||||
import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||
import ua.acclorite.book_story.presentation.core.constants.DataStoreConstants
|
||||
import ua.acclorite.book_story.presentation.core.constants.provideFonts
|
||||
import ua.acclorite.book_story.presentation.core.constants.provideLanguages
|
||||
import ua.acclorite.book_story.ui.theme.DarkTheme
|
||||
import ua.acclorite.book_story.ui.theme.PureDark
|
||||
import ua.acclorite.book_story.ui.theme.Theme
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.ui.theme.toDarkTheme
|
||||
import ua.acclorite.book_story.ui.theme.toPureDark
|
||||
import ua.acclorite.book_story.ui.theme.toTheme
|
||||
import ua.acclorite.book_story.ui.theme.toThemeContrast
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Book's Story — free and open-source Material You eBook reader.
|
||||
* Copyright (C) 2024-2025 Acclorite
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
package ua.acclorite.book_story.ui.theme
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
@Composable
|
||||
private fun animateColor(targetColor: Color): Color {
|
||||
return animateColorAsState(
|
||||
targetValue = targetColor,
|
||||
animationSpec = tween(300),
|
||||
label = ""
|
||||
).value
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun animateColorScheme(targetColorScheme: ColorScheme): ColorScheme {
|
||||
return ColorScheme(
|
||||
primary = animateColor(targetColor = targetColorScheme.primary),
|
||||
onPrimary = animateColor(targetColor = targetColorScheme.onPrimary),
|
||||
primaryContainer = animateColor(targetColor = targetColorScheme.primaryContainer),
|
||||
onPrimaryContainer = animateColor(targetColor = targetColorScheme.onPrimaryContainer),
|
||||
secondary = animateColor(targetColor = targetColorScheme.secondary),
|
||||
onSecondary = animateColor(targetColor = targetColorScheme.onSecondary),
|
||||
secondaryContainer = animateColor(targetColor = targetColorScheme.secondaryContainer),
|
||||
onSecondaryContainer = animateColor(targetColor = targetColorScheme.onSecondaryContainer),
|
||||
tertiary = animateColor(targetColor = targetColorScheme.tertiary),
|
||||
onTertiary = animateColor(targetColor = targetColorScheme.onTertiary),
|
||||
tertiaryContainer = animateColor(targetColor = targetColorScheme.tertiaryContainer),
|
||||
onTertiaryContainer = animateColor(targetColor = targetColorScheme.onTertiaryContainer),
|
||||
error = animateColor(targetColor = targetColorScheme.error),
|
||||
errorContainer = animateColor(targetColor = targetColorScheme.errorContainer),
|
||||
onError = animateColor(targetColor = targetColorScheme.onError),
|
||||
onErrorContainer = animateColor(targetColor = targetColorScheme.onErrorContainer),
|
||||
background = animateColor(targetColor = targetColorScheme.background),
|
||||
onBackground = animateColor(targetColor = targetColorScheme.onBackground),
|
||||
surface = animateColor(targetColor = targetColorScheme.surface),
|
||||
onSurface = animateColor(targetColor = targetColorScheme.onSurface),
|
||||
surfaceVariant = animateColor(targetColor = targetColorScheme.surfaceVariant),
|
||||
onSurfaceVariant = animateColor(targetColor = targetColorScheme.onSurfaceVariant),
|
||||
outline = animateColor(targetColor = targetColorScheme.outline),
|
||||
inverseOnSurface = animateColor(targetColor = targetColorScheme.inverseOnSurface),
|
||||
inverseSurface = animateColor(targetColor = targetColorScheme.inverseSurface),
|
||||
inversePrimary = animateColor(targetColor = targetColorScheme.inversePrimary),
|
||||
surfaceTint = animateColor(targetColor = targetColorScheme.surfaceTint),
|
||||
outlineVariant = animateColor(targetColor = targetColorScheme.outlineVariant),
|
||||
scrim = animateColor(targetColor = targetColorScheme.scrim),
|
||||
surfaceBright = animateColor(targetColor = targetColorScheme.surfaceBright),
|
||||
surfaceDim = animateColor(targetColor = targetColorScheme.surfaceDim),
|
||||
surfaceContainer = animateColor(targetColor = targetColorScheme.surfaceContainer),
|
||||
surfaceContainerHigh = animateColor(targetColor = targetColorScheme.surfaceContainerHigh),
|
||||
surfaceContainerHighest = animateColor(targetColor = targetColorScheme.surfaceContainerHighest),
|
||||
surfaceContainerLow = animateColor(targetColor = targetColorScheme.surfaceContainerLow),
|
||||
surfaceContainerLowest = animateColor(targetColor = targetColorScheme.surfaceContainerLowest),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun animatedColorScheme(
|
||||
theme: Theme,
|
||||
isDark: Boolean,
|
||||
isPureDark: Boolean,
|
||||
themeContrast: ThemeContrast
|
||||
): ColorScheme {
|
||||
val colorScheme = colorScheme(
|
||||
theme = theme,
|
||||
darkTheme = isDark,
|
||||
isPureDark = isPureDark,
|
||||
themeContrast = themeContrast
|
||||
)
|
||||
|
||||
return animateColorScheme(targetColorScheme = colorScheme)
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ 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.domain.ui.ThemeContrast
|
||||
import ua.acclorite.book_story.ui.theme.color.aquaTheme
|
||||
import ua.acclorite.book_story.ui.theme.color.blackTheme
|
||||
import ua.acclorite.book_story.ui.theme.color.blueTheme
|
||||
|
|
|
|||
|
|
@ -7,85 +7,16 @@
|
|||
package ua.acclorite.book_story.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Parcelable
|
||||
import android.os.PowerManager
|
||||
import android.view.View
|
||||
import androidx.annotation.Keep
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.WindowCompat
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Immutable
|
||||
@Keep
|
||||
@Parcelize
|
||||
enum class PureDark : Parcelable {
|
||||
OFF,
|
||||
ON,
|
||||
SAVER
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@Keep
|
||||
@Parcelize
|
||||
enum class ThemeContrast : Parcelable {
|
||||
STANDARD,
|
||||
MEDIUM,
|
||||
HIGH
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@Keep
|
||||
@Parcelize
|
||||
enum class DarkTheme : Parcelable {
|
||||
FOLLOW_SYSTEM,
|
||||
OFF,
|
||||
ON
|
||||
}
|
||||
|
||||
fun String.toDarkTheme(): DarkTheme {
|
||||
return DarkTheme.valueOf(this)
|
||||
}
|
||||
|
||||
fun String.toPureDark(): PureDark {
|
||||
return PureDark.valueOf(this)
|
||||
}
|
||||
|
||||
fun String.toThemeContrast(): ThemeContrast {
|
||||
return ThemeContrast.valueOf(this)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DarkTheme.isDark(): Boolean {
|
||||
return when (this) {
|
||||
DarkTheme.FOLLOW_SYSTEM -> isSystemInDarkTheme()
|
||||
DarkTheme.ON -> true
|
||||
DarkTheme.OFF -> false
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PureDark.isPureDark(context: Context): Boolean {
|
||||
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
|
||||
return when (this) {
|
||||
PureDark.OFF -> false
|
||||
PureDark.ON -> true
|
||||
PureDark.SAVER -> powerManager.isPowerSaveMode
|
||||
}
|
||||
}
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
@Composable
|
||||
fun BookStoryTheme(
|
||||
|
|
@ -128,78 +59,4 @@ fun BookStoryTheme(
|
|||
typography = Typography(),
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
object Colors {
|
||||
val readerSystemBarsColor: Color
|
||||
@Composable
|
||||
get() = MaterialTheme.colorScheme.surfaceContainer.copy(0.9f)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun animateColor(targetColor: Color): Color {
|
||||
return animateColorAsState(
|
||||
targetValue = targetColor,
|
||||
animationSpec = tween(300),
|
||||
label = ""
|
||||
).value
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun animateColorScheme(targetColorScheme: ColorScheme): ColorScheme {
|
||||
return ColorScheme(
|
||||
primary = animateColor(targetColor = targetColorScheme.primary),
|
||||
onPrimary = animateColor(targetColor = targetColorScheme.onPrimary),
|
||||
primaryContainer = animateColor(targetColor = targetColorScheme.primaryContainer),
|
||||
onPrimaryContainer = animateColor(targetColor = targetColorScheme.onPrimaryContainer),
|
||||
secondary = animateColor(targetColor = targetColorScheme.secondary),
|
||||
onSecondary = animateColor(targetColor = targetColorScheme.onSecondary),
|
||||
secondaryContainer = animateColor(targetColor = targetColorScheme.secondaryContainer),
|
||||
onSecondaryContainer = animateColor(targetColor = targetColorScheme.onSecondaryContainer),
|
||||
tertiary = animateColor(targetColor = targetColorScheme.tertiary),
|
||||
onTertiary = animateColor(targetColor = targetColorScheme.onTertiary),
|
||||
tertiaryContainer = animateColor(targetColor = targetColorScheme.tertiaryContainer),
|
||||
onTertiaryContainer = animateColor(targetColor = targetColorScheme.onTertiaryContainer),
|
||||
error = animateColor(targetColor = targetColorScheme.error),
|
||||
errorContainer = animateColor(targetColor = targetColorScheme.errorContainer),
|
||||
onError = animateColor(targetColor = targetColorScheme.onError),
|
||||
onErrorContainer = animateColor(targetColor = targetColorScheme.onErrorContainer),
|
||||
background = animateColor(targetColor = targetColorScheme.background),
|
||||
onBackground = animateColor(targetColor = targetColorScheme.onBackground),
|
||||
surface = animateColor(targetColor = targetColorScheme.surface),
|
||||
onSurface = animateColor(targetColor = targetColorScheme.onSurface),
|
||||
surfaceVariant = animateColor(targetColor = targetColorScheme.surfaceVariant),
|
||||
onSurfaceVariant = animateColor(targetColor = targetColorScheme.onSurfaceVariant),
|
||||
outline = animateColor(targetColor = targetColorScheme.outline),
|
||||
inverseOnSurface = animateColor(targetColor = targetColorScheme.inverseOnSurface),
|
||||
inverseSurface = animateColor(targetColor = targetColorScheme.inverseSurface),
|
||||
inversePrimary = animateColor(targetColor = targetColorScheme.inversePrimary),
|
||||
surfaceTint = animateColor(targetColor = targetColorScheme.surfaceTint),
|
||||
outlineVariant = animateColor(targetColor = targetColorScheme.outlineVariant),
|
||||
scrim = animateColor(targetColor = targetColorScheme.scrim),
|
||||
surfaceBright = animateColor(targetColor = targetColorScheme.surfaceBright),
|
||||
surfaceDim = animateColor(targetColor = targetColorScheme.surfaceDim),
|
||||
surfaceContainer = animateColor(targetColor = targetColorScheme.surfaceContainer),
|
||||
surfaceContainerHigh = animateColor(targetColor = targetColorScheme.surfaceContainerHigh),
|
||||
surfaceContainerHighest = animateColor(targetColor = targetColorScheme.surfaceContainerHighest),
|
||||
surfaceContainerLow = animateColor(targetColor = targetColorScheme.surfaceContainerLow),
|
||||
surfaceContainerLowest = animateColor(targetColor = targetColorScheme.surfaceContainerLowest),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun animatedColorScheme(
|
||||
theme: Theme,
|
||||
isDark: Boolean,
|
||||
isPureDark: Boolean,
|
||||
themeContrast: ThemeContrast
|
||||
): ColorScheme {
|
||||
val colorScheme = colorScheme(
|
||||
theme = theme,
|
||||
darkTheme = isDark,
|
||||
isPureDark = isPureDark,
|
||||
themeContrast = themeContrast
|
||||
)
|
||||
|
||||
return animateColorScheme(targetColorScheme = colorScheme)
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Book's Story — free and open-source Material You eBook reader.
|
||||
* Copyright (C) 2024-2025 Acclorite
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
package ua.acclorite.book_story.ui.theme
|
||||
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val ColorScheme.readerBarsColor: Color
|
||||
get() = surfaceContainer.copy(0.9f)
|
||||
|
||||
@Composable
|
||||
fun ColorScheme.dynamicListItemColor(
|
||||
index: Int
|
||||
): Color {
|
||||
return when (index % 3) {
|
||||
0 -> surfaceContainerLow
|
||||
1 -> surfaceContainerHigh
|
||||
else -> surfaceContainer
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
|
||||
private val primaryLight = Color(0xFF116682)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
|
||||
private val primaryLight = Color(0xFF485D92)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
private val primaryLight = Color(0xFF306A42)
|
||||
private val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
private val primaryLight = Color(0xFF824C76)
|
||||
private val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
private val primaryLight = Color(0xFF006A65)
|
||||
private val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
private val primaryLight = Color(0xFF8C4A60)
|
||||
private val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
private val primaryLight = Color(0xFF725188)
|
||||
private val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
private val primaryLight = Color(0xFF904A42)
|
||||
private val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import androidx.compose.material3.darkColorScheme
|
|||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.ui.theme.ThemeContrast
|
||||
import ua.acclorite.book_story.domain.ui.ThemeContrast
|
||||
|
||||
private val primaryLight = Color(0xFF845415)
|
||||
private val onPrimaryLight = Color(0xFFFFFFFF)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue