Introduce DropdownFilterChip for SearchFilter
This commit is contained in:
1 parent
0295c40b02
commit
4ec7de611c
13 files changed
+91
-53
No files matched your search
@@ -12,9 +12,7 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.FilterAlt
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material.icons.outlined.FilterAlt
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
@@ -39,8 +37,9 @@ import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.asMutableState
|
||||
import com.hippo.ehviewer.client.EhTagDatabase
|
||||
import com.hippo.ehviewer.client.EhUtils
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo.Companion.S_LANG_TAGS
|
||||
import com.hippo.ehviewer.collectAsState
|
||||
import com.hippo.ehviewer.ui.tools.DropdownFilterChip
|
||||
import com.hippo.ehviewer.ui.tools.LocalDialogState
|
||||
import com.hippo.ehviewer.ui.tools.thenIf
|
||||
import com.hippo.ehviewer.util.toIntOrDefault
|
||||
@@ -89,40 +88,44 @@ fun SearchFilter(
|
||||
)
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.horizontalScroll(rememberScrollState()).padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
val any = stringResource(id = R.string.any)
|
||||
val languageStr = stringResource(id = R.string.key_language)
|
||||
FilterChip(
|
||||
selected = languageFilter != -1,
|
||||
onClick = {
|
||||
scope.launch {
|
||||
val items = listOf(any, *languages.toTypedArray())
|
||||
languageFilter = dialogState.awaitSingleChoice(items, languageFilter + 1) - 1
|
||||
val languages = remember {
|
||||
val translatable = EhTagDatabase.initialized && EhTagDatabase.isTranslatable(context)
|
||||
List(S_LANG_TAGS.size + 1) { i ->
|
||||
if (i == 0) {
|
||||
any
|
||||
} else {
|
||||
val tag = S_LANG_TAGS[i - 1].substringAfter(':')
|
||||
if (translatable) {
|
||||
EhTagDatabase.getTranslation("l", tag) ?: tag
|
||||
} else {
|
||||
tag
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var languageFilter by Settings.languageFilter.asMutableState()
|
||||
DropdownFilterChip(
|
||||
label = languageStr,
|
||||
menuItems = languages,
|
||||
selectedItemIndex = languageFilter + 1,
|
||||
onSelectedItemIndexChange = {
|
||||
languageFilter = it - 1
|
||||
},
|
||||
label = {
|
||||
Text(text = if (languageFilter == -1) languageStr else languages[languageFilter])
|
||||
},
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
imageVector = if (languageFilter == -1) Icons.Outlined.FilterAlt else Icons.Default.FilterAlt,
|
||||
contentDescription = null,
|
||||
)
|
||||
)
|
||||
val minRatingItems = stringArrayResource(id = R.array.search_min_rating)
|
||||
val minRatingStr = stringResource(id = R.string.search_sr)
|
||||
DropdownFilterChip(
|
||||
label = minRatingStr,
|
||||
menuItems = minRatingItems.asList(),
|
||||
selectedItemIndex = (advancedOption.minRating - 1).coerceAtLeast(0),
|
||||
onSelectedItemIndexChange = {
|
||||
onAdvancedOptionChanged(advancedOption.copy(minRating = if (it == 0) 0 else it + 1))
|
||||
},
|
||||
)
|
||||
val pageErr1 = stringResource(R.string.search_sp_err1)
|
||||
@@ -204,19 +207,6 @@ fun SearchFilter(
|
||||
},
|
||||
label = { Text(text = pagesText) },
|
||||
)
|
||||
val minRatingItems = stringArrayResource(id = R.array.search_min_rating)
|
||||
val minRatingStr = stringResource(id = R.string.search_sr)
|
||||
val minRatingIndex = (advancedOption.minRating - 1).coerceAtLeast(0)
|
||||
FilterChip(
|
||||
selected = advancedOption.minRating != 0,
|
||||
onClick = {
|
||||
scope.launch {
|
||||
val selected = dialogState.awaitSingleChoice(minRatingItems.toList(), minRatingIndex)
|
||||
onAdvancedOptionChanged(advancedOption.copy(minRating = if (selected == 0) 0 else selected + 1))
|
||||
}
|
||||
},
|
||||
label = { Text(text = minRatingStr + minRatingItems[minRatingIndex]) },
|
||||
)
|
||||
fun checked(bit: Int) = advancedOption.advanceSearch and bit != 0
|
||||
fun AdvancedSearchOption.inv(bit: Int) = onAdvancedOptionChanged(copy(advanceSearch = advanceSearch xor bit))
|
||||
FilterChip(
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.hippo.ehviewer.ui.tools
|
||||
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.MenuAnchorType
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@Composable
|
||||
fun DropdownFilterChip(
|
||||
label: String,
|
||||
menuItems: List<String>,
|
||||
selectedItemIndex: Int,
|
||||
onSelectedItemIndexChange: (Int) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
ExposedDropdownMenuBox(expanded = expanded, onExpandedChange = { expanded = it }, modifier = modifier) {
|
||||
FilterChip(
|
||||
selected = selectedItemIndex != 0,
|
||||
onClick = {},
|
||||
label = {
|
||||
Text(text = if (selectedItemIndex == 0) label else menuItems[selectedItemIndex])
|
||||
},
|
||||
modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable),
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||
)
|
||||
ExposedDropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
||||
menuItems.forEachIndexed { index, item ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = item) },
|
||||
onClick = {
|
||||
expanded = false
|
||||
onSelectedItemIndexChange(index)
|
||||
},
|
||||
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@
|
||||
<string name="search_image">Suche nach einem Bild</string>
|
||||
<string name="search_sh">Gelöschte Galerien anzeigen</string>
|
||||
<string name="search_sto">Nur die Galerien mit Torrentdateien anzeigen</string>
|
||||
<string name="search_sr">Mindestpunktzahl: </string>
|
||||
<string name="search_sr">Mindestpunktzahl</string>
|
||||
<string name="search_sp_to">zu</string>
|
||||
<string name="search_sf">Standard-Filter deaktivieren für: </string>
|
||||
<string name="search_sfl">Sprache</string>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
<string name="search_sh">Mostrar galerías borradas</string>
|
||||
<string name="search_sto">Mostrar solo galerías con torrents</string>
|
||||
<string name="search_sr">Valoración mínima:</string>
|
||||
<string name="search_sr">Valoración mínima</string>
|
||||
<string name="select_image">Seleccionar imagen</string>
|
||||
<string name="select_image_first">Seleccione la imagen primero</string>
|
||||
<string name="search_sp_to">hasta</string>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
<string name="search_sh">Montrer les galeries supprimées</string>
|
||||
<string name="search_sto">Seulement montrer galeries avec des fiches torrent</string>
|
||||
<string name="search_sr">Minimum note :</string>
|
||||
<string name="search_sr">Minimum note</string>
|
||||
<string name="search_sp_to">à</string>
|
||||
<string name="search_sf">Désactiver le filtre par défaut pour les items suivants :</string>
|
||||
<string name="search_sfl">Langue</string>
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
<string name="search_sh">削除済みのギャラリーを表示</string>
|
||||
<string name="search_sto">Torrentのあるギャラリーのみを表示</string>
|
||||
<string name="search_sr">評価の下限:</string>
|
||||
<string name="search_sr">評価の下限</string>
|
||||
<string name="search_sp_to">から</string>
|
||||
<string name="search_sp_suffix">まで</string>
|
||||
<string name="search_sf">既定フィルターから下記のものを例外とする:</string>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
<string name="search_sh">Expunged 갤러리 표시</string>
|
||||
<string name="search_sto">토렌트 파일이 있는 갤러리만 검색</string>
|
||||
<string name="search_sr">최소 평점:</string>
|
||||
<string name="search_sr">최소 평점</string>
|
||||
|
||||
<string name="select_image">이미지 선택</string>
|
||||
<string name="select_image_first">먼저 이미지를 선택해 주세요.</string>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
<string name="search_sh">แสดงแกลเลอรี่ที่ถูกลบออก</string>
|
||||
<string name="search_sto">แสดงผลเฉพาะแกลเลอรี่ที่มีไฟล์ Torrents</string>
|
||||
<string name="search_sr">เรตติ้งขั้นต่ำ:</string>
|
||||
<string name="search_sr">เรตติ้งขั้นต่ำ</string>
|
||||
|
||||
<string name="select_image">เลือกรูปภาพ</string>
|
||||
<string name="select_image_first">โปรดเลือกรูปภาพก่อน</string>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<string name="search_image">Görsel Arama</string>
|
||||
<string name="search_sh">Yalnızca Silinen Galerileri Gösteri</string>
|
||||
<string name="search_sto">Yalnızca Torrent\'li Galerileri Göster</string>
|
||||
<string name="search_sr">En Az Derecelendirme:</string>
|
||||
<string name="search_sr">En Az Derecelendirme</string>
|
||||
<string name="search_sp_to">/</string>
|
||||
<string name="search_sp_err2">Sayfa oranı en az 20 olmalı</string>
|
||||
<string name="search_sf">Varsayılan filtreleri şunlar için devre dışı bırak:</string>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<string name="search_image">图片搜索</string>
|
||||
<string name="search_sh">已删除</string>
|
||||
<string name="search_sto">有种子</string>
|
||||
<string name="search_sr">最低评分:</string>
|
||||
<string name="search_sr">最低评分</string>
|
||||
<string name="search_sp_to">到</string>
|
||||
<string name="search_sp_err1">页数最大值至少为 10</string>
|
||||
<string name="search_sp_err2">页数范围差至少为 20</string>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
<string name="search_sh">已刪除</string>
|
||||
<string name="search_sto">有種子</string>
|
||||
<string name="search_sr">最低評分:</string>
|
||||
<string name="search_sr">最低評分</string>
|
||||
<string name="search_sp_to">到</string>
|
||||
<string name="search_sf">禁用排除項:</string>
|
||||
<string name="search_sfl">語言</string>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<string name="search_image">圖片搜尋</string>
|
||||
<string name="search_sh">已被移除</string>
|
||||
<string name="search_sto">有種子</string>
|
||||
<string name="search_sr">最低評分:</string>
|
||||
<string name="search_sr">最低評分</string>
|
||||
<string name="search_sp_to">到</string>
|
||||
<string name="search_sp_err1">頁數最大值至少為 10</string>
|
||||
<string name="search_sp_err2">頁數範圍差至少為 20</string>
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
<string name="search_image">Image Search</string>
|
||||
<string name="search_sh">Expunged</string>
|
||||
<string name="search_sto">Has Torrent</string>
|
||||
<string name="search_sr">Minimum Rating:</string>
|
||||
<string name="search_sr">Minimum Rating</string>
|
||||
<string name="search_sp_to">to</string>
|
||||
<string name="search_sp_err1">The page range maximum cannot be below 10</string>
|
||||
<string name="search_sp_err2">The page range must be at least 20</string>
|
||||
|
||||
Reference in new issue
Block a user