修复搜素不到除小说之外的书籍的问题
新增自由筛选搜素书籍类型
This commit is contained in:
@@ -32,6 +32,7 @@ data class BookSearchRequest(
|
|||||||
val scope: BookSearchScope,
|
val scope: BookSearchScope,
|
||||||
val precision: Boolean,
|
val precision: Boolean,
|
||||||
val concurrency: Int,
|
val concurrency: Int,
|
||||||
|
val types: Set<Int>? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed interface SearchRunEvent {
|
sealed interface SearchRunEvent {
|
||||||
@@ -88,7 +89,10 @@ class SearchBooksUseCase(
|
|||||||
sourceParts.map { part ->
|
sourceParts.map { part ->
|
||||||
async(Dispatchers.IO) {
|
async(Dispatchers.IO) {
|
||||||
val source = gateway.getBookSource(part.bookSourceUrl) ?: return@async null
|
val source = gateway.getBookSource(part.bookSourceUrl) ?: return@async null
|
||||||
if (source.bookSourceType != 0 || source.searchUrl.isNullOrBlank()) {
|
if (source.searchUrl.isNullOrBlank()) {
|
||||||
|
return@async null
|
||||||
|
}
|
||||||
|
if (request.types != null && !request.types.contains(source.bookSourceType)) {
|
||||||
return@async null
|
return@async null
|
||||||
}
|
}
|
||||||
SearchableSource(part, source)
|
SearchableSource(part, source)
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ data class SearchUiState(
|
|||||||
val hasMore: Boolean = true,
|
val hasMore: Boolean = true,
|
||||||
val processedSources: Int = 0,
|
val processedSources: Int = 0,
|
||||||
val totalSources: Int = 0,
|
val totalSources: Int = 0,
|
||||||
|
val selectedSourceTypes: Set<Int> = emptySet(),
|
||||||
val showScopeSheet: Boolean = false,
|
val showScopeSheet: Boolean = false,
|
||||||
|
val showTypeSheet: Boolean = false,
|
||||||
val showClearHistoryDialog: Boolean = false,
|
val showClearHistoryDialog: Boolean = false,
|
||||||
val showSuggestions: Boolean = true,
|
val showSuggestions: Boolean = true,
|
||||||
val emptyScopeAction: SearchEmptyScopeAction? = null,
|
val emptyScopeAction: SearchEmptyScopeAction? = null,
|
||||||
@@ -62,6 +64,8 @@ sealed interface SearchIntent {
|
|||||||
data class SetClearHistoryDialogVisible(val visible: Boolean) : SearchIntent
|
data class SetClearHistoryDialogVisible(val visible: Boolean) : SearchIntent
|
||||||
data object ConfirmClearHistory : SearchIntent
|
data object ConfirmClearHistory : SearchIntent
|
||||||
data class SetScopeSheetVisible(val visible: Boolean) : SearchIntent
|
data class SetScopeSheetVisible(val visible: Boolean) : SearchIntent
|
||||||
|
data class SetTypeSheetVisible(val visible: Boolean) : SearchIntent
|
||||||
|
data class ToggleSourceType(val type: Int) : SearchIntent
|
||||||
data object SelectAllScope : SearchIntent
|
data object SelectAllScope : SearchIntent
|
||||||
data class ToggleScopeGroup(val groupName: String) : SearchIntent
|
data class ToggleScopeGroup(val groupName: String) : SearchIntent
|
||||||
data class ToggleScopeSource(val source: BookSourcePart) : SearchIntent
|
data class ToggleScopeSource(val source: BookSourcePart) : SearchIntent
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.filled.Book
|
import androidx.compose.material.icons.filled.Book
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.History
|
import androidx.compose.material.icons.filled.History
|
||||||
|
import androidx.compose.material.icons.filled.Layers
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
import androidx.compose.material.icons.filled.Stop
|
import androidx.compose.material.icons.filled.Stop
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
@@ -268,6 +269,16 @@ fun SearchScreen(
|
|||||||
activeText = stringResource(R.string.precision_search),
|
activeText = stringResource(R.string.precision_search),
|
||||||
inactiveText = stringResource(R.string.search),
|
inactiveText = stringResource(R.string.search),
|
||||||
)
|
)
|
||||||
|
TopBarAnimatedActionButton(
|
||||||
|
checked = state.selectedSourceTypes.isNotEmpty(),
|
||||||
|
onCheckedChange = {
|
||||||
|
viewModel.onIntent(SearchIntent.SetTypeSheetVisible(true))
|
||||||
|
},
|
||||||
|
iconChecked = Icons.Default.Layers,
|
||||||
|
iconUnchecked = Icons.Default.Layers,
|
||||||
|
activeText = "搜素类型",
|
||||||
|
inactiveText = "搜素类型",
|
||||||
|
)
|
||||||
TopBarAnimatedActionButton(
|
TopBarAnimatedActionButton(
|
||||||
checked = !state.isAllScope,
|
checked = !state.isAllScope,
|
||||||
onCheckedChange = {
|
onCheckedChange = {
|
||||||
@@ -572,6 +583,49 @@ fun SearchScreen(
|
|||||||
Spacer(modifier = Modifier.height(20.dp))
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppModalBottomSheet(
|
||||||
|
show = state.showTypeSheet,
|
||||||
|
onDismissRequest = { viewModel.onIntent(SearchIntent.SetTypeSheetVisible(false)) },
|
||||||
|
title = "搜素类型",
|
||||||
|
) {
|
||||||
|
Column {
|
||||||
|
SelectionItemCard(
|
||||||
|
title = stringResource(R.string.all),
|
||||||
|
isSelected = state.selectedSourceTypes.isEmpty(),
|
||||||
|
containerColor = LegadoTheme.colorScheme.onSheetContent,
|
||||||
|
inSelectionMode = true,
|
||||||
|
onToggleSelection = {
|
||||||
|
if (state.selectedSourceTypes.isNotEmpty()) {
|
||||||
|
state.selectedSourceTypes.forEach {
|
||||||
|
viewModel.onIntent(SearchIntent.ToggleSourceType(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
0 to stringResource(R.string.noval),
|
||||||
|
2 to stringResource(R.string.manga),
|
||||||
|
1 to stringResource(R.string.audio),
|
||||||
|
).forEach { (type, label) ->
|
||||||
|
SelectionItemCard(
|
||||||
|
title = label,
|
||||||
|
isSelected = state.selectedSourceTypes.contains(type),
|
||||||
|
containerColor = LegadoTheme.colorScheme.onSheetContent,
|
||||||
|
inSelectionMode = true,
|
||||||
|
onToggleSelection = {
|
||||||
|
viewModel.onIntent(SearchIntent.ToggleSourceType(type))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class SearchFloatingSummary(
|
private data class SearchFloatingSummary(
|
||||||
|
|||||||
@@ -140,6 +140,23 @@ class SearchViewModel(
|
|||||||
_uiState.update { it.copy(showScopeSheet = intent.visible) }
|
_uiState.update { it.copy(showScopeSheet = intent.visible) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is SearchIntent.SetTypeSheetVisible -> {
|
||||||
|
_uiState.update { it.copy(showTypeSheet = intent.visible) }
|
||||||
|
}
|
||||||
|
|
||||||
|
is SearchIntent.ToggleSourceType -> {
|
||||||
|
_uiState.update { state ->
|
||||||
|
val current = state.selectedSourceTypes
|
||||||
|
val next = if (current.contains(intent.type)) {
|
||||||
|
current - intent.type
|
||||||
|
} else {
|
||||||
|
current + intent.type
|
||||||
|
}
|
||||||
|
state.copy(selectedSourceTypes = next)
|
||||||
|
}
|
||||||
|
restartCommittedSearchIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
SearchIntent.SelectAllScope -> {
|
SearchIntent.SelectAllScope -> {
|
||||||
val oldScope = searchScope.toString()
|
val oldScope = searchScope.toString()
|
||||||
searchScope.update("")
|
searchScope.update("")
|
||||||
@@ -334,6 +351,7 @@ class SearchViewModel(
|
|||||||
scope = BookSearchScope(searchScope.toString()),
|
scope = BookSearchScope(searchScope.toString()),
|
||||||
precision = _uiState.value.isPrecisionSearch,
|
precision = _uiState.value.isPrecisionSearch,
|
||||||
concurrency = OtherConfig.threadCount,
|
concurrency = OtherConfig.threadCount,
|
||||||
|
types = _uiState.value.selectedSourceTypes.takeIf { it.isNotEmpty() },
|
||||||
),
|
),
|
||||||
searchControl
|
searchControl
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user