Просмотр исходного кода

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

HapeLee 11 месяцев назад
Родитель
Сommit
429d41b168

+ 46 - 39
app/src/main/java/io/legado/app/ui/book/explore/ExploreShowScreen.kt

@@ -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
+                )
+            }
         }
     }
-}
+}

+ 11 - 13
app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt

@@ -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