Fix disappearance items when fast scrolling (#1035)

* Don't use animateItem's fade-in/fade-out in FastScrollLazyColumn

* Move to extension function

Avoid using animateItemPlacement name since it's shadowed by compose-bom's deprecated one

(cherry picked from commit 913ff22132390a59a13c463645ce954c7cbc5c6b)
This commit is contained in:
Tran M. Cuong 2024-07-27 02:01:32 +07:00 committed by Jobobby04
parent 365cd0b14d
commit 3408ef635d
12 changed files with 34 additions and 20 deletions

View File

@ -48,6 +48,7 @@ import eu.kanade.presentation.browse.components.ExtensionIcon
import eu.kanade.presentation.components.WarningBanner
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep
@ -188,14 +189,14 @@ private fun ExtensionContent(
}
ExtensionHeader(
textRes = header.textRes,
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
action = action,
)
}
is ExtensionUiModel.Header.Text -> {
ExtensionHeader(
text = header.text,
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
)
}
}
@ -213,7 +214,7 @@ private fun ExtensionContent(
},
) { item ->
ExtensionItem(
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
item = item,
onClickItem = {
when (it) {

View File

@ -92,7 +92,7 @@ fun FeedScreen(
refreshing = true
onRefresh()
},
enabled = { !state.isLoadingItems },
enabled = !state.isLoadingItems,
) {
ScrollbarLazyColumn(
contentPadding = contentPadding + topSmallPaddingValues,
@ -103,7 +103,6 @@ fun FeedScreen(
key = { it.feed.id },
) { item ->
GlobalSearchResultItem(
modifier = Modifier.animateItemPlacement(),
title = item.title,
subtitle = item.subtitle,
onLongClick = {
@ -116,6 +115,7 @@ fun FeedScreen(
onClickSource(item.source)
}
},
modifier = Modifier.animateItem(),
) {
FeedItem(
item = item,

View File

@ -28,6 +28,7 @@ import eu.kanade.presentation.browse.components.MigrationItem
import eu.kanade.presentation.browse.components.MigrationItemResult
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigratingManga
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -95,7 +96,7 @@ fun MigrationListScreen(
Row(
Modifier
.fillMaxWidth()
.animateItemPlacement()
.animateItemFastScroll()
.padding(horizontal = 16.dp)
.height(IntrinsicSize.Min),
horizontalArrangement = Arrangement.SpaceBetween,

View File

@ -15,6 +15,7 @@ import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
import eu.kanade.presentation.browse.components.GlobalSearchResultItem
import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.util.animateItemFastScroll
import kotlinx.collections.immutable.ImmutableList
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.FeedSavedSearch
@ -153,7 +154,7 @@ fun SourceFeedList(
key = { it.id },
) { item ->
GlobalSearchResultItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
title = item.title,
subtitle = null,
onLongClick = if (item is SourceFeedUI.SourceSavedSearch) {

View File

@ -11,6 +11,7 @@ import androidx.compose.ui.platform.LocalContext
import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.domain.source.model.Source
@ -79,7 +80,7 @@ private fun SourcesFilterContent(
contentType = "source-filter-header",
) {
SourcesFilterHeader(
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
language = language,
enabled = enabled,
onClickItem = onClickLanguage,
@ -95,7 +96,7 @@ private fun SourcesFilterContent(
sources.none { it.id.toString() in state.disabledSources }
}
SourcesFilterToggle(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
isEnabled = toggleEnabled,
onClickItem = {
onClickSources(!toggleEnabled, sources)
@ -109,7 +110,7 @@ private fun SourcesFilterContent(
contentType = { "source-filter-item" },
) { source ->
SourcesFilterItem(
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
source = source,
enabled = "${source.id}" !in state.disabledSources,
onClickItem = onClickSource,

View File

@ -26,7 +26,7 @@ fun BiometricTimesContent(
) {
items(timeRanges, key = { it.formattedString }) { timeRange ->
BiometricTimesListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
timeRange = timeRange,
onDelete = { onClickDelete(timeRange) },
)

View File

@ -27,7 +27,7 @@ fun SortTagContent(
) {
itemsIndexed(tags, key = { _, tag -> tag }) { index, tag ->
SortTagListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
tag = tag,
canMoveUp = index != 0,
canMoveDown = index != tags.lastIndex,

View File

@ -26,7 +26,7 @@ fun SourceCategoryContent(
) {
items(categories, key = { it }) { category ->
SourceCategoryListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
category = category,
onRename = { onClickRename(category) },
onDelete = { onClickDelete(category) },

View File

@ -18,6 +18,7 @@ import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.components.relativeDateText
import eu.kanade.presentation.history.components.HistoryItem
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -114,14 +115,14 @@ private fun HistoryScreenContent(
when (item) {
is HistoryUiModel.Header -> {
ListGroupHeader(
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
text = relativeDateText(item.date),
)
}
is HistoryUiModel.Item -> {
val value = item.item
HistoryItem(
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
history = value,
onClickCover = { onClickCover(value) },
onClickResume = { onClickResume(value) },

View File

@ -7,7 +7,7 @@ import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SuggestionChip
import androidx.compose.material3.Surface
@ -141,7 +141,7 @@ fun TagsChip(
border: ChipBorder? = SuggestionChipDefaults.suggestionChipBorder(),
borderM3: BorderStroke? = SuggestionChipDefaultsM3.suggestionChipBorder(enabled = true),
) {
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
if (onClick != null) {
SuggestionChip(
modifier = modifier,

View File

@ -37,6 +37,7 @@ import eu.kanade.presentation.manga.components.ChapterDownloadAction
import eu.kanade.presentation.manga.components.ChapterDownloadIndicator
import eu.kanade.presentation.manga.components.DotSeparatorText
import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.presentation.util.relativeTimeSpanString
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
@ -54,7 +55,7 @@ internal fun LazyListScope.updatesLastUpdatedItem(
item(key = "updates-lastUpdated") {
Box(
modifier = Modifier
.animateItem()
.animateItem(fadeInSpec = null, fadeOutSpec = null)
.padding(horizontal = MaterialTheme.padding.medium, vertical = MaterialTheme.padding.small),
) {
Text(
@ -94,14 +95,14 @@ internal fun LazyListScope.updatesUiItems(
when (item) {
is UpdatesUiModel.Header -> {
ListGroupHeader(
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
text = relativeDateText(item.date),
)
}
is UpdatesUiModel.Item -> {
val updatesItem = item.item
UpdatesUiItem(
modifier = Modifier.animateItem(),
modifier = Modifier.animateItemFastScroll(),
update = updatesItem.update,
selected = updatesItem.selected,
readProgress = updatesItem.update.lastPageRead

View File

@ -0,0 +1,8 @@
package eu.kanade.presentation.util
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.ui.Modifier
// https://issuetracker.google.com/352584409
context(LazyItemScope)
fun Modifier.animateItemFastScroll() = this.animateItem(fadeInSpec = null, fadeOutSpec = null)