From 67a5f12b6a24d5937809522b2f91e8b9f5d730f2 Mon Sep 17 00:00:00 2001 From: Acclorite <140836141+Acclorite@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:00:35 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Images=20Color=20Effects=20optio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Different color effects (Grayscale, Font Color, Background Color) Part-of: #69 --- .../domain/reader/ReaderColorEffects.kt | 12 ++++ .../core/constants/DataStoreConstants.kt | 1 + .../presentation/reader/ReaderContent.kt | 3 + .../presentation/reader/ReaderLayout.kt | 3 + .../presentation/reader/ReaderLayoutText.kt | 5 +- .../reader/ReaderLayoutTextImage.kt | 5 +- .../presentation/reader/ReaderScaffold.kt | 3 + .../reader/images/ImagesSubcategory.kt | 5 ++ .../components/ImagesColorEffectsOption.kt | 57 +++++++++++++++++++ .../acclorite/book_story/ui/main/MainEvent.kt | 1 + .../acclorite/book_story/ui/main/MainModel.kt | 9 +++ .../acclorite/book_story/ui/main/MainState.kt | 7 +++ .../book_story/ui/reader/ReaderScreen.kt | 28 +++++++++ app/src/main/res/values-uk/strings.xml | 7 +++ app/src/main/res/values/strings.xml | 7 +++ 15 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/ua/acclorite/book_story/domain/reader/ReaderColorEffects.kt create mode 100644 app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/components/ImagesColorEffectsOption.kt diff --git a/app/src/main/java/ua/acclorite/book_story/domain/reader/ReaderColorEffects.kt b/app/src/main/java/ua/acclorite/book_story/domain/reader/ReaderColorEffects.kt new file mode 100644 index 00000000..927c211d --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/domain/reader/ReaderColorEffects.kt @@ -0,0 +1,12 @@ +package ua.acclorite.book_story.domain.reader + +enum class ReaderColorEffects { + OFF, + GRAYSCALE, + FONT, + BACKGROUND +} + +fun String.toColorEffects(): ReaderColorEffects { + return ReaderColorEffects.valueOf(this) +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt b/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt index f546edaf..8e4a6c80 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/core/constants/DataStoreConstants.kt @@ -52,6 +52,7 @@ object DataStoreConstants { val IMAGES_CORNERS_ROUNDNESS = intPreferencesKey("images_corners_roundness") val IMAGES_ALIGNMENT = stringPreferencesKey("images_alignment") val IMAGES_WIDTH = doublePreferencesKey("images_width") + val IMAGES_COLOR_EFFECTS = stringPreferencesKey("images_color_effects") // Browse settings val BROWSE_FILES_STRUCTURE = stringPreferencesKey("browse_files_structure") diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt index 17ad836d..c2c4e6b9 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderContent.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight @@ -60,6 +61,7 @@ fun ReaderContent( imagesCornersRoundness: Dp, imagesAlignment: ReaderImagesAlignment, imagesWidth: Float, + imagesColorEffects: ColorFilter?, fontFamily: FontWithName, lineHeight: TextUnit, fontStyle: FontStyle, @@ -129,6 +131,7 @@ fun ReaderContent( imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = imagesAlignment, imagesWidth = imagesWidth, + imagesColorEffects = imagesColorEffects, fontFamily = fontFamily, lineHeight = lineHeight, fontStyle = fontStyle, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt index 7711aceb..a9d97380 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayout.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp @@ -53,6 +54,7 @@ fun ReaderLayout( imagesCornersRoundness: Dp, imagesAlignment: ReaderImagesAlignment, imagesWidth: Float, + imagesColorEffects: ColorFilter?, fontFamily: FontWithName, lineHeight: TextUnit, fontStyle: FontStyle, @@ -172,6 +174,7 @@ fun ReaderLayout( imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = imagesAlignment, imagesWidth = imagesWidth, + imagesColorEffects = imagesColorEffects, fontFamily = fontFamily, fontColor = fontColor, lineHeight = lineHeight, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt index 85d1bccc..fbeadad4 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutText.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp @@ -23,6 +24,7 @@ fun LazyItemScope.ReaderLayoutText( imagesCornersRoundness: Dp, imagesAlignment: ReaderImagesAlignment, imagesWidth: Float, + imagesColorEffects: ColorFilter?, fontFamily: FontWithName, fontColor: Color, lineHeight: TextUnit, @@ -49,7 +51,8 @@ fun LazyItemScope.ReaderLayoutText( sidePadding = sidePadding, imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = imagesAlignment, - imagesWidth = imagesWidth + imagesWidth = imagesWidth, + imagesColorEffects = imagesColorEffects ) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutTextImage.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutTextImage.kt index f8a8d831..be28733f 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutTextImage.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderLayoutTextImage.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.Dp import ua.acclorite.book_story.domain.reader.ReaderImagesAlignment @@ -20,7 +21,8 @@ fun LazyItemScope.ReaderLayoutTextImage( sidePadding: Dp, imagesCornersRoundness: Dp, imagesAlignment: ReaderImagesAlignment, - imagesWidth: Float + imagesWidth: Float, + imagesColorEffects: ColorFilter? ) { Box( modifier = Modifier @@ -38,6 +40,7 @@ fun LazyItemScope.ReaderLayoutTextImage( .fillMaxWidth(imagesWidth), bitmap = entry.imageBitmap, contentDescription = null, + colorFilter = imagesColorEffects, contentScale = ContentScale.FillWidth ) } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt index cd96ec9b..0db920b1 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderScaffold.kt @@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.text.font.FontStyle @@ -64,6 +65,7 @@ fun ReaderScaffold( imagesCornersRoundness: Dp, imagesAlignment: ReaderImagesAlignment, imagesWidth: Float, + imagesColorEffects: ColorFilter?, fontFamily: FontWithName, lineHeight: TextUnit, fontStyle: FontStyle, @@ -160,6 +162,7 @@ fun ReaderScaffold( imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = imagesAlignment, imagesWidth = imagesWidth, + imagesColorEffects = imagesColorEffects, fontFamily = fontFamily, lineHeight = lineHeight, fontStyle = fontStyle, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/ImagesSubcategory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/ImagesSubcategory.kt index 2fabcdea..e933f1b6 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/ImagesSubcategory.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/ImagesSubcategory.kt @@ -10,6 +10,7 @@ import androidx.compose.ui.res.stringResource import ua.acclorite.book_story.R import ua.acclorite.book_story.presentation.settings.components.SettingsSubcategory import ua.acclorite.book_story.presentation.settings.reader.images.components.ImagesAlignmentOption +import ua.acclorite.book_story.presentation.settings.reader.images.components.ImagesColorEffectsOption import ua.acclorite.book_story.presentation.settings.reader.images.components.ImagesCornersRoundnessOption import ua.acclorite.book_story.presentation.settings.reader.images.components.ImagesOption import ua.acclorite.book_story.presentation.settings.reader.images.components.ImagesWidthOption @@ -30,6 +31,10 @@ fun LazyListScope.ImagesSubcategory( ImagesOption() } + item { + ImagesColorEffectsOption() + } + item { ImagesCornersRoundnessOption() } diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/components/ImagesColorEffectsOption.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/components/ImagesColorEffectsOption.kt new file mode 100644 index 00000000..b8138e20 --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/images/components/ImagesColorEffectsOption.kt @@ -0,0 +1,57 @@ +package ua.acclorite.book_story.presentation.settings.reader.images.components + +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +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.reader.ReaderColorEffects +import ua.acclorite.book_story.domain.ui.ButtonItem +import ua.acclorite.book_story.presentation.core.components.settings.ChipsWithTitle +import ua.acclorite.book_story.ui.main.MainEvent +import ua.acclorite.book_story.ui.main.MainModel +import ua.acclorite.book_story.ui.theme.ExpandingTransition + +@Composable +fun ImagesColorEffectsOption() { + val mainModel = hiltViewModel() + val state = mainModel.state.collectAsStateWithLifecycle() + + ExpandingTransition(visible = state.value.images) { + ChipsWithTitle( + title = stringResource(id = R.string.images_color_effects_option), + chips = ReaderColorEffects.entries.map { + ButtonItem( + id = it.toString(), + title = when (it) { + ReaderColorEffects.OFF -> { + stringResource(R.string.color_effects_off) + } + + ReaderColorEffects.GRAYSCALE -> { + stringResource(R.string.color_effects_grayscale) + } + + ReaderColorEffects.FONT -> { + stringResource(R.string.color_effects_font) + } + + ReaderColorEffects.BACKGROUND -> { + stringResource(R.string.color_effects_background) + } + }, + textStyle = MaterialTheme.typography.labelLarge, + selected = it == state.value.imagesColorEffects + ) + }, + onClick = { + mainModel.onEvent( + MainEvent.OnChangeImagesColorEffects( + it.id + ) + ) + } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt index 39f72ec9..e3a82e72 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainEvent.kt @@ -54,4 +54,5 @@ sealed class MainEvent { data class OnChangeImagesCornersRoundness(val value: Int) : MainEvent() data class OnChangeImagesAlignment(val value: String) : MainEvent() data class OnChangeImagesWidth(val value: Float) : MainEvent() + data class OnChangeImagesColorEffects(val value: String) : MainEvent() } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt index d63c7d64..458efcc3 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainModel.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.yield import ua.acclorite.book_story.domain.browse.toBrowseFilesStructure import ua.acclorite.book_story.domain.browse.toBrowseLayout import ua.acclorite.book_story.domain.browse.toBrowseSortOrder +import ua.acclorite.book_story.domain.reader.toColorEffects import ua.acclorite.book_story.domain.reader.toHorizontalGesture import ua.acclorite.book_story.domain.reader.toImagesAlignment import ua.acclorite.book_story.domain.reader.toReaderScreenOrientation @@ -455,6 +456,14 @@ class MainModel @Inject constructor( it.copy(imagesWidth = this.toFloat()) } ) + + is MainEvent.OnChangeImagesColorEffects -> handleDatastoreUpdate( + key = DataStoreConstants.IMAGES_COLOR_EFFECTS, + value = event.value, + updateState = { + it.copy(imagesColorEffects = this.toColorEffects()) + } + ) } } diff --git a/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt b/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt index 86b5fb81..bd01b485 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/main/MainState.kt @@ -13,10 +13,12 @@ import ua.acclorite.book_story.domain.browse.BrowseSortOrder import ua.acclorite.book_story.domain.browse.toBrowseFilesStructure import ua.acclorite.book_story.domain.browse.toBrowseLayout import ua.acclorite.book_story.domain.browse.toBrowseSortOrder +import ua.acclorite.book_story.domain.reader.ReaderColorEffects import ua.acclorite.book_story.domain.reader.ReaderHorizontalGesture import ua.acclorite.book_story.domain.reader.ReaderImagesAlignment import ua.acclorite.book_story.domain.reader.ReaderScreenOrientation import ua.acclorite.book_story.domain.reader.ReaderTextAlignment +import ua.acclorite.book_story.domain.reader.toColorEffects import ua.acclorite.book_story.domain.reader.toHorizontalGesture import ua.acclorite.book_story.domain.reader.toImagesAlignment import ua.acclorite.book_story.domain.reader.toReaderScreenOrientation @@ -99,6 +101,7 @@ data class MainState( val imagesCornersRoundness: Int = provideDefaultValue { 8 }, val imagesAlignment: ReaderImagesAlignment = provideDefaultValue { ReaderImagesAlignment.START }, val imagesWidth: Float = provideDefaultValue { 0.8f }, + val imagesColorEffects: ReaderColorEffects = provideDefaultValue { ReaderColorEffects.OFF }, // Browse Settings val browseFilesStructure: BrowseFilesStructure = provideDefaultValue { @@ -332,6 +335,10 @@ data class MainState( imagesWidth = provideValue( IMAGES_WIDTH, convert = { toFloat() } ) { imagesWidth }, + + imagesColorEffects = provideValue( + IMAGES_COLOR_EFFECTS, convert = { toColorEffects() } + ) { imagesColorEffects }, ) } } diff --git a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt index 035c4965..be38d376 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/reader/ReaderScreen.kt @@ -21,6 +21,9 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.platform.LocalDensity @@ -36,6 +39,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import kotlinx.parcelize.Parcelize import ua.acclorite.book_story.domain.navigator.Screen +import ua.acclorite.book_story.domain.reader.ReaderColorEffects import ua.acclorite.book_story.domain.reader.ReaderTextAlignment import ua.acclorite.book_story.presentation.core.constants.Constants import ua.acclorite.book_story.presentation.core.constants.provideFonts @@ -193,6 +197,29 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable { ) { (mainState.value.imagesCornersRoundness * 3 * imagesWidth).dp } + val imagesColorEffects = remember( + mainState.value.imagesColorEffects, + fontColor.value, + backgroundColor.value + ) { + when (mainState.value.imagesColorEffects) { + ReaderColorEffects.OFF -> null + + ReaderColorEffects.GRAYSCALE -> ColorFilter.colorMatrix( + ColorMatrix().apply { setToSaturation(0f) } + ) + + ReaderColorEffects.FONT -> ColorFilter.tint( + color = fontColor.value, + blendMode = BlendMode.Color + ) + + ReaderColorEffects.BACKGROUND -> ColorFilter.tint( + color = backgroundColor.value, + blendMode = BlendMode.Color + ) + } + } val layoutDirection = LocalLayoutDirection.current val cutoutInsets = WindowInsets.displayCutout @@ -350,6 +377,7 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable { imagesCornersRoundness = imagesCornersRoundness, imagesAlignment = mainState.value.imagesAlignment, imagesWidth = imagesWidth, + imagesColorEffects = imagesColorEffects, fontFamily = fontFamily, lineHeight = lineHeight, fontStyle = fontStyle, diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 0719340b..135907f3 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -202,6 +202,7 @@ Округлість кутків Розташування Розмір + Ефекти кольору Структура файлів @@ -275,6 +276,12 @@ рівень + + Вимкнені + Відтінки сірого + Колір шрифта + Колір фона + Меркурій Нептун diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fe3b4ac9..96ef64e0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -257,6 +257,7 @@ Corners roundness Alignment Size + Color effects Files structure @@ -332,6 +333,12 @@ level + + Off + Grayscale + Font color + Background color + Mercury Neptune