🚀 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.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlin.collections.plus
|
||||
|
||||
@HiltViewModel(assistedFactory = Navigator.Factory::class)
|
||||
class Navigator @AssistedInject constructor(
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.ui.library.LibraryScreen
|
||||
import javax.inject.Inject
|
||||
import kotlin.collections.map
|
||||
|
||||
@HiltViewModel
|
||||
class BrowseModel @Inject constructor(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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())
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@
|
|||
<string name="horizontal_gesture_option">Горизонтальний жест</string>
|
||||
<string name="horizontal_gesture_scroll_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="highlighted_reading_option">Підсвічування слів</string>
|
||||
<string name="highlighted_reading_option_desc">Підсвічувати початок кожного слова</string>
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@
|
|||
<string name="horizontal_gesture_option">Horizontal gesture</string>
|
||||
<string name="horizontal_gesture_scroll_option">Scroll fraction</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="highlighted_reading_option">Highlight words</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