diff --git a/app/src/main/java/ua/acclorite/book_story/domain/navigator/Navigator.kt b/app/src/main/java/ua/acclorite/book_story/domain/navigator/Navigator.kt index 4c7aaac9..06620f37 100644 --- a/app/src/main/java/ua/acclorite/book_story/domain/navigator/Navigator.kt +++ b/app/src/main/java/ua/acclorite/book_story/domain/navigator/Navigator.kt @@ -17,7 +17,6 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -import kotlin.collections.plus @HiltViewModel(assistedFactory = Navigator.Factory::class) class Navigator @AssistedInject constructor( 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 d6eda79a..264a463e 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 @@ -50,6 +50,7 @@ object DataStoreConstants { val HORIZONTAL_GESTURE = stringPreferencesKey("horizontal_gesture") val HORIZONTAL_GESTURE_SCROLL = doublePreferencesKey("horizontal_gesture_scroll") val HORIZONTAL_GESTURE_SENSITIVITY = doublePreferencesKey("horizontal_gesture_sensitivity") + val HORIZONTAL_GESTURE_ALPHA_ANIM = doublePreferencesKey("horizontal_gesture_alpha_anim") val BOTTOM_BAR_PADDING = intPreferencesKey("bottom_bar_padding") val HIGHLIGHTED_READING = booleanPreferencesKey("highlighted_reading") val HIGHLIGHTED_READING_THICKNESS = intPreferencesKey("highlighted_reading_thickness") 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 4e754d05..6817905c 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 @@ -57,6 +57,7 @@ fun ReaderContent( horizontalGesture: ReaderHorizontalGesture, horizontalGestureScroll: Float, horizontalGestureSensitivity: Dp, + horizontalGestureAlphaAnim: Float, highlightedReading: Boolean, highlightedReadingThickness: FontWeight, progress: String, @@ -133,6 +134,7 @@ fun ReaderContent( horizontalGesture = horizontalGesture, horizontalGestureScroll = horizontalGestureScroll, horizontalGestureSensitivity = horizontalGestureSensitivity, + horizontalGestureAlphaAnim = horizontalGestureAlphaAnim, highlightedReading = highlightedReading, highlightedReadingThickness = highlightedReadingThickness, progress = progress, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderHorizontalGesture.kt b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderHorizontalGesture.kt index 2d836687..3b1c623f 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderHorizontalGesture.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/reader/ReaderHorizontalGesture.kt @@ -34,11 +34,13 @@ fun Modifier.readerHorizontalGesture( horizontalGesture: ReaderHorizontalGesture, horizontalGestureScroll: Float, horizontalGestureSensitivity: Dp, + horizontalGestureAlphaAnim: Float, isLoading: Boolean ): Modifier { if (horizontalGesture == ReaderHorizontalGesture.OFF || isLoading) return this val inverted = rememberUpdatedState(horizontalGesture == ReaderHorizontalGesture.INVERSE) val sensitivity = rememberUpdatedState(horizontalGestureSensitivity) + val alphaAnim = rememberUpdatedState(horizontalGestureAlphaAnim) val scope = rememberCoroutineScope() val density = LocalDensity.current @@ -69,7 +71,9 @@ fun Modifier.readerHorizontalGesture( @Composable fun calculateAlpha(): Float { return animateFloatAsState( - 1f - (abs(with(density) { horizontalOffset.floatValue.toDp() }.value) / sensitivity.value.value) + 1f - abs(with(density) { horizontalOffset.floatValue.toDp() }.value) + .div(sensitivity.value.value) + .times(alphaAnim.value) ).value } @@ -89,7 +93,7 @@ fun Modifier.readerHorizontalGesture( onDragStart = { horizontalOffset.floatValue = 0f }, - onHorizontalDrag = { change, dragAmount -> + onHorizontalDrag = { _, dragAmount -> horizontalOffset.floatValue += (dragAmount * 0.15f) }, onDragCancel = { 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 b6fc23fd..9651ecf4 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 @@ -57,6 +57,7 @@ fun ReaderLayout( horizontalGesture: ReaderHorizontalGesture, horizontalGestureScroll: Float, horizontalGestureSensitivity: Dp, + horizontalGestureAlphaAnim: Float, highlightedReading: Boolean, highlightedReadingThickness: FontWeight, progress: String, @@ -162,6 +163,7 @@ fun ReaderLayout( horizontalGesture = horizontalGesture, horizontalGestureScroll = horizontalGestureScroll, horizontalGestureSensitivity = horizontalGestureSensitivity, + horizontalGestureAlphaAnim = horizontalGestureAlphaAnim, isLoading = isLoading ) ) { @@ -181,7 +183,7 @@ fun ReaderLayout( ) { itemsIndexed( text, - key = { index, entry -> index } + key = { index, _ -> index } ) { index, entry -> when { !images && entry is ReaderText.Image -> return@itemsIndexed 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 7913fd31..7bd62065 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 @@ -61,6 +61,7 @@ fun ReaderScaffold( horizontalGesture: ReaderHorizontalGesture, horizontalGestureScroll: Float, horizontalGestureSensitivity: Dp, + horizontalGestureAlphaAnim: Float, highlightedReading: Boolean, highlightedReadingThickness: FontWeight, progress: String, @@ -164,6 +165,7 @@ fun ReaderScaffold( horizontalGesture = horizontalGesture, horizontalGestureScroll = horizontalGestureScroll, horizontalGestureSensitivity = horizontalGestureSensitivity, + horizontalGestureAlphaAnim = horizontalGestureAlphaAnim, highlightedReading = highlightedReading, highlightedReadingThickness = highlightedReadingThickness, progress = progress, diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/reading_mode/ReadingModeSubcategory.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/reading_mode/ReadingModeSubcategory.kt index 56ce341d..d7987838 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/reading_mode/ReadingModeSubcategory.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/reading_mode/ReadingModeSubcategory.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.Color 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.reading_mode.components.HorizontalGestureAlphaAnimOption import ua.acclorite.book_story.presentation.settings.reader.reading_mode.components.HorizontalGestureOption import ua.acclorite.book_story.presentation.settings.reader.reading_mode.components.HorizontalGestureScrollOption import ua.acclorite.book_story.presentation.settings.reader.reading_mode.components.HorizontalGestureSensitivityOption @@ -42,5 +43,9 @@ fun LazyListScope.ReadingModeSubcategory( item { HorizontalGestureSensitivityOption() } + + item { + HorizontalGestureAlphaAnimOption() + } } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/reading_mode/components/HorizontalGestureAlphaAnimOption.kt b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/reading_mode/components/HorizontalGestureAlphaAnimOption.kt new file mode 100644 index 00000000..7768ecfd --- /dev/null +++ b/app/src/main/java/ua/acclorite/book_story/presentation/settings/reader/reading_mode/components/HorizontalGestureAlphaAnimOption.kt @@ -0,0 +1,42 @@ +/* + * 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.presentation.settings.reader.reading_mode.components + +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.ReaderHorizontalGesture +import ua.acclorite.book_story.presentation.core.components.settings.SliderWithTitle +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 HorizontalGestureAlphaAnimOption() { + val mainModel = hiltViewModel() + val state = mainModel.state.collectAsStateWithLifecycle() + + ExpandingTransition( + visible = when (state.value.horizontalGesture) { + ReaderHorizontalGesture.OFF -> false + else -> true + } + ) { + SliderWithTitle( + value = state.value.horizontalGestureAlphaAnim to "%", + toValue = 100, + title = stringResource(id = R.string.horizontal_gesture_alpha_anim_option), + onValueChange = { + mainModel.onEvent( + MainEvent.OnChangeHorizontalGestureAlphaAnim(it) + ) + } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt index d5c1153d..7616b44d 100644 --- a/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt +++ b/app/src/main/java/ua/acclorite/book_story/ui/browse/BrowseModel.kt @@ -32,7 +32,6 @@ import ua.acclorite.book_story.domain.use_case.file_system.GetFiles import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.ui.library.LibraryScreen import javax.inject.Inject -import kotlin.collections.map @HiltViewModel class BrowseModel @Inject constructor( 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 09e9dbcd..cbc6294f 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 @@ -65,4 +65,5 @@ sealed class MainEvent { data class OnChangeBrowsePinnedPaths(val value: String) : MainEvent() data class OnChangeFontThickness(val value: String) : MainEvent() data class OnChangeProgressCount(val value: String) : MainEvent() + data class OnChangeHorizontalGestureAlphaAnim(val value: Float) : 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 216e9057..79f917f0 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 @@ -499,6 +499,14 @@ class MainModel @Inject constructor( it.copy(progressCount = this.toProgressCount()) } ) + + is MainEvent.OnChangeHorizontalGestureAlphaAnim -> handleDatastoreUpdate( + key = DataStoreConstants.HORIZONTAL_GESTURE_ALPHA_ANIM, + value = event.value.toDouble(), + updateState = { + it.copy(horizontalGestureAlphaAnim = this.toFloat()) + } + ) } } 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 94d24102..48b14e46 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 @@ -101,6 +101,7 @@ data class MainState( }, val horizontalGestureScroll: Float = provideDefaultValue { 0.7f }, val horizontalGestureSensitivity: Float = provideDefaultValue { 0.6f }, + val horizontalGestureAlphaAnim: Float = provideDefaultValue { 1f }, val bottomBarPadding: Int = provideDefaultValue { 0 }, val highlightedReading: Boolean = provideDefaultValue { false }, val highlightedReadingThickness: Int = provideDefaultValue { 2 }, @@ -365,6 +366,10 @@ data class MainState( progressCount = provideValue( PROGRESS_COUNT, convert = { toProgressCount() } ) { progressCount }, + + horizontalGestureAlphaAnim = provideValue( + HORIZONTAL_GESTURE_ALPHA_ANIM, convert = { toFloat() } + ) { horizontalGestureAlphaAnim }, ) } } 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 87b444ce..9b733fe6 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 @@ -425,6 +425,7 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable { horizontalGesture = mainState.value.horizontalGesture, horizontalGestureScroll = mainState.value.horizontalGestureScroll, horizontalGestureSensitivity = horizontalGestureSensitivity, + horizontalGestureAlphaAnim = mainState.value.horizontalGestureAlphaAnim, highlightedReading = mainState.value.highlightedReading, highlightedReadingThickness = highlightedReadingThickness, progress = progress, diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 7b11bc67..9e822402 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -186,6 +186,7 @@ Горизонтальний жест Частка прокрутки Чутливість + Анімувати видимість Відступ нижньої панелі Підсвічування слів Підсвічувати початок кожного слова diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 367151e1..93f825fb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -217,6 +217,7 @@ Horizontal gesture Scroll fraction Sensitivity + Animate visibility Bottom bar margin Highlight words Highlight the beginning of each word