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:
parent
365cd0b14d
commit
3408ef635d
@ -48,6 +48,7 @@ import eu.kanade.presentation.browse.components.ExtensionIcon
|
|||||||
import eu.kanade.presentation.components.WarningBanner
|
import eu.kanade.presentation.components.WarningBanner
|
||||||
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
|
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
|
||||||
import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen
|
import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen
|
||||||
|
import eu.kanade.presentation.util.animateItemFastScroll
|
||||||
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
|
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.model.InstallStep
|
import eu.kanade.tachiyomi.extension.model.InstallStep
|
||||||
@ -188,14 +189,14 @@ private fun ExtensionContent(
|
|||||||
}
|
}
|
||||||
ExtensionHeader(
|
ExtensionHeader(
|
||||||
textRes = header.textRes,
|
textRes = header.textRes,
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
action = action,
|
action = action,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ExtensionUiModel.Header.Text -> {
|
is ExtensionUiModel.Header.Text -> {
|
||||||
ExtensionHeader(
|
ExtensionHeader(
|
||||||
text = header.text,
|
text = header.text,
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,7 +214,7 @@ private fun ExtensionContent(
|
|||||||
},
|
},
|
||||||
) { item ->
|
) { item ->
|
||||||
ExtensionItem(
|
ExtensionItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
item = item,
|
item = item,
|
||||||
onClickItem = {
|
onClickItem = {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
@ -92,7 +92,7 @@ fun FeedScreen(
|
|||||||
refreshing = true
|
refreshing = true
|
||||||
onRefresh()
|
onRefresh()
|
||||||
},
|
},
|
||||||
enabled = { !state.isLoadingItems },
|
enabled = !state.isLoadingItems,
|
||||||
) {
|
) {
|
||||||
ScrollbarLazyColumn(
|
ScrollbarLazyColumn(
|
||||||
contentPadding = contentPadding + topSmallPaddingValues,
|
contentPadding = contentPadding + topSmallPaddingValues,
|
||||||
@ -103,7 +103,6 @@ fun FeedScreen(
|
|||||||
key = { it.feed.id },
|
key = { it.feed.id },
|
||||||
) { item ->
|
) { item ->
|
||||||
GlobalSearchResultItem(
|
GlobalSearchResultItem(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
|
||||||
title = item.title,
|
title = item.title,
|
||||||
subtitle = item.subtitle,
|
subtitle = item.subtitle,
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
@ -116,6 +115,7 @@ fun FeedScreen(
|
|||||||
onClickSource(item.source)
|
onClickSource(item.source)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
modifier = Modifier.animateItem(),
|
||||||
) {
|
) {
|
||||||
FeedItem(
|
FeedItem(
|
||||||
item = item,
|
item = item,
|
||||||
|
@ -28,6 +28,7 @@ import eu.kanade.presentation.browse.components.MigrationItem
|
|||||||
import eu.kanade.presentation.browse.components.MigrationItemResult
|
import eu.kanade.presentation.browse.components.MigrationItemResult
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.AppBarActions
|
import eu.kanade.presentation.components.AppBarActions
|
||||||
|
import eu.kanade.presentation.util.animateItemFastScroll
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigratingManga
|
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigratingManga
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
@ -95,7 +96,7 @@ fun MigrationListScreen(
|
|||||||
Row(
|
Row(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.animateItemPlacement()
|
.animateItemFastScroll()
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
.height(IntrinsicSize.Min),
|
.height(IntrinsicSize.Min),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
@ -15,6 +15,7 @@ import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
|
|||||||
import eu.kanade.presentation.browse.components.GlobalSearchResultItem
|
import eu.kanade.presentation.browse.components.GlobalSearchResultItem
|
||||||
import eu.kanade.presentation.components.AppBarTitle
|
import eu.kanade.presentation.components.AppBarTitle
|
||||||
import eu.kanade.presentation.components.SearchToolbar
|
import eu.kanade.presentation.components.SearchToolbar
|
||||||
|
import eu.kanade.presentation.util.animateItemFastScroll
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.source.model.FeedSavedSearch
|
import tachiyomi.domain.source.model.FeedSavedSearch
|
||||||
@ -153,7 +154,7 @@ fun SourceFeedList(
|
|||||||
key = { it.id },
|
key = { it.id },
|
||||||
) { item ->
|
) { item ->
|
||||||
GlobalSearchResultItem(
|
GlobalSearchResultItem(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
title = item.title,
|
title = item.title,
|
||||||
subtitle = null,
|
subtitle = null,
|
||||||
onLongClick = if (item is SourceFeedUI.SourceSavedSearch) {
|
onLongClick = if (item is SourceFeedUI.SourceSavedSearch) {
|
||||||
|
@ -11,6 +11,7 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import eu.kanade.presentation.browse.components.BaseSourceItem
|
import eu.kanade.presentation.browse.components.BaseSourceItem
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
|
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.ui.browse.source.SourcesFilterScreenModel
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import tachiyomi.domain.source.model.Source
|
import tachiyomi.domain.source.model.Source
|
||||||
@ -79,7 +80,7 @@ private fun SourcesFilterContent(
|
|||||||
contentType = "source-filter-header",
|
contentType = "source-filter-header",
|
||||||
) {
|
) {
|
||||||
SourcesFilterHeader(
|
SourcesFilterHeader(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
language = language,
|
language = language,
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
onClickItem = onClickLanguage,
|
onClickItem = onClickLanguage,
|
||||||
@ -95,7 +96,7 @@ private fun SourcesFilterContent(
|
|||||||
sources.none { it.id.toString() in state.disabledSources }
|
sources.none { it.id.toString() in state.disabledSources }
|
||||||
}
|
}
|
||||||
SourcesFilterToggle(
|
SourcesFilterToggle(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItem(),
|
||||||
isEnabled = toggleEnabled,
|
isEnabled = toggleEnabled,
|
||||||
onClickItem = {
|
onClickItem = {
|
||||||
onClickSources(!toggleEnabled, sources)
|
onClickSources(!toggleEnabled, sources)
|
||||||
@ -109,7 +110,7 @@ private fun SourcesFilterContent(
|
|||||||
contentType = { "source-filter-item" },
|
contentType = { "source-filter-item" },
|
||||||
) { source ->
|
) { source ->
|
||||||
SourcesFilterItem(
|
SourcesFilterItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
source = source,
|
source = source,
|
||||||
enabled = "${source.id}" !in state.disabledSources,
|
enabled = "${source.id}" !in state.disabledSources,
|
||||||
onClickItem = onClickSource,
|
onClickItem = onClickSource,
|
||||||
|
@ -26,7 +26,7 @@ fun BiometricTimesContent(
|
|||||||
) {
|
) {
|
||||||
items(timeRanges, key = { it.formattedString }) { timeRange ->
|
items(timeRanges, key = { it.formattedString }) { timeRange ->
|
||||||
BiometricTimesListItem(
|
BiometricTimesListItem(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItem(),
|
||||||
timeRange = timeRange,
|
timeRange = timeRange,
|
||||||
onDelete = { onClickDelete(timeRange) },
|
onDelete = { onClickDelete(timeRange) },
|
||||||
)
|
)
|
||||||
|
@ -27,7 +27,7 @@ fun SortTagContent(
|
|||||||
) {
|
) {
|
||||||
itemsIndexed(tags, key = { _, tag -> tag }) { index, tag ->
|
itemsIndexed(tags, key = { _, tag -> tag }) { index, tag ->
|
||||||
SortTagListItem(
|
SortTagListItem(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItem(),
|
||||||
tag = tag,
|
tag = tag,
|
||||||
canMoveUp = index != 0,
|
canMoveUp = index != 0,
|
||||||
canMoveDown = index != tags.lastIndex,
|
canMoveDown = index != tags.lastIndex,
|
||||||
|
@ -26,7 +26,7 @@ fun SourceCategoryContent(
|
|||||||
) {
|
) {
|
||||||
items(categories, key = { it }) { category ->
|
items(categories, key = { it }) { category ->
|
||||||
SourceCategoryListItem(
|
SourceCategoryListItem(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItem(),
|
||||||
category = category,
|
category = category,
|
||||||
onRename = { onClickRename(category) },
|
onRename = { onClickRename(category) },
|
||||||
onDelete = { onClickDelete(category) },
|
onDelete = { onClickDelete(category) },
|
||||||
|
@ -18,6 +18,7 @@ import eu.kanade.presentation.components.SearchToolbar
|
|||||||
import eu.kanade.presentation.components.relativeDateText
|
import eu.kanade.presentation.components.relativeDateText
|
||||||
import eu.kanade.presentation.history.components.HistoryItem
|
import eu.kanade.presentation.history.components.HistoryItem
|
||||||
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
|
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
|
||||||
|
import eu.kanade.presentation.util.animateItemFastScroll
|
||||||
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
|
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
@ -114,14 +115,14 @@ private fun HistoryScreenContent(
|
|||||||
when (item) {
|
when (item) {
|
||||||
is HistoryUiModel.Header -> {
|
is HistoryUiModel.Header -> {
|
||||||
ListGroupHeader(
|
ListGroupHeader(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
text = relativeDateText(item.date),
|
text = relativeDateText(item.date),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is HistoryUiModel.Item -> {
|
is HistoryUiModel.Item -> {
|
||||||
val value = item.item
|
val value = item.item
|
||||||
HistoryItem(
|
HistoryItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
history = value,
|
history = value,
|
||||||
onClickCover = { onClickCover(value) },
|
onClickCover = { onClickCover(value) },
|
||||||
onClickResume = { onClickResume(value) },
|
onClickResume = { onClickResume(value) },
|
||||||
|
@ -7,7 +7,7 @@ import androidx.compose.foundation.layout.FlowRow
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
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.MaterialTheme
|
||||||
import androidx.compose.material3.SuggestionChip
|
import androidx.compose.material3.SuggestionChip
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
@ -141,7 +141,7 @@ fun TagsChip(
|
|||||||
border: ChipBorder? = SuggestionChipDefaults.suggestionChipBorder(),
|
border: ChipBorder? = SuggestionChipDefaults.suggestionChipBorder(),
|
||||||
borderM3: BorderStroke? = SuggestionChipDefaultsM3.suggestionChipBorder(enabled = true),
|
borderM3: BorderStroke? = SuggestionChipDefaultsM3.suggestionChipBorder(enabled = true),
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
|
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
|
||||||
if (onClick != null) {
|
if (onClick != null) {
|
||||||
SuggestionChip(
|
SuggestionChip(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
@ -37,6 +37,7 @@ import eu.kanade.presentation.manga.components.ChapterDownloadAction
|
|||||||
import eu.kanade.presentation.manga.components.ChapterDownloadIndicator
|
import eu.kanade.presentation.manga.components.ChapterDownloadIndicator
|
||||||
import eu.kanade.presentation.manga.components.DotSeparatorText
|
import eu.kanade.presentation.manga.components.DotSeparatorText
|
||||||
import eu.kanade.presentation.manga.components.MangaCover
|
import eu.kanade.presentation.manga.components.MangaCover
|
||||||
|
import eu.kanade.presentation.util.animateItemFastScroll
|
||||||
import eu.kanade.presentation.util.relativeTimeSpanString
|
import eu.kanade.presentation.util.relativeTimeSpanString
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
||||||
@ -54,7 +55,7 @@ internal fun LazyListScope.updatesLastUpdatedItem(
|
|||||||
item(key = "updates-lastUpdated") {
|
item(key = "updates-lastUpdated") {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.animateItem()
|
.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||||
.padding(horizontal = MaterialTheme.padding.medium, vertical = MaterialTheme.padding.small),
|
.padding(horizontal = MaterialTheme.padding.medium, vertical = MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
@ -94,14 +95,14 @@ internal fun LazyListScope.updatesUiItems(
|
|||||||
when (item) {
|
when (item) {
|
||||||
is UpdatesUiModel.Header -> {
|
is UpdatesUiModel.Header -> {
|
||||||
ListGroupHeader(
|
ListGroupHeader(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
text = relativeDateText(item.date),
|
text = relativeDateText(item.date),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is UpdatesUiModel.Item -> {
|
is UpdatesUiModel.Item -> {
|
||||||
val updatesItem = item.item
|
val updatesItem = item.item
|
||||||
UpdatesUiItem(
|
UpdatesUiItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItemFastScroll(),
|
||||||
update = updatesItem.update,
|
update = updatesItem.update,
|
||||||
selected = updatesItem.selected,
|
selected = updatesItem.selected,
|
||||||
readProgress = updatesItem.update.lastPageRead
|
readProgress = updatesItem.update.lastPageRead
|
||||||
|
@ -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)
|
Loading…
x
Reference in New Issue
Block a user