[修复] 当当前发现页有书籍但全都被过滤时,自动加载下一页 #399

This commit is contained in:
HapeLee
2025-11-30 15:43:07 +08:00
parent edfdfb341f
commit 429d41b168
2 changed files with 57 additions and 52 deletions
@@ -64,6 +64,7 @@ import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.model.BookShelfState
import io.legado.app.ui.widget.components.AnimatedTextLine
import io.legado.app.ui.widget.components.Cover
import io.legado.app.ui.widget.components.EmptyMessageView
import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalMaterial3Api::class)
@@ -145,35 +146,35 @@ fun ExploreShowScreen(
.fillMaxSize()
.padding(paddingValues)
) {
LazyColumn(
state = listState,
contentPadding = PaddingValues(bottom = 16.dp)
) {
items(
items = books,
key = { it.bookUrl }
) { book ->
val shelfState = viewModel.getCurrentBookShelfState(book)
ExploreBookItem(
book = book,
shelfState = shelfState,
onClick = { onBookClick(book) },
modifier = Modifier.animateItem()
)
}
item {
LoadMoreFooter(
isLoading = isLoading,
errorMsg = errorMsg,
onRetry = { viewModel.loadMore() }
)
}
}
if (!isLoading && books.isEmpty() && errorMsg == null) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text("暂无书籍", color = Color.Gray)
EmptyMessageView(message = "暂无书籍")
}
} else {
LazyColumn(
state = listState,
contentPadding = PaddingValues(bottom = 16.dp)
) {
items(
items = books,
key = { it.bookUrl }
) { book ->
val shelfState = viewModel.getCurrentBookShelfState(book)
ExploreBookItem(
book = book,
shelfState = shelfState,
onClick = { onBookClick(book) },
modifier = Modifier.animateItem()
)
}
item {
LoadMoreFooter(
isLoading = isLoading,
errorMsg = errorMsg,
onRetry = viewModel::loadMore
)
}
}
}
@@ -181,7 +182,7 @@ fun ExploreShowScreen(
derivedStateOf {
val totalItems = listState.layoutInfo.totalItemsCount
val lastVisibleIndex = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0
totalItems > 0 && lastVisibleIndex >= totalItems - 2
totalItems > 0 && lastVisibleIndex >= totalItems - 9
}
}
@@ -366,6 +367,7 @@ fun ExploreBookItem(
style = MaterialTheme.typography.bodySmall,
color = Color.Gray,
maxLines = 2,
minLines = 2,
overflow = TextOverflow.Ellipsis
)
}
@@ -442,18 +444,23 @@ fun LoadMoreFooter(
.padding(32.dp),
contentAlignment = Alignment.Center
) {
if (isLoading) {
LoadingIndicator()
} else if (errorMsg != null) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "加载失败: $errorMsg", color = Color.Red, style = MaterialTheme.typography.bodySmall)
TextButton(onClick = onRetry) {
Text("重试")
when {
isLoading -> LoadingIndicator()
errorMsg != null -> {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("加载失败: $errorMsg", color = Color.Red)
TextButton(onClick = onRetry) { Text("重试") }
}
}
} else {
// 没有在加载且没有错误,可能到底了,或者等待滑动触发
Spacer(modifier = Modifier.height(1.dp))
else -> {
Text(
text = "已经到底了~",
color = Color.Gray,
style = MaterialTheme.typography.bodySmall
)
}
}
}
}
}
@@ -63,19 +63,7 @@ class ExploreShowViewModel(
_bookshelf
) { books, filter, bookshelf ->
books.filter { item ->
val state = getBookShelfState(item, bookshelf)
when (filter) {
BookFilterState.SHOW_ALL -> true
BookFilterState.HIDE_IN_SHELF ->
state != BookShelfState.IN_SHELF
BookFilterState.HIDE_SAME_NAME_AUTHOR ->
state != BookShelfState.SAME_NAME_AUTHOR
BookFilterState.SHOW_NOT_IN_SHELF_ONLY ->
state == BookShelfState.NOT_IN_SHELF
}
isBookValid(item, filter, bookshelf)
}
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
@@ -169,6 +157,16 @@ class ExploreShowViewModel(
return getBookShelfState(item, _bookshelf.value)
}
private fun isBookValid(book: SearchBook, filter: BookFilterState, shelf: Set<BookKey>): Boolean {
val state = getBookShelfState(book, shelf)
return when (filter) {
BookFilterState.SHOW_ALL -> true
BookFilterState.HIDE_IN_SHELF -> state != BookShelfState.IN_SHELF
BookFilterState.HIDE_SAME_NAME_AUTHOR -> state != BookShelfState.SAME_NAME_AUTHOR
BookFilterState.SHOW_NOT_IN_SHELF_ONLY -> state == BookShelfState.NOT_IN_SHELF
}
}
private fun getBookShelfState(item: SearchBook, shelf: Set<BookKey>): BookShelfState {
val exactMatch = shelf.any { it.name == item.name && it.author == item.author && it.url == item.bookUrl }
if (exactMatch) return BookShelfState.IN_SHELF