mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2026-01-18 08:43:56 +00:00
fix: Save FAB freaking out in select patches screen
This commit is contained in:
@@ -49,10 +49,12 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
@@ -81,9 +83,11 @@ import app.revanced.manager.util.Options
|
|||||||
import app.revanced.manager.util.PatchSelection
|
import app.revanced.manager.util.PatchSelection
|
||||||
import app.revanced.manager.util.isScrollingUp
|
import app.revanced.manager.util.isScrollingUp
|
||||||
import app.revanced.manager.util.transparentListItemColors
|
import app.revanced.manager.util.transparentListItemColors
|
||||||
|
import kotlinx.coroutines.FlowPreview
|
||||||
|
import kotlinx.coroutines.flow.sample
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class, FlowPreview::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun PatchesSelectorScreen(
|
fun PatchesSelectorScreen(
|
||||||
onSave: (PatchSelection?, Options) -> Unit,
|
onSave: (PatchSelection?, Options) -> Unit,
|
||||||
@@ -231,7 +235,8 @@ fun PatchesSelectorScreen(
|
|||||||
viewModel.selectionWarningEnabled -> showSelectionWarning = true
|
viewModel.selectionWarningEnabled -> showSelectionWarning = true
|
||||||
|
|
||||||
// Show universal warning if universal patch is selected and the toggle is off
|
// Show universal warning if universal patch is selected and the toggle is off
|
||||||
patch.compatiblePackages == null && viewModel.universalPatchWarningEnabled -> showUniversalWarning = true
|
patch.compatiblePackages == null && viewModel.universalPatchWarningEnabled -> showUniversalWarning =
|
||||||
|
true
|
||||||
|
|
||||||
// Toggle the patch otherwise
|
// Toggle the patch otherwise
|
||||||
else -> viewModel.togglePatch(uid, patch)
|
else -> viewModel.togglePatch(uid, patch)
|
||||||
@@ -360,6 +365,21 @@ fun PatchesSelectorScreen(
|
|||||||
) {
|
) {
|
||||||
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isScrollingUp =
|
||||||
|
patchLazyListStates.getOrNull(pagerState.currentPage)?.isScrollingUp()
|
||||||
|
val expanded by produceState(true, isScrollingUp) {
|
||||||
|
val state = isScrollingUp ?: return@produceState
|
||||||
|
value = state.value
|
||||||
|
|
||||||
|
// Use snapshotFlow and sample to prevent the value from changing too often.
|
||||||
|
snapshotFlow { state.value }
|
||||||
|
.sample(333L)
|
||||||
|
.collect {
|
||||||
|
value = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HapticExtendedFloatingActionButton(
|
HapticExtendedFloatingActionButton(
|
||||||
text = {
|
text = {
|
||||||
Text(
|
Text(
|
||||||
@@ -375,8 +395,7 @@ fun PatchesSelectorScreen(
|
|||||||
contentDescription = stringResource(R.string.save)
|
contentDescription = stringResource(R.string.save)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
expanded = patchLazyListStates.getOrNull(pagerState.currentPage)?.isScrollingUp
|
expanded = expanded,
|
||||||
?: true,
|
|
||||||
onClick = {
|
onClick = {
|
||||||
onSave(viewModel.getCustomSelection(), viewModel.getOptions())
|
onSave(viewModel.getCustomSelection(), viewModel.getOptions())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,10 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.ReadOnlyComposable
|
import androidx.compose.runtime.ReadOnlyComposable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@@ -50,6 +48,7 @@ import kotlinx.datetime.format.char
|
|||||||
import kotlinx.datetime.toInstant
|
import kotlinx.datetime.toInstant
|
||||||
import kotlinx.datetime.toLocalDateTime
|
import kotlinx.datetime.toLocalDateTime
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import kotlin.math.abs
|
||||||
import kotlin.properties.PropertyDelegateProvider
|
import kotlin.properties.PropertyDelegateProvider
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
@@ -196,7 +195,12 @@ val transparentListItemColors
|
|||||||
.also { transparentListItemColorsCached = it }
|
.also { transparentListItemColorsCached = it }
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun <T> EventEffect(flow: Flow<T>, vararg keys: Any?, state: Lifecycle.State = Lifecycle.State.STARTED, block: suspend (T) -> Unit) {
|
fun <T> EventEffect(
|
||||||
|
flow: Flow<T>,
|
||||||
|
vararg keys: Any?,
|
||||||
|
state: Lifecycle.State = Lifecycle.State.STARTED,
|
||||||
|
block: suspend (T) -> Unit
|
||||||
|
) {
|
||||||
val lifecycleOwner = LocalLifecycleOwner.current
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
val currentBlock by rememberUpdatedState(block)
|
val currentBlock by rememberUpdatedState(block)
|
||||||
|
|
||||||
@@ -212,40 +216,36 @@ fun <T> EventEffect(flow: Flow<T>, vararg keys: Any?, state: Lifecycle.State = L
|
|||||||
const val isScrollingUpSensitivity = 10
|
const val isScrollingUpSensitivity = 10
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LazyListState.isScrollingUp(): State<Boolean> {
|
fun LazyListState.isScrollingUp() = produceState(true, this) {
|
||||||
return remember(this) {
|
var previousIndex = firstVisibleItemIndex
|
||||||
var previousIndex by mutableIntStateOf(firstVisibleItemIndex)
|
var previousScrollOffset = firstVisibleItemScrollOffset
|
||||||
var previousScrollOffset by mutableIntStateOf(firstVisibleItemScrollOffset)
|
|
||||||
|
|
||||||
derivedStateOf {
|
snapshotFlow {
|
||||||
val indexChanged = previousIndex != firstVisibleItemIndex
|
firstVisibleItemIndex to firstVisibleItemScrollOffset
|
||||||
val offsetChanged =
|
}.collect { (index, scrollOffset) ->
|
||||||
kotlin.math.abs(previousScrollOffset - firstVisibleItemScrollOffset) > isScrollingUpSensitivity
|
val indexChanged = previousIndex != index
|
||||||
|
val offsetChanged = abs(previousScrollOffset - scrollOffset) > isScrollingUpSensitivity
|
||||||
|
|
||||||
if (indexChanged) {
|
value = when {
|
||||||
previousIndex > firstVisibleItemIndex
|
indexChanged -> previousIndex > index
|
||||||
} else if (offsetChanged) {
|
offsetChanged -> previousScrollOffset > scrollOffset
|
||||||
previousScrollOffset > firstVisibleItemScrollOffset
|
else -> value
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}.also {
|
|
||||||
previousIndex = firstVisibleItemIndex
|
|
||||||
previousScrollOffset = firstVisibleItemScrollOffset
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
previousIndex = index
|
||||||
|
previousScrollOffset = scrollOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: support sensitivity
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ScrollState.isScrollingUp(): State<Boolean> {
|
fun ScrollState.isScrollingUp() = produceState(true, this) {
|
||||||
return remember(this) {
|
var previousScrollOffset = this@isScrollingUp.value
|
||||||
var previousScrollOffset by mutableIntStateOf(value)
|
|
||||||
derivedStateOf {
|
snapshotFlow { this@isScrollingUp.value }.collect { scrollOffset ->
|
||||||
(previousScrollOffset >= value).also {
|
if (abs(previousScrollOffset - scrollOffset) > isScrollingUpSensitivity) {
|
||||||
previousScrollOffset = value
|
value = previousScrollOffset >= scrollOffset
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
previousScrollOffset = scrollOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user