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

This commit is contained in:
HapeLee committed 2025-11-30 15:43:07 +08:00
1 parent edfdfb341f
commit 429d41b168
2 files changed
+34 -29

No files matched your search

@@ -64,6 +64,7 @@ import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.model.BookShelfState import io.legado.app.model.BookShelfState
import io.legado.app.ui.widget.components.AnimatedTextLine import io.legado.app.ui.widget.components.AnimatedTextLine
import io.legado.app.ui.widget.components.Cover import io.legado.app.ui.widget.components.Cover
import io.legado.app.ui.widget.components.EmptyMessageView
import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@@ -145,6 +146,11 @@ fun ExploreShowScreen(
.fillMaxSize() .fillMaxSize()
.padding(paddingValues) .padding(paddingValues)
) { ) {
if (!isLoading && books.isEmpty() && errorMsg == null) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
EmptyMessageView(message = "暂无书籍")
}
} else {
LazyColumn( LazyColumn(
state = listState, state = listState,
contentPadding = PaddingValues(bottom = 16.dp) contentPadding = PaddingValues(bottom = 16.dp)
@@ -166,22 +172,17 @@ fun ExploreShowScreen(
LoadMoreFooter( LoadMoreFooter(
isLoading = isLoading, isLoading = isLoading,
errorMsg = errorMsg, errorMsg = errorMsg,
onRetry = { viewModel.loadMore() } onRetry = viewModel::loadMore
) )
} }
} }
if (!isLoading && books.isEmpty() && errorMsg == null) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Text("暂无书籍", color = Color.Gray)
}
} }
val shouldLoadMore = remember { val shouldLoadMore = remember {
derivedStateOf { derivedStateOf {
val totalItems = listState.layoutInfo.totalItemsCount val totalItems = listState.layoutInfo.totalItemsCount
val lastVisibleIndex = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 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, style = MaterialTheme.typography.bodySmall,
color = Color.Gray, color = Color.Gray,
maxLines = 2, maxLines = 2,
minLines = 2,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
} }
@@ -442,18 +444,23 @@ fun LoadMoreFooter(
.padding(32.dp), .padding(32.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
if (isLoading) { when {
LoadingIndicator() isLoading -> LoadingIndicator()
} else if (errorMsg != null) {
errorMsg != null -> {
Column(horizontalAlignment = Alignment.CenterHorizontally) { Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "加载失败: $errorMsg", color = Color.Red, style = MaterialTheme.typography.bodySmall) Text("加载失败: $errorMsg", color = Color.Red)
TextButton(onClick = onRetry) { TextButton(onClick = onRetry) { Text("重试") }
Text("重试")
} }
} }
} else {
// 没有在加载且没有错误,可能到底了,或者等待滑动触发 else -> {
Spacer(modifier = Modifier.height(1.dp)) Text(
text = "已经到底了~",
color = Color.Gray,
style = MaterialTheme.typography.bodySmall
)
}
} }
} }
} }
@@ -63,19 +63,7 @@ class ExploreShowViewModel(
_bookshelf _bookshelf
) { books, filter, bookshelf -> ) { books, filter, bookshelf ->
books.filter { item -> books.filter { item ->
val state = getBookShelfState(item, bookshelf) isBookValid(item, filter, 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
}
} }
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList()) }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
@@ -169,6 +157,16 @@ class ExploreShowViewModel(
return getBookShelfState(item, _bookshelf.value) 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 { 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 } val exactMatch = shelf.any { it.name == item.name && it.author == item.author && it.url == item.bookUrl }
if (exactMatch) return BookShelfState.IN_SHELF if (exactMatch) return BookShelfState.IN_SHELF