From 95fbe496cb06207475df4e100cfe9d1599332aee Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 22 Nov 2023 16:11:23 +0200 Subject: [PATCH] Search through all sources in catalog --- .../sources/catalog/SourceCatalogItem.kt | 3 +- .../sources/catalog/SourceCatalogItemAD.kt | 7 +++++ .../sources/catalog/SourcesCatalogActivity.kt | 20 +++++++++++-- .../catalog/SourcesCatalogListProducer.kt | 14 +++++---- .../catalog/SourcesCatalogMenuProvider.kt | 7 +++-- .../catalog/SourcesCatalogViewModel.kt | 6 ++-- .../main/res/layout/item_source_catalog.xml | 29 +++++++++++++++---- app/src/main/res/values/strings.xml | 2 +- 8 files changed, 66 insertions(+), 22 deletions(-) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItem.kt index 9ea1e55c0..34c84e2c4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItem.kt @@ -8,7 +8,8 @@ import org.koitharu.kotatsu.parsers.model.MangaSource sealed interface SourceCatalogItem : ListModel { data class Source( - val source: MangaSource + val source: MangaSource, + val showSummary: Boolean, ) : SourceCatalogItem { override fun areItemsTheSame(other: ListModel): Boolean { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItemAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItemAD.kt index 21abf7aff..55c4b412f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItemAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourceCatalogItemAD.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.LifecycleOwner import coil.ImageLoader import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.model.getSummary import org.koitharu.kotatsu.core.model.isNsfw import org.koitharu.kotatsu.core.parser.favicon.faviconUri import org.koitharu.kotatsu.core.ui.image.FaviconDrawable @@ -43,6 +44,12 @@ fun sourceCatalogItemSourceAD( } else { item.source.title } + if (item.showSummary) { + binding.textViewDescription.text = item.source.getSummary(context) + binding.textViewDescription.isVisible = true + } else { + binding.textViewDescription.isVisible = false + } val fallbackIcon = FaviconDrawable(context, R.style.FaviconDrawable_Small, item.source.name) binding.imageViewIcon.newImageRequest(lifecycleOwner, item.source.faviconUri())?.run { crossfade(context) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt index 7c3900100..a67cd0508 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogActivity.kt @@ -1,9 +1,12 @@ package org.koitharu.kotatsu.settings.sources.catalog import android.os.Bundle +import android.view.MenuItem import android.view.View import androidx.activity.viewModels +import androidx.appcompat.widget.SearchView import androidx.core.graphics.Insets +import androidx.core.view.isVisible import androidx.core.view.updatePadding import coil.ImageLoader import com.google.android.material.appbar.AppBarLayout @@ -28,7 +31,7 @@ import javax.inject.Inject class SourcesCatalogActivity : BaseActivity(), TabLayout.OnTabSelectedListener, OnListItemClickListener, - AppBarOwner { + AppBarOwner, MenuItem.OnActionExpandListener { @Inject lateinit var coil: ImageLoader @@ -56,7 +59,7 @@ class SourcesCatalogActivity : BaseActivity(), viewModel.locale.observe(this) { supportActionBar?.subtitle = it.getLocaleDisplayName() } - addMenuProvider(SourcesCatalogMenuProvider(this, viewModel)) + addMenuProvider(SourcesCatalogMenuProvider(this, viewModel, this)) } override fun onWindowInsetsChanged(insets: Insets) { @@ -83,6 +86,19 @@ class SourcesCatalogActivity : BaseActivity(), viewBinding.recyclerView.firstVisibleItemPosition = 0 } + override fun onMenuItemActionExpand(item: MenuItem): Boolean { + viewBinding.tabs.isVisible = false + val sq = (item.actionView as? SearchView)?.query?.trim()?.toString().orEmpty() + viewModel.performSearch(sq) + return true + } + + override fun onMenuItemActionCollapse(item: MenuItem): Boolean { + viewBinding.tabs.isVisible = true + viewModel.performSearch(null) + return true + } + private fun initTabs() { val tabs = viewBinding.tabs for (type in ContentType.entries) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogListProducer.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogListProducer.kt index dfa0cc296..40c42c3e2 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogListProducer.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogListProducer.kt @@ -28,7 +28,7 @@ class SourcesCatalogListProducer @AssistedInject constructor( ) : InvalidationTracker.Observer(TABLE_SOURCES), RetainedLifecycle.OnClearedListener { private val scope = lifecycle.lifecycleScope - private var query: String = "" + private var query: String? = null val list = MutableStateFlow(emptyList()) private var job = scope.launch(Dispatchers.Default) { @@ -54,20 +54,21 @@ class SourcesCatalogListProducer @AssistedInject constructor( } } - fun setQuery(value: String) { + fun setQuery(value: String?) { this.query = value onInvalidated(emptySet()) } private suspend fun buildList(): List { val sources = repository.getDisabledSources().toMutableList() - sources.retainAll { it.contentType == contentType && it.locale == locale } - if (query.isNotEmpty()) { - sources.retainAll { it.title.contains(query, ignoreCase = true) } + when (val q = query) { + null -> sources.retainAll { it.contentType == contentType && it.locale == locale } + "" -> return emptyList() + else -> sources.retainAll { it.title.contains(q, ignoreCase = true) } } return if (sources.isEmpty()) { listOf( - if (query.isEmpty()) { + if (query == null) { SourceCatalogItem.Hint( icon = R.drawable.ic_empty_feed, title = R.string.no_manga_sources, @@ -86,6 +87,7 @@ class SourcesCatalogListProducer @AssistedInject constructor( sources.map { SourceCatalogItem.Source( source = it, + showSummary = query != null, ) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogMenuProvider.kt index 2c365bbaf..db569ed39 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogMenuProvider.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogMenuProvider.kt @@ -15,6 +15,7 @@ import org.koitharu.kotatsu.parsers.util.toTitleCase class SourcesCatalogMenuProvider( private val activity: Activity, private val viewModel: SourcesCatalogViewModel, + private val expandListener: MenuItem.OnActionExpandListener, ) : MenuProvider, MenuItem.OnActionExpandListener, SearchView.OnQueryTextListener { @@ -40,18 +41,18 @@ class SourcesCatalogMenuProvider( override fun onMenuItemActionExpand(item: MenuItem): Boolean { (activity as? AppBarOwner)?.appBar?.setExpanded(false, true) - return true + return expandListener.onMenuItemActionExpand(item) } override fun onMenuItemActionCollapse(item: MenuItem): Boolean { (item.actionView as SearchView).setQuery("", false) - return true + return expandListener.onMenuItemActionCollapse(item) } override fun onQueryTextSubmit(query: String?): Boolean = false override fun onQueryTextChange(newText: String?): Boolean { - viewModel.performSearch(newText.orEmpty()) + viewModel.performSearch(newText?.trim().orEmpty()) return true } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogViewModel.kt index 9a6f864f2..2ac9ef081 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogViewModel.kt @@ -29,11 +29,11 @@ import javax.inject.Inject class SourcesCatalogViewModel @Inject constructor( private val repository: MangaSourcesRepository, private val listProducerFactory: SourcesCatalogListProducer.Factory, - private val settings: AppSettings, + settings: AppSettings, ) : BaseViewModel() { private val lifecycle = RetainedLifecycleImpl() - private var searchQuery: String = "" + private var searchQuery: String? = null val onActionDone = MutableEventFlow() val contentType = MutableStateFlow(ContentType.entries.first()) val locales = getLocalesImpl() @@ -59,7 +59,7 @@ class SourcesCatalogViewModel @Inject constructor( lifecycle.dispatchOnCleared() } - fun performSearch(query: String) { + fun performSearch(query: String?) { searchQuery = query listProducer.value?.setQuery(query) } diff --git a/app/src/main/res/layout/item_source_catalog.xml b/app/src/main/res/layout/item_source_catalog.xml index a1a67ebed..b7c73edd0 100644 --- a/app/src/main/res/layout/item_source_catalog.xml +++ b/app/src/main/res/layout/item_source_catalog.xml @@ -23,17 +23,34 @@ app:shapeAppearance="?shapeAppearanceCornerSmall" tools:src="@tools:sample/avatars" /> - + android:orientation="vertical"> + + + + + + %1$s, %2$s Sources catalog Source enabled - No available sources in this section yet. Stay tuned + There are no sources available in this section, or all of it might have been already added.\nStay tuned No available manga sources found by your query Catalog Manage sources