[优化] 发现页可以在添加进书架后立即标记,与增加发现页内分组搜索
This commit is contained in:
@@ -93,7 +93,9 @@ import io.legado.app.ui.widget.components.AnimatedTextButton
|
||||
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 io.legado.app.ui.widget.components.SearchBarSection
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@SuppressLint("LocalContextConfigurationRead", "ConfigurationScreenWidthHeight")
|
||||
@@ -216,6 +218,7 @@ fun ExploreShowScreen(
|
||||
|
||||
if (showKindSheet) {
|
||||
val scrollState = rememberScrollState()
|
||||
var kindQuery by remember { mutableStateOf("") }
|
||||
val sheetState = rememberModalBottomSheetState(
|
||||
skipPartiallyExpanded = true,
|
||||
confirmValueChange = { newValue ->
|
||||
@@ -231,16 +234,30 @@ fun ExploreShowScreen(
|
||||
.fillMaxWidth()
|
||||
.heightIn(max = LocalConfiguration.current.screenHeightDp.dp * 0.8f)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(12.dp)
|
||||
) {
|
||||
Text(
|
||||
"选择分类",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
|
||||
var kindQuery by remember { mutableStateOf("") }
|
||||
|
||||
SearchBarSection(
|
||||
query = kindQuery,
|
||||
onQueryChange = { kindQuery = it },
|
||||
placeholder = "选择或搜索分类",
|
||||
backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh
|
||||
)
|
||||
|
||||
FlowRow(modifier = Modifier.fillMaxWidth()) {
|
||||
kinds.forEach { kind ->
|
||||
val filteredKinds = remember(kindQuery, kinds) {
|
||||
if (kindQuery.isBlank()) kinds
|
||||
else kinds.filter { kind ->
|
||||
kind.title.contains(kindQuery, ignoreCase = true) ||
|
||||
(kind.url?.contains(kindQuery, ignoreCase = true) == true)
|
||||
}
|
||||
}
|
||||
|
||||
FlowRow(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
filteredKinds.forEach { kind ->
|
||||
KindListItem(
|
||||
kind = kind,
|
||||
currentTitle = selectedTitle ?: title,
|
||||
@@ -295,10 +312,9 @@ fun ExploreShowScreen(
|
||||
items = books,
|
||||
key = { it.bookUrl }
|
||||
) { book ->
|
||||
val shelfState = viewModel.getCurrentBookShelfState(book)
|
||||
ExploreBookGridItem(
|
||||
book = book,
|
||||
shelfState = shelfState,
|
||||
shelfState = viewModel.getBookShelfStateFlow(book),
|
||||
onClick = { onBookClick(book) },
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
@@ -325,7 +341,7 @@ fun ExploreShowScreen(
|
||||
val shelfState = viewModel.getCurrentBookShelfState(book)
|
||||
ExploreBookItem(
|
||||
book = book,
|
||||
shelfState = shelfState,
|
||||
shelfState = viewModel.getBookShelfStateFlow(book),
|
||||
onClick = { onBookClick(book) },
|
||||
modifier = Modifier.animateItem()
|
||||
)
|
||||
@@ -372,7 +388,7 @@ fun KindListItem(
|
||||
modifier = Modifier
|
||||
.then(
|
||||
if (!isClickable) Modifier.fillMaxWidth()
|
||||
else Modifier.fillMaxWidth(1 / 3f)
|
||||
else Modifier.fillMaxWidth(1f / 3f)
|
||||
)
|
||||
.padding(horizontal = 4.dp)
|
||||
)
|
||||
@@ -472,10 +488,11 @@ fun ExploreTopBar(
|
||||
@Composable
|
||||
fun ExploreBookItem(
|
||||
book: SearchBook,
|
||||
shelfState: BookShelfState,
|
||||
shelfState: Flow<BookShelfState>,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val shelfState by shelfState.collectAsState(initial = BookShelfState.NOT_IN_SHELF)
|
||||
|
||||
val badge: (@Composable RowScope.() -> Unit)?
|
||||
= when (shelfState) {
|
||||
@@ -584,10 +601,12 @@ fun ExploreBookItem(
|
||||
fun ExploreBookGridItem(
|
||||
book: SearchBook,
|
||||
onClick: () -> Unit,
|
||||
shelfState: BookShelfState,
|
||||
shelfState: Flow<BookShelfState>,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
|
||||
val shelfState by shelfState.collectAsState(initial = BookShelfState.NOT_IN_SHELF)
|
||||
|
||||
val badgeText: String? = when (shelfState) {
|
||||
BookShelfState.IN_SHELF -> "已在书架"
|
||||
BookShelfState.SAME_NAME_AUTHOR -> "同名书籍"
|
||||
|
||||
@@ -11,11 +11,14 @@ import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.model.BookShelfState
|
||||
import io.legado.app.ui.book.search.BookKey
|
||||
import io.legado.app.utils.exploreLayoutGrid
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import splitties.init.appCtx
|
||||
@@ -198,6 +201,12 @@ class ExploreShowViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun getBookShelfStateFlow(item: SearchBook): Flow<BookShelfState> {
|
||||
return _bookshelf.map { shelf ->
|
||||
getBookShelfState(item, shelf)
|
||||
}.distinctUntilChanged()
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.material3.ContainedLoadingIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.LoadingIndicator
|
||||
import androidx.compose.material3.Text
|
||||
@@ -36,7 +37,7 @@ fun AnimatedTextButton(
|
||||
label = "ButtonLoading"
|
||||
) { loading ->
|
||||
if (loading) {
|
||||
LoadingIndicator()
|
||||
ContainedLoadingIndicator()
|
||||
} else {
|
||||
Text(text)
|
||||
}
|
||||
|
||||
@@ -24,14 +24,15 @@ import androidx.compose.ui.unit.dp
|
||||
fun SearchBarSection(
|
||||
query: String,
|
||||
onQueryChange: (String) -> Unit,
|
||||
placeholder: String = "搜索书名"
|
||||
placeholder: String = "搜索书名",
|
||||
backgroundColor: Color = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
shape = RoundedCornerShape(32.dp),
|
||||
color = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
color = backgroundColor
|
||||
) {
|
||||
|
||||
TextField(
|
||||
|
||||
Reference in New Issue
Block a user