Skip to content
This repository was archived by the owner on Nov 4, 2025. It is now read-only.

Commit 119b7c2

Browse files
Add filtering options for pinned sources and empty results in search menu
1 parent 5701862 commit 119b7c2

File tree

5 files changed

+68
-10
lines changed

5 files changed

+68
-10
lines changed

app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class SearchActivity :
9494
setDisplayHomeAsUp(isEnabled = true, showUpAsClose = false)
9595
supportActionBar?.setSubtitle(R.string.search_results)
9696

97-
addMenuProvider(SearchKindMenuProvider(this, viewModel.query, viewModel.kind))
97+
addMenuProvider(SearchKindMenuProvider(this, viewModel, viewModel.query, viewModel.kind))
9898

9999
viewModel.list.observe(this, adapter)
100100
viewModel.onError.observeEvent(this, SnackbarErrorObserver(viewBinding.recyclerView, null))

app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchKindMenuProvider.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import org.koitharu.kotatsu.search.domain.SearchKind
1111

1212
class SearchKindMenuProvider(
1313
private val activity: SearchActivity,
14+
private val viewModel: SearchViewModel,
1415
private val query: String,
15-
private val kind: SearchKind
16+
private val kind: SearchKind,
1617
) : MenuProvider {
1718

1819
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
@@ -32,6 +33,20 @@ class SearchKindMenuProvider(
3233
}
3334

3435
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
36+
when (menuItem.itemId) {
37+
R.id.action_filter_pinned_only -> {
38+
menuItem.isChecked = !menuItem.isChecked
39+
viewModel.setPinnedOnly(menuItem.isChecked)
40+
return true
41+
}
42+
43+
R.id.action_filter_hide_empty -> {
44+
menuItem.isChecked = !menuItem.isChecked
45+
viewModel.setHideEmpty(menuItem.isChecked)
46+
return true
47+
}
48+
}
49+
3550
val newKind = when (menuItem.itemId) {
3651
R.id.action_kind_simple -> SearchKind.SIMPLE
3752
R.id.action_kind_title -> SearchKind.TITLE

app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchViewModel.kt

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class SearchViewModel @Inject constructor(
6262
val kind = savedStateHandle.get<SearchKind>(AppRouter.KEY_KIND) ?: SearchKind.SIMPLE
6363

6464
private var includeDisabledSources = MutableStateFlow(false)
65+
private var pinnedOnly = MutableStateFlow(false)
66+
private var hideEmpty = MutableStateFlow(false)
6567
private val results = MutableStateFlow<List<SearchResultsListModel>>(emptyList())
6668

6769
private var searchJob: Job? = null
@@ -70,9 +72,15 @@ class SearchViewModel @Inject constructor(
7072
results,
7173
isLoading.dropWhile { !it },
7274
includeDisabledSources,
73-
) { list, loading, includeDisabled ->
75+
hideEmpty,
76+
) { list, loading, includeDisabled, hideEmptyVal ->
77+
val filteredList = if (hideEmptyVal) {
78+
list.filter { it.list.isNotEmpty() }
79+
} else {
80+
list
81+
}
7482
when {
75-
list.isEmpty() -> listOf(
83+
filteredList.isEmpty() -> listOf(
7684
when {
7785
loading -> LoadingState
7886
else -> EmptyState(
@@ -84,9 +92,9 @@ class SearchViewModel @Inject constructor(
8492
},
8593
)
8694

87-
loading -> list + LoadingFooter()
88-
includeDisabled -> list
89-
else -> list + ButtonFooter(R.string.search_disabled_sources)
95+
loading -> filteredList + LoadingFooter()
96+
includeDisabled -> filteredList
97+
else -> filteredList + ButtonFooter(R.string.search_disabled_sources)
9098
}
9199
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, listOf(LoadingState))
92100

@@ -114,6 +122,17 @@ class SearchViewModel @Inject constructor(
114122
doSearch()
115123
}
116124

125+
fun setPinnedOnly(value: Boolean) {
126+
if (pinnedOnly.value != value) {
127+
pinnedOnly.value = value
128+
retry()
129+
}
130+
}
131+
132+
fun setHideEmpty(value: Boolean) {
133+
hideEmpty.value = value
134+
}
135+
117136
fun continueSearch() {
118137
if (includeDisabledSources.value) {
119138
return
@@ -122,8 +141,12 @@ class SearchViewModel @Inject constructor(
122141
searchJob = launchLoadingJob(Dispatchers.Default) {
123142
includeDisabledSources.value = true
124143
prevJob?.join()
125-
val sources = sourcesRepository.getDisabledSources()
126-
.sortedByDescending { it.priority() }
144+
val sources = if (pinnedOnly.value) {
145+
emptyList()
146+
} else {
147+
sourcesRepository.getDisabledSources()
148+
.sortedByDescending { it.priority() }
149+
}
127150
val semaphore = Semaphore(MAX_PARALLELISM)
128151
sources.map { source ->
129152
launch {
@@ -142,7 +165,11 @@ class SearchViewModel @Inject constructor(
142165
appendResult(searchHistory())
143166
appendResult(searchFavorites())
144167
appendResult(searchLocal())
145-
val sources = sourcesRepository.getEnabledSources()
168+
val sources = if (pinnedOnly.value) {
169+
sourcesRepository.getPinnedSources().toList()
170+
} else {
171+
sourcesRepository.getEnabledSources()
172+
}
146173
val semaphore = Semaphore(MAX_PARALLELISM)
147174
sources.map { source ->
148175
launch {

app/src/main/res/menu/opt_search_kind.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@
3333
android:title="@string/genre" />
3434

3535
</group>
36+
37+
<group android:id="@+id/group_search_filters">
38+
39+
<item
40+
android:id="@+id/action_filter_pinned_only"
41+
android:checkable="true"
42+
android:title="@string/pinned_sources_only" />
43+
44+
<item
45+
android:id="@+id/action_filter_hide_empty"
46+
android:checkable="true"
47+
android:title="@string/hide_empty_sources" />
48+
49+
</group>
3650
</menu>
3751

3852
</item>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@
210210
<string name="disabled">Disabled</string>
211211
<string name="reset_filter">Reset filter</string>
212212
<string name="enter_name">Enter name</string>
213+
<string name="pinned_sources_only">Pinned sources only</string>
214+
<string name="hide_empty_sources">Hide empty sources</string>
213215
<string name="onboard_text">Select languages which you want to read manga. You can change it later in settings.</string>
214216
<string name="never">Never</string>
215217
<string name="only_using_wifi">Only on Wi-Fi</string>

0 commit comments

Comments
 (0)