🚀 Absolute Dark setting
* Added new "Absolute Dark" setting, which darkens "Pure Dark" theme even more, giving it completely black color as background * May be more suitable for OLED screen users, while default "Pure Dark" may be better for non-OLED display users
This commit is contained in:
parent
be9b28834c
commit
63bb317865
9 changed files with 100 additions and 46 deletions
|
|
@ -11,6 +11,7 @@ object DataStoreConstants {
|
|||
val THEME = stringPreferencesKey("theme")
|
||||
val DARK_THEME = stringPreferencesKey("dark_theme")
|
||||
val PURE_DARK = stringPreferencesKey("pure_dark")
|
||||
val ABSOLUTE_DARK = booleanPreferencesKey("absolute_dark")
|
||||
val THEME_CONTRAST = stringPreferencesKey("theme_contrast")
|
||||
val SHOW_START_SCREEN = booleanPreferencesKey("guide")
|
||||
val CHECK_FOR_UPDATES = booleanPreferencesKey("check_for_updates")
|
||||
|
|
|
|||
|
|
@ -31,4 +31,5 @@ sealed class MainEvent {
|
|||
data class OnChangeTextAlignment(val alignment: String) : MainEvent()
|
||||
data class OnChangeDoublePressExit(val bool: Boolean) : MainEvent()
|
||||
data class OnChangeLetterSpacing(val spacing: Int) : MainEvent()
|
||||
data class OnChangeAbsoluteDark(val bool: Boolean) : MainEvent()
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@ data class MainState(
|
|||
},
|
||||
val darkTheme: DarkTheme = provideDefaultValue { DarkTheme.FOLLOW_SYSTEM },
|
||||
val pureDark: PureDark = provideDefaultValue { PureDark.OFF },
|
||||
val absoluteDark: Boolean = provideDefaultValue { false },
|
||||
val themeContrast: ThemeContrast = provideDefaultValue { ThemeContrast.STANDARD },
|
||||
val showStartScreen: Boolean = provideDefaultValue { true },
|
||||
val checkForUpdates: Boolean = provideDefaultValue { false },
|
||||
|
|
@ -118,6 +119,10 @@ data class MainState(
|
|||
PURE_DARK, convert = { toPureDark() }
|
||||
) { pureDark },
|
||||
|
||||
absoluteDark = provideValue(
|
||||
ABSOLUTE_DARK
|
||||
) { absoluteDark },
|
||||
|
||||
themeContrast = provideValue(
|
||||
THEME_CONTRAST, convert = { toThemeContrast() }
|
||||
) { themeContrast },
|
||||
|
|
|
|||
|
|
@ -373,6 +373,20 @@ class MainViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
is MainEvent.OnChangeAbsoluteDark -> {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
setDatastore.execute(
|
||||
DataStoreConstants.ABSOLUTE_DARK,
|
||||
event.bool
|
||||
)
|
||||
updateStateWithSavedHandle {
|
||||
it.copy(
|
||||
absoluteDark = event.bool
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.settings
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel
|
||||
import ua.acclorite.book_story.presentation.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.SwitchWithTitle
|
||||
import ua.acclorite.book_story.presentation.ui.ExpandingTransition
|
||||
import ua.acclorite.book_story.presentation.ui.isPureDark
|
||||
|
||||
/**
|
||||
* Absolute Dark setting.
|
||||
* If true, changes Pure Dark (OLED) theme to have black color as background.
|
||||
*/
|
||||
@Composable
|
||||
fun AbsoluteDarkSetting() {
|
||||
val state = LocalMainViewModel.current.state
|
||||
val onMainEvent = LocalMainViewModel.current.onEvent
|
||||
val context = LocalContext.current
|
||||
|
||||
ExpandingTransition(visible = state.value.pureDark.isPureDark(context)) {
|
||||
SwitchWithTitle(
|
||||
selected = state.value.absoluteDark,
|
||||
title = stringResource(id = R.string.absolute_dark_option),
|
||||
description = stringResource(id = R.string.absolute_dark_option_desc),
|
||||
onClick = {
|
||||
onMainEvent(
|
||||
MainEvent.OnChangeAbsoluteDark(
|
||||
!state.value.absoluteDark
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import androidx.compose.ui.unit.coerceAtLeast
|
|||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.settings.AbsoluteDarkSetting
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.settings.DarkThemeSetting
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.settings.PureDarkSetting
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.settings.ThemeContrastSetting
|
||||
|
|
@ -66,6 +67,10 @@ fun LazyListScope.ThemePreferencesSubcategory(
|
|||
PureDarkSetting()
|
||||
}
|
||||
|
||||
item {
|
||||
AbsoluteDarkSetting()
|
||||
}
|
||||
|
||||
item {
|
||||
Spacer(
|
||||
modifier = Modifier.height(bottomPadding)
|
||||
|
|
|
|||
|
|
@ -3,61 +3,48 @@ package ua.acclorite.book_story.presentation.ui.theme
|
|||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel
|
||||
|
||||
@Composable
|
||||
fun blackTheme(initialTheme: ColorScheme): ColorScheme {
|
||||
val absoluteDark = LocalMainViewModel.current.state.value.absoluteDark
|
||||
val surfaceDarker = 3f
|
||||
val surfaceContainerDarker = if (absoluteDark) 3f else 1.95f
|
||||
|
||||
return initialTheme.copy(
|
||||
surface = initialTheme.surface.copy {
|
||||
val darker = 3f
|
||||
it.copy(
|
||||
red = it.red / darker,
|
||||
green = it.green / darker,
|
||||
blue = it.blue / darker
|
||||
)
|
||||
if (absoluteDark) {
|
||||
return@copy Color.Black
|
||||
}
|
||||
|
||||
it.darkenBy(surfaceDarker)
|
||||
},
|
||||
surfaceContainer = initialTheme.surfaceContainer.copy {
|
||||
val darker = 1.95f
|
||||
it.copy(
|
||||
red = it.red / darker,
|
||||
green = it.green / darker,
|
||||
blue = it.blue / darker
|
||||
surfaceContainer = initialTheme.surfaceContainer.darkenBy(
|
||||
surfaceContainerDarker
|
||||
),
|
||||
surfaceContainerLowest = initialTheme.surfaceContainerLowest.darkenBy(
|
||||
surfaceContainerDarker
|
||||
),
|
||||
surfaceContainerLow = initialTheme.surfaceContainerLow.darkenBy(
|
||||
surfaceContainerDarker
|
||||
),
|
||||
surfaceContainerHigh = initialTheme.surfaceContainerHigh.darkenBy(
|
||||
surfaceContainerDarker
|
||||
),
|
||||
surfaceContainerHighest = initialTheme.surfaceContainerHighest.darkenBy(
|
||||
surfaceContainerDarker
|
||||
)
|
||||
},
|
||||
surfaceContainerLowest = initialTheme.surfaceContainerLowest.copy {
|
||||
val darker = 1.95f
|
||||
it.copy(
|
||||
red = it.red / darker,
|
||||
green = it.green / darker,
|
||||
blue = it.blue / darker
|
||||
)
|
||||
},
|
||||
surfaceContainerLow = initialTheme.surfaceContainerLow.copy {
|
||||
val darker = 1.95f
|
||||
it.copy(
|
||||
red = it.red / darker,
|
||||
green = it.green / darker,
|
||||
blue = it.blue / darker
|
||||
)
|
||||
},
|
||||
surfaceContainerHigh = initialTheme.surfaceContainerHigh.copy {
|
||||
val darker = 1.95f
|
||||
it.copy(
|
||||
red = it.red / darker,
|
||||
green = it.green / darker,
|
||||
blue = it.blue / darker
|
||||
)
|
||||
},
|
||||
surfaceContainerHighest = initialTheme.surfaceContainerHighest.copy {
|
||||
val darker = 1.95f
|
||||
it.copy(
|
||||
red = it.red / darker,
|
||||
green = it.green / darker,
|
||||
blue = it.blue / darker
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun Color.copy(calculation: (Color) -> Color): Color {
|
||||
return calculation(this)
|
||||
}
|
||||
|
||||
private fun Color.darkenBy(value: Float): Color {
|
||||
return copy(
|
||||
red = red / value,
|
||||
green = green / value,
|
||||
blue = blue / value
|
||||
)
|
||||
}
|
||||
|
|
@ -209,6 +209,8 @@
|
|||
<string name="language_option">Мова застосунка</string>
|
||||
<string name="dark_theme_option">Темна тема</string>
|
||||
<string name="pure_dark_option">Суцільна темрява (ОЛЕД)</string>
|
||||
<string name="absolute_dark_option">Абсолютна темрява</string>
|
||||
<string name="absolute_dark_option_desc">Змініть колір фона на повністю чорний</string>
|
||||
<string name="theme_contrast_option">Контрастність теми</string>
|
||||
<string name="app_theme_option">Тема застосунка</string>
|
||||
<string name="check_for_updates_option">Перевіряти на оновлення</string>
|
||||
|
|
|
|||
|
|
@ -226,6 +226,8 @@
|
|||
<string name="language_option">App language</string>
|
||||
<string name="dark_theme_option">Dark theme</string>
|
||||
<string name="pure_dark_option">Pure dark (OLED)</string>
|
||||
<string name="absolute_dark_option">Absolute dark</string>
|
||||
<string name="absolute_dark_option_desc">Change background color to be completely black</string>
|
||||
<string name="theme_contrast_option">Theme contrast</string>
|
||||
<string name="app_theme_option">App theme</string>
|
||||
<string name="check_for_updates_option">Check for updates</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue