fix(sources-search): search box visibility glitch when scrolling (#1278)
* fix(sources-screen): search box visibility glitch when scrolling * Refactor to a reusable function * Apply to MigrateSourceScreen * Fix warning * suggestions * Revert "Fix warning" This reverts commit b1c97bcf04b9e34b3eb314fd54c45be953d2f451. * Add comment --------- Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
This commit is contained in:
parent
798bfc19ff
commit
b24b14c73d
4 changed files with 153 additions and 103 deletions
|
|
@ -3,6 +3,7 @@ package eu.kanade.presentation.browse
|
|||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
|
@ -30,6 +31,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
||||
import eu.kanade.domain.source.model.installedExtension
|
||||
import eu.kanade.presentation.browse.components.BaseSourceItem
|
||||
|
|
@ -48,7 +50,6 @@ import tachiyomi.i18n.kmk.KMR
|
|||
import tachiyomi.presentation.core.components.Badge
|
||||
import tachiyomi.presentation.core.components.BadgeGroup
|
||||
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
||||
import tachiyomi.presentation.core.components.Scroller.STICKY_HEADER_KEY_PREFIX
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.icons.FlagEmoji
|
||||
|
|
@ -126,27 +127,9 @@ private fun MigrateSourceList(
|
|||
}
|
||||
|
||||
Column(
|
||||
// Wrap around so we can use stickyHeader
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
) {
|
||||
AnimatedFloatingSearchBox(
|
||||
listState = lazyListState,
|
||||
searchQuery = state.searchQuery,
|
||||
onChangeSearchQuery = onChangeSearchQuery,
|
||||
placeholderText = stringResource(KMR.strings.action_search_for_source),
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
horizontal = MaterialTheme.padding.medium,
|
||||
vertical = MaterialTheme.padding.small,
|
||||
),
|
||||
)
|
||||
|
||||
FastScrollLazyColumn(
|
||||
state = lazyListState,
|
||||
// contentPadding = contentPadding + topSmallPaddingValues,
|
||||
// KMK <--
|
||||
) {
|
||||
stickyHeader(key = STICKY_HEADER_KEY_PREFIX) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
|
|
@ -194,8 +177,14 @@ private fun MigrateSourceList(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
Box {
|
||||
FastScrollLazyColumn(
|
||||
state = lazyListState,
|
||||
contentPadding = PaddingValues(top = 65.dp),
|
||||
// KMK <--
|
||||
) {
|
||||
items(
|
||||
items = list
|
||||
// KMK -->
|
||||
|
|
@ -221,6 +210,23 @@ private fun MigrateSourceList(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
AnimatedFloatingSearchBox(
|
||||
listState = lazyListState,
|
||||
searchQuery = state.searchQuery,
|
||||
onChangeSearchQuery = onChangeSearchQuery,
|
||||
placeholderText = stringResource(KMR.strings.action_search_for_source),
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.padding(
|
||||
horizontal = MaterialTheme.padding.medium,
|
||||
vertical = MaterialTheme.padding.small,
|
||||
)
|
||||
.align(Alignment.TopCenter),
|
||||
)
|
||||
// KMK <--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package eu.kanade.presentation.browse
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
|
@ -23,6 +25,7 @@ import androidx.compose.material3.TextButton
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -82,24 +85,12 @@ fun SourcesScreen(
|
|||
modifier = Modifier.padding(contentPadding),
|
||||
)
|
||||
// KMK -->
|
||||
else -> Column(
|
||||
// Wrap around so we can use stickyHeader
|
||||
else -> Box(
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
) {
|
||||
AnimatedFloatingSearchBox(
|
||||
listState = lazyListState,
|
||||
searchQuery = state.searchQuery,
|
||||
onChangeSearchQuery = onChangeSearchQuery,
|
||||
placeholderText = stringResource(KMR.strings.action_search_for_source),
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
horizontal = MaterialTheme.padding.medium,
|
||||
vertical = MaterialTheme.padding.small,
|
||||
),
|
||||
)
|
||||
|
||||
FastScrollLazyColumn(
|
||||
state = lazyListState,
|
||||
contentPadding = PaddingValues(top = 65.dp),
|
||||
// KMK <--
|
||||
) {
|
||||
items(
|
||||
|
|
@ -141,6 +132,22 @@ fun SourcesScreen(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
AnimatedFloatingSearchBox(
|
||||
listState = lazyListState,
|
||||
searchQuery = state.searchQuery,
|
||||
onChangeSearchQuery = onChangeSearchQuery,
|
||||
placeholderText = stringResource(KMR.strings.action_search_for_source),
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.padding(
|
||||
horizontal = MaterialTheme.padding.medium,
|
||||
vertical = MaterialTheme.padding.small,
|
||||
)
|
||||
.align(Alignment.TopCenter),
|
||||
)
|
||||
// KMK <--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ import tachiyomi.i18n.MR
|
|||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.util.clearFocusOnSoftKeyboardHide
|
||||
import tachiyomi.presentation.core.util.isScrolledToStart
|
||||
import tachiyomi.presentation.core.util.isScrollingDown
|
||||
import tachiyomi.presentation.core.util.isItemScrollingUp
|
||||
import tachiyomi.presentation.core.util.runOnEnterKeyPressed
|
||||
import tachiyomi.presentation.core.util.secondaryItemAlpha
|
||||
|
||||
|
|
@ -61,7 +60,7 @@ fun AnimatedFloatingSearchBox(
|
|||
keyboardController: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = listState.isScrolledToStart() || !listState.isScrollingDown(),
|
||||
visible = listState.isItemScrollingUp(),
|
||||
enter = expandVertically(),
|
||||
exit = shrinkVertically(),
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@ package tachiyomi.presentation.core.util
|
|||
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
||||
@Composable
|
||||
fun LazyListState.shouldExpandFAB(): Boolean {
|
||||
|
|
@ -75,3 +79,37 @@ fun LazyListState.isScrollingDown(): Boolean {
|
|||
}
|
||||
}.value
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
@Composable
|
||||
private fun LazyListState.isItemScrolling(
|
||||
initialValue: Boolean,
|
||||
comparison: (Int, Int) -> Boolean,
|
||||
): Boolean {
|
||||
var isScrolling by remember { mutableStateOf(initialValue) }
|
||||
var previousIndex by remember { mutableIntStateOf(firstVisibleItemIndex) }
|
||||
|
||||
LaunchedEffect(this) {
|
||||
snapshotFlow { firstVisibleItemIndex }
|
||||
.distinctUntilChanged()
|
||||
.collect { currentIndex ->
|
||||
if (previousIndex != currentIndex) {
|
||||
isScrolling = comparison(previousIndex, currentIndex)
|
||||
previousIndex = currentIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isScrolling
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LazyListState.isItemScrollingUp(initiallyVisible: Boolean = true): Boolean {
|
||||
return isItemScrolling(initialValue = initiallyVisible) { previous, current -> previous > current }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LazyListState.isItemScrollingDown(initiallyVisible: Boolean = false): Boolean {
|
||||
return isItemScrolling(initialValue = initiallyVisible) { previous, current -> previous < current }
|
||||
}
|
||||
// KMK <--
|
||||
|
|
|
|||
Loading…
Reference in a new issue