🚀 Horizontal gesture "Animate visibility" option
* Option to change how much (in %) the visibility animates when using horizontal gesture
This commit is contained in:
parent
0fec497c1b
commit
78e7d710ea
15 changed files with 78 additions and 5 deletions
|
|
@ -17,7 +17,6 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlin.collections.plus
|
|
||||||
|
|
||||||
@HiltViewModel(assistedFactory = Navigator.Factory::class)
|
@HiltViewModel(assistedFactory = Navigator.Factory::class)
|
||||||
class Navigator @AssistedInject constructor(
|
class Navigator @AssistedInject constructor(
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ object DataStoreConstants {
|
||||||
val HORIZONTAL_GESTURE = stringPreferencesKey("horizontal_gesture")
|
val HORIZONTAL_GESTURE = stringPreferencesKey("horizontal_gesture")
|
||||||
val HORIZONTAL_GESTURE_SCROLL = doublePreferencesKey("horizontal_gesture_scroll")
|
val HORIZONTAL_GESTURE_SCROLL = doublePreferencesKey("horizontal_gesture_scroll")
|
||||||
val HORIZONTAL_GESTURE_SENSITIVITY = doublePreferencesKey("horizontal_gesture_sensitivity")
|
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 BOTTOM_BAR_PADDING = intPreferencesKey("bottom_bar_padding")
|
||||||
val HIGHLIGHTED_READING = booleanPreferencesKey("highlighted_reading")
|
val HIGHLIGHTED_READING = booleanPreferencesKey("highlighted_reading")
|
||||||
val HIGHLIGHTED_READING_THICKNESS = intPreferencesKey("highlighted_reading_thickness")
|
val HIGHLIGHTED_READING_THICKNESS = intPreferencesKey("highlighted_reading_thickness")
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ fun ReaderContent(
|
||||||
horizontalGesture: ReaderHorizontalGesture,
|
horizontalGesture: ReaderHorizontalGesture,
|
||||||
horizontalGestureScroll: Float,
|
horizontalGestureScroll: Float,
|
||||||
horizontalGestureSensitivity: Dp,
|
horizontalGestureSensitivity: Dp,
|
||||||
|
horizontalGestureAlphaAnim: Float,
|
||||||
highlightedReading: Boolean,
|
highlightedReading: Boolean,
|
||||||
highlightedReadingThickness: FontWeight,
|
highlightedReadingThickness: FontWeight,
|
||||||
progress: String,
|
progress: String,
|
||||||
|
|
@ -133,6 +134,7 @@ fun ReaderContent(
|
||||||
horizontalGesture = horizontalGesture,
|
horizontalGesture = horizontalGesture,
|
||||||
horizontalGestureScroll = horizontalGestureScroll,
|
horizontalGestureScroll = horizontalGestureScroll,
|
||||||
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
||||||
|
horizontalGestureAlphaAnim = horizontalGestureAlphaAnim,
|
||||||
highlightedReading = highlightedReading,
|
highlightedReading = highlightedReading,
|
||||||
highlightedReadingThickness = highlightedReadingThickness,
|
highlightedReadingThickness = highlightedReadingThickness,
|
||||||
progress = progress,
|
progress = progress,
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,13 @@ fun Modifier.readerHorizontalGesture(
|
||||||
horizontalGesture: ReaderHorizontalGesture,
|
horizontalGesture: ReaderHorizontalGesture,
|
||||||
horizontalGestureScroll: Float,
|
horizontalGestureScroll: Float,
|
||||||
horizontalGestureSensitivity: Dp,
|
horizontalGestureSensitivity: Dp,
|
||||||
|
horizontalGestureAlphaAnim: Float,
|
||||||
isLoading: Boolean
|
isLoading: Boolean
|
||||||
): Modifier {
|
): Modifier {
|
||||||
if (horizontalGesture == ReaderHorizontalGesture.OFF || isLoading) return this
|
if (horizontalGesture == ReaderHorizontalGesture.OFF || isLoading) return this
|
||||||
val inverted = rememberUpdatedState(horizontalGesture == ReaderHorizontalGesture.INVERSE)
|
val inverted = rememberUpdatedState(horizontalGesture == ReaderHorizontalGesture.INVERSE)
|
||||||
val sensitivity = rememberUpdatedState(horizontalGestureSensitivity)
|
val sensitivity = rememberUpdatedState(horizontalGestureSensitivity)
|
||||||
|
val alphaAnim = rememberUpdatedState(horizontalGestureAlphaAnim)
|
||||||
|
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
|
|
@ -69,7 +71,9 @@ fun Modifier.readerHorizontalGesture(
|
||||||
@Composable
|
@Composable
|
||||||
fun calculateAlpha(): Float {
|
fun calculateAlpha(): Float {
|
||||||
return animateFloatAsState(
|
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
|
).value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +93,7 @@ fun Modifier.readerHorizontalGesture(
|
||||||
onDragStart = {
|
onDragStart = {
|
||||||
horizontalOffset.floatValue = 0f
|
horizontalOffset.floatValue = 0f
|
||||||
},
|
},
|
||||||
onHorizontalDrag = { change, dragAmount ->
|
onHorizontalDrag = { _, dragAmount ->
|
||||||
horizontalOffset.floatValue += (dragAmount * 0.15f)
|
horizontalOffset.floatValue += (dragAmount * 0.15f)
|
||||||
},
|
},
|
||||||
onDragCancel = {
|
onDragCancel = {
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ fun ReaderLayout(
|
||||||
horizontalGesture: ReaderHorizontalGesture,
|
horizontalGesture: ReaderHorizontalGesture,
|
||||||
horizontalGestureScroll: Float,
|
horizontalGestureScroll: Float,
|
||||||
horizontalGestureSensitivity: Dp,
|
horizontalGestureSensitivity: Dp,
|
||||||
|
horizontalGestureAlphaAnim: Float,
|
||||||
highlightedReading: Boolean,
|
highlightedReading: Boolean,
|
||||||
highlightedReadingThickness: FontWeight,
|
highlightedReadingThickness: FontWeight,
|
||||||
progress: String,
|
progress: String,
|
||||||
|
|
@ -162,6 +163,7 @@ fun ReaderLayout(
|
||||||
horizontalGesture = horizontalGesture,
|
horizontalGesture = horizontalGesture,
|
||||||
horizontalGestureScroll = horizontalGestureScroll,
|
horizontalGestureScroll = horizontalGestureScroll,
|
||||||
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
||||||
|
horizontalGestureAlphaAnim = horizontalGestureAlphaAnim,
|
||||||
isLoading = isLoading
|
isLoading = isLoading
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
|
@ -181,7 +183,7 @@ fun ReaderLayout(
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
text,
|
text,
|
||||||
key = { index, entry -> index }
|
key = { index, _ -> index }
|
||||||
) { index, entry ->
|
) { index, entry ->
|
||||||
when {
|
when {
|
||||||
!images && entry is ReaderText.Image -> return@itemsIndexed
|
!images && entry is ReaderText.Image -> return@itemsIndexed
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ fun ReaderScaffold(
|
||||||
horizontalGesture: ReaderHorizontalGesture,
|
horizontalGesture: ReaderHorizontalGesture,
|
||||||
horizontalGestureScroll: Float,
|
horizontalGestureScroll: Float,
|
||||||
horizontalGestureSensitivity: Dp,
|
horizontalGestureSensitivity: Dp,
|
||||||
|
horizontalGestureAlphaAnim: Float,
|
||||||
highlightedReading: Boolean,
|
highlightedReading: Boolean,
|
||||||
highlightedReadingThickness: FontWeight,
|
highlightedReadingThickness: FontWeight,
|
||||||
progress: String,
|
progress: String,
|
||||||
|
|
@ -164,6 +165,7 @@ fun ReaderScaffold(
|
||||||
horizontalGesture = horizontalGesture,
|
horizontalGesture = horizontalGesture,
|
||||||
horizontalGestureScroll = horizontalGestureScroll,
|
horizontalGestureScroll = horizontalGestureScroll,
|
||||||
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
||||||
|
horizontalGestureAlphaAnim = horizontalGestureAlphaAnim,
|
||||||
highlightedReading = highlightedReading,
|
highlightedReading = highlightedReading,
|
||||||
highlightedReadingThickness = highlightedReadingThickness,
|
highlightedReadingThickness = highlightedReadingThickness,
|
||||||
progress = progress,
|
progress = progress,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.settings.components.SettingsSubcategory
|
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.HorizontalGestureOption
|
||||||
import ua.acclorite.book_story.presentation.settings.reader.reading_mode.components.HorizontalGestureScrollOption
|
import ua.acclorite.book_story.presentation.settings.reader.reading_mode.components.HorizontalGestureScrollOption
|
||||||
import ua.acclorite.book_story.presentation.settings.reader.reading_mode.components.HorizontalGestureSensitivityOption
|
import ua.acclorite.book_story.presentation.settings.reader.reading_mode.components.HorizontalGestureSensitivityOption
|
||||||
|
|
@ -42,5 +43,9 @@ fun LazyListScope.ReadingModeSubcategory(
|
||||||
item {
|
item {
|
||||||
HorizontalGestureSensitivityOption()
|
HorizontalGestureSensitivityOption()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item {
|
||||||
|
HorizontalGestureAlphaAnimOption()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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<MainModel>()
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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.presentation.core.util.showToast
|
||||||
import ua.acclorite.book_story.ui.library.LibraryScreen
|
import ua.acclorite.book_story.ui.library.LibraryScreen
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.collections.map
|
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class BrowseModel @Inject constructor(
|
class BrowseModel @Inject constructor(
|
||||||
|
|
|
||||||
|
|
@ -65,4 +65,5 @@ sealed class MainEvent {
|
||||||
data class OnChangeBrowsePinnedPaths(val value: String) : MainEvent()
|
data class OnChangeBrowsePinnedPaths(val value: String) : MainEvent()
|
||||||
data class OnChangeFontThickness(val value: String) : MainEvent()
|
data class OnChangeFontThickness(val value: String) : MainEvent()
|
||||||
data class OnChangeProgressCount(val value: String) : MainEvent()
|
data class OnChangeProgressCount(val value: String) : MainEvent()
|
||||||
|
data class OnChangeHorizontalGestureAlphaAnim(val value: Float) : MainEvent()
|
||||||
}
|
}
|
||||||
|
|
@ -499,6 +499,14 @@ class MainModel @Inject constructor(
|
||||||
it.copy(progressCount = this.toProgressCount())
|
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())
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ data class MainState(
|
||||||
},
|
},
|
||||||
val horizontalGestureScroll: Float = provideDefaultValue { 0.7f },
|
val horizontalGestureScroll: Float = provideDefaultValue { 0.7f },
|
||||||
val horizontalGestureSensitivity: Float = provideDefaultValue { 0.6f },
|
val horizontalGestureSensitivity: Float = provideDefaultValue { 0.6f },
|
||||||
|
val horizontalGestureAlphaAnim: Float = provideDefaultValue { 1f },
|
||||||
val bottomBarPadding: Int = provideDefaultValue { 0 },
|
val bottomBarPadding: Int = provideDefaultValue { 0 },
|
||||||
val highlightedReading: Boolean = provideDefaultValue { false },
|
val highlightedReading: Boolean = provideDefaultValue { false },
|
||||||
val highlightedReadingThickness: Int = provideDefaultValue { 2 },
|
val highlightedReadingThickness: Int = provideDefaultValue { 2 },
|
||||||
|
|
@ -365,6 +366,10 @@ data class MainState(
|
||||||
progressCount = provideValue(
|
progressCount = provideValue(
|
||||||
PROGRESS_COUNT, convert = { toProgressCount() }
|
PROGRESS_COUNT, convert = { toProgressCount() }
|
||||||
) { progressCount },
|
) { progressCount },
|
||||||
|
|
||||||
|
horizontalGestureAlphaAnim = provideValue(
|
||||||
|
HORIZONTAL_GESTURE_ALPHA_ANIM, convert = { toFloat() }
|
||||||
|
) { horizontalGestureAlphaAnim },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -425,6 +425,7 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable {
|
||||||
horizontalGesture = mainState.value.horizontalGesture,
|
horizontalGesture = mainState.value.horizontalGesture,
|
||||||
horizontalGestureScroll = mainState.value.horizontalGestureScroll,
|
horizontalGestureScroll = mainState.value.horizontalGestureScroll,
|
||||||
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
horizontalGestureSensitivity = horizontalGestureSensitivity,
|
||||||
|
horizontalGestureAlphaAnim = mainState.value.horizontalGestureAlphaAnim,
|
||||||
highlightedReading = mainState.value.highlightedReading,
|
highlightedReading = mainState.value.highlightedReading,
|
||||||
highlightedReadingThickness = highlightedReadingThickness,
|
highlightedReadingThickness = highlightedReadingThickness,
|
||||||
progress = progress,
|
progress = progress,
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,7 @@
|
||||||
<string name="horizontal_gesture_option">Горизонтальний жест</string>
|
<string name="horizontal_gesture_option">Горизонтальний жест</string>
|
||||||
<string name="horizontal_gesture_scroll_option">Частка прокрутки</string>
|
<string name="horizontal_gesture_scroll_option">Частка прокрутки</string>
|
||||||
<string name="horizontal_gesture_sensitivity_option">Чутливість</string>
|
<string name="horizontal_gesture_sensitivity_option">Чутливість</string>
|
||||||
|
<string name="horizontal_gesture_alpha_anim_option">Анімувати видимість</string>
|
||||||
<string name="bottom_bar_padding_option">Відступ нижньої панелі</string>
|
<string name="bottom_bar_padding_option">Відступ нижньої панелі</string>
|
||||||
<string name="highlighted_reading_option">Підсвічування слів</string>
|
<string name="highlighted_reading_option">Підсвічування слів</string>
|
||||||
<string name="highlighted_reading_option_desc">Підсвічувати початок кожного слова</string>
|
<string name="highlighted_reading_option_desc">Підсвічувати початок кожного слова</string>
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,7 @@
|
||||||
<string name="horizontal_gesture_option">Horizontal gesture</string>
|
<string name="horizontal_gesture_option">Horizontal gesture</string>
|
||||||
<string name="horizontal_gesture_scroll_option">Scroll fraction</string>
|
<string name="horizontal_gesture_scroll_option">Scroll fraction</string>
|
||||||
<string name="horizontal_gesture_sensitivity_option">Sensitivity</string>
|
<string name="horizontal_gesture_sensitivity_option">Sensitivity</string>
|
||||||
|
<string name="horizontal_gesture_alpha_anim_option">Animate visibility</string>
|
||||||
<string name="bottom_bar_padding_option">Bottom bar margin</string>
|
<string name="bottom_bar_padding_option">Bottom bar margin</string>
|
||||||
<string name="highlighted_reading_option">Highlight words</string>
|
<string name="highlighted_reading_option">Highlight words</string>
|
||||||
<string name="highlighted_reading_option_desc">Highlight the beginning of each word</string>
|
<string name="highlighted_reading_option_desc">Highlight the beginning of each word</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue