Add language filter for search (#428)
* Add language filter for search * Refine * Refine
This commit is contained in:
1 parent
ba943a31d4
commit
fc3b9d73ec
12 files changed
+69
-28
No files matched your search
@@ -105,6 +105,7 @@ object Settings : DataStorePreferences(null) {
|
||||
val detailSize = intPref("detail_size_2", 0)
|
||||
val thumbColumns = intPref("thumb_columns", 3)
|
||||
val listThumbSize = intPref("list_tile_size", 40)
|
||||
val languageFilter = intPref("language_filter", -1)
|
||||
val meteredNetworkWarning = boolPref("cellular_network_warning", false)
|
||||
val predictiveNavAnim = boolPref("predictive_nav_anim", true)
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ interface GalleryInfo {
|
||||
Pattern.compile("[(\\[]hun(?:garian)?[)\\]]|ハンガリー翻訳", Pattern.CASE_INSENSITIVE),
|
||||
Pattern.compile("[(\\[]dutch[)\\]]|オランダ翻訳", Pattern.CASE_INSENSITIVE),
|
||||
)
|
||||
private val S_LANG_TAGS = arrayOf(
|
||||
val S_LANG_TAGS = arrayOf(
|
||||
"language:english",
|
||||
"language:chinese",
|
||||
"language:spanish",
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.hippo.ehviewer.client.data
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.IntDef
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.client.EhUrl
|
||||
import com.hippo.ehviewer.client.EhUtils
|
||||
import com.hippo.ehviewer.client.addQueryParameterIfNotBlank
|
||||
@@ -258,24 +259,17 @@ data class ListUrlBuilder(
|
||||
if (category != EhUtils.NONE) {
|
||||
addEncodedQueryParameter("f_cats", (category.inv() and EhUtils.ALL_CATEGORY).toString())
|
||||
}
|
||||
val query = mKeyword?.let {
|
||||
val index = Settings.languageFilter.value
|
||||
GalleryInfo.S_LANG_TAGS.getOrNull(index)?.let { lang ->
|
||||
"$it $lang"
|
||||
} ?: it
|
||||
}
|
||||
addQueryParameterIfNotBlank("f_search", query)
|
||||
addQueryParameterIfNotBlank("f_shash", hash)
|
||||
addQueryParameterIfNotBlank("prev", mPrev)
|
||||
addQueryParameterIfNotBlank("next", mNext)
|
||||
addQueryParameterIfNotBlank("seek", mJumpTo)
|
||||
// Search key
|
||||
// the settings of ub:UrlBuilder may be overwritten by following Advance search
|
||||
mKeyword?.split('|')?.forEachIndexed { idx, kwd ->
|
||||
val keyword = kwd.trim { it <= ' ' }
|
||||
when (idx) {
|
||||
0 -> addQueryParameterIfNotBlank("f_search", keyword)
|
||||
|
||||
else -> keyword.indexOf(':').takeIf { it >= 0 }?.run {
|
||||
val key = keyword.substring(0, this).trim { it <= ' ' }
|
||||
val value = keyword.substring(this + 1).trim { it <= ' ' }
|
||||
addQueryParameterIfNotBlank(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Advance search
|
||||
if (advanceSearch != -1) {
|
||||
addQueryParameter("advsearch", "1")
|
||||
|
||||
@@ -327,7 +327,7 @@ fun DownloadsScreen(navigator: DestinationsNavigator) {
|
||||
onClick = {
|
||||
expanded = false
|
||||
coroutineScope.launch {
|
||||
filterType = dialogState.showSingleChoice(states, filterType + 1) - 1
|
||||
filterType = dialogState.showSingleChoice(*states, selected = filterType + 1) - 1
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -541,6 +541,7 @@ fun GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) {
|
||||
title = suitableTitle,
|
||||
searchFieldState = searchFieldState,
|
||||
searchFieldHint = searchBarHint,
|
||||
showLanguageFilter = true,
|
||||
showSearchFab = showSearchLayout,
|
||||
onApplySearch = { query ->
|
||||
val builder = ListUrlBuilder()
|
||||
@@ -552,11 +553,11 @@ fun GalleryListScreen(lub: ListUrlBuilder, navigator: DestinationsNavigator) {
|
||||
builder.keyword = query
|
||||
} else {
|
||||
if (searchNormalMode) {
|
||||
when (searchMethod) {
|
||||
1 -> builder.mode = MODE_NORMAL
|
||||
2 -> builder.mode = MODE_SUBSCRIPTION
|
||||
3 -> builder.mode = MODE_UPLOADER
|
||||
4 -> builder.mode = MODE_TAG
|
||||
builder.mode = when (searchMethod) {
|
||||
2 -> MODE_SUBSCRIPTION
|
||||
3 -> MODE_UPLOADER
|
||||
4 -> MODE_TAG
|
||||
else -> MODE_NORMAL
|
||||
}
|
||||
builder.keyword = query
|
||||
builder.category = category
|
||||
|
||||
@@ -29,8 +29,11 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.MenuBook
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.FilterAlt
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material.icons.outlined.FilterAlt
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
@@ -64,12 +67,15 @@ import androidx.compose.ui.util.lerp
|
||||
import com.hippo.ehviewer.EhApplication.Companion.searchDatabase
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.asMutableState
|
||||
import com.hippo.ehviewer.client.EhTagDatabase
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.dao.Search
|
||||
import com.hippo.ehviewer.dao.SearchDao
|
||||
import com.hippo.ehviewer.ui.LocalNavDrawerState
|
||||
import com.hippo.ehviewer.ui.LockDrawer
|
||||
import com.hippo.ehviewer.ui.main.FAB_ANIMATE_TIME
|
||||
import com.hippo.ehviewer.ui.tools.IconFix
|
||||
import com.hippo.ehviewer.ui.tools.LocalDialogState
|
||||
import com.jamal.composeprefs3.ui.ifNotNullThen
|
||||
import com.jamal.composeprefs3.ui.ifTrueThen
|
||||
@@ -101,6 +107,7 @@ fun SearchBarScreen(
|
||||
title: String? = null,
|
||||
searchFieldState: TextFieldState,
|
||||
searchFieldHint: String? = null,
|
||||
showLanguageFilter: Boolean = false,
|
||||
showSearchFab: Boolean = false,
|
||||
onApplySearch: suspend (String) -> Unit,
|
||||
onSearchExpanded: () -> Unit,
|
||||
@@ -314,6 +321,42 @@ fun SearchBarScreen(
|
||||
}
|
||||
},
|
||||
) {
|
||||
if (showLanguageFilter) {
|
||||
var languageFilter by Settings.languageFilter.asMutableState()
|
||||
val languages = remember {
|
||||
GalleryInfo.S_LANG_TAGS.map { tag ->
|
||||
tag.substringAfter(':').let {
|
||||
if (EhTagDatabase.initialized && EhTagDatabase.isTranslatable(context)) {
|
||||
EhTagDatabase.getTranslation("l", it) ?: it
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
}.toTypedArray()
|
||||
}
|
||||
Row(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
||||
val any = stringResource(id = R.string.any)
|
||||
val languageStr = stringResource(id = R.string.key_language)
|
||||
FilterChip(
|
||||
selected = languageFilter != -1,
|
||||
onClick = {
|
||||
scope.launch {
|
||||
languageFilter =
|
||||
dialogState.showSingleChoice(any, *languages, selected = languageFilter + 1) - 1
|
||||
}
|
||||
},
|
||||
label = {
|
||||
Text(text = if (languageFilter == -1) languageStr else languages[languageFilter])
|
||||
},
|
||||
trailingIcon = {
|
||||
IconFix(
|
||||
imageVector = if (languageFilter == -1) Icons.Outlined.FilterAlt else Icons.Default.FilterAlt,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = WindowInsets.navigationBars.union(WindowInsets.ime).asPaddingValues(),
|
||||
|
||||
@@ -18,8 +18,10 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
@@ -389,10 +391,10 @@ class DialogState {
|
||||
}
|
||||
|
||||
suspend fun showSingleChoice(
|
||||
items: Array<String>,
|
||||
vararg items: String,
|
||||
selected: Int,
|
||||
): Int = showNoButton {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Column(modifier = Modifier.verticalScroll(rememberScrollState()).padding(vertical = 8.dp)) {
|
||||
items.forEachIndexed { index, text ->
|
||||
Row(
|
||||
modifier = Modifier.clickable { dismissWith(index) }.fillMaxWidth()
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<string name="keyword_search">Nøkkelordssøk</string>
|
||||
<string name="search_sp">Sider:</string>
|
||||
<string name="search_sft">Etiketter</string>
|
||||
<string name="unlimited">Ubegrenset</string>
|
||||
<string name="any">Ubegrenset</string>
|
||||
<plurals name="page_count">
|
||||
<item quantity="one">%d side</item>
|
||||
<item quantity="other">%d sider</item>
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<string name="delete_quick_search">删除快速搜索“%s”?</string>
|
||||
<string name="go_to_hint">第 %1$d 页,共 %2$d 页</string>
|
||||
<!-- search_min_rating -->
|
||||
<string name="unlimited">不限</string>
|
||||
<string name="any">不限</string>
|
||||
<string name="star_2">2 星</string>
|
||||
<string name="star_3">3 星</string>
|
||||
<string name="star_4">4 星</string>
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<string name="delete_quick_search">刪除快速搜尋“%s”?</string>
|
||||
<string name="go_to_hint">第 %1$d 頁,共 %2$d 頁</string>
|
||||
<!-- search_min_rating -->
|
||||
<string name="unlimited">不限</string>
|
||||
<string name="any">不限</string>
|
||||
<string name="star_2">2 星</string>
|
||||
<string name="star_3">3 星</string>
|
||||
<string name="star_4">4 星</string>
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
</integer-array>
|
||||
|
||||
<string-array name="search_min_rating" translatable="false">
|
||||
<item>@string/unlimited</item>
|
||||
<item>@string/any</item>
|
||||
<item>@string/star_2</item>
|
||||
<item>@string/star_3</item>
|
||||
<item>@string/star_4</item>
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<string name="delete_quick_search">Delete quick search \"%s\"?</string>
|
||||
<string name="go_to_hint">Page %1$d, total %2$d pages</string>
|
||||
<!-- search_min_rating -->
|
||||
<string name="unlimited">Unlimited</string>
|
||||
<string name="any">Any</string>
|
||||
<string name="star_2">2 stars</string>
|
||||
<string name="star_3">3 stars</string>
|
||||
<string name="star_4">4 stars</string>
|
||||
|
||||
Reference in new issue
Block a user