From 7d41318d157469de1e94920b0e283b6bcbf69c48 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Fri, 8 Jul 2022 13:55:37 +0300 Subject: [PATCH] Add manga sources to search suggestion --- .../kotatsu/core/prefs/AppSettings.kt | 16 ++---- .../koitharu/kotatsu/main/ui/MainActivity.kt | 26 ++++------ .../search/domain/MangaSearchRepository.kt | 13 +++++ .../ui/suggestion/SearchSuggestionFragment.kt | 5 +- .../ui/suggestion/SearchSuggestionListener.kt | 5 +- .../SearchSuggestionMenuProvider.kt | 41 ++++++++++++++++ .../suggestion/SearchSuggestionViewModel.kt | 46 ++++++++--------- .../adapter/SearchSuggestionAdapter.kt | 15 +++++- .../adapter/SearchSuggestionHeaderAD.kt | 29 ----------- .../adapter/SearchSuggestionSourceAD.kt | 49 +++++++++++++++++++ .../suggestion/model/SearchSuggestionItem.kt | 15 +++--- .../layout/item_search_suggestion_header.xml | 28 ----------- .../layout/item_search_suggestion_source.xml | 45 +++++++++++++++++ .../main/res/menu/opt_search_suggestion.xml | 11 +++++ 14 files changed, 222 insertions(+), 122 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionHeaderAD.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionSourceAD.kt delete mode 100644 app/src/main/res/layout/item_search_suggestion_header.xml create mode 100644 app/src/main/res/layout/item_search_suggestion_source.xml create mode 100644 app/src/main/res/menu/opt_search_suggestion.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt index cd9c8a07a..356458852 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -10,13 +10,6 @@ import androidx.collection.arraySetOf import androidx.core.content.edit import androidx.preference.PreferenceManager import com.google.android.material.color.DynamicColors -import java.io.File -import java.text.DateFormat -import java.text.SimpleDateFormat -import java.util.* -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.channels.trySendBlocking -import kotlinx.coroutines.flow.callbackFlow import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.model.ZoomMode import org.koitharu.kotatsu.core.network.DoHProvider @@ -25,6 +18,10 @@ import org.koitharu.kotatsu.utils.ext.getEnumValue import org.koitharu.kotatsu.utils.ext.observe import org.koitharu.kotatsu.utils.ext.putEnumValue import org.koitharu.kotatsu.utils.ext.toUriOrNull +import java.io.File +import java.text.DateFormat +import java.text.SimpleDateFormat +import java.util.* class AppSettings(context: Context) { @@ -195,10 +192,6 @@ class AppSettings(context: Context) { val isSuggestionsExcludeNsfw: Boolean get() = prefs.getBoolean(KEY_SUGGESTIONS_EXCLUDE_NSFW, false) - var isSearchSingleSource: Boolean - get() = prefs.getBoolean(KEY_SEARCH_SINGLE_SOURCE, false) - set(value) = prefs.edit { putBoolean(KEY_SEARCH_SINGLE_SOURCE, value) } - val dnsOverHttps: DoHProvider get() = prefs.getEnumValue(KEY_DOH, DoHProvider.NONE) @@ -308,7 +301,6 @@ class AppSettings(context: Context) { const val KEY_SUGGESTIONS = "suggestions" const val KEY_SUGGESTIONS_EXCLUDE_NSFW = "suggestions_exclude_nsfw" const val KEY_SUGGESTIONS_EXCLUDE_TAGS = "suggestions_exclude_tags" - const val KEY_SEARCH_SINGLE_SOURCE = "search_single_source" const val KEY_SHIKIMORI = "shikimori" const val KEY_DOWNLOADS_PARALLELISM = "downloads_parallelism" const val KEY_DOWNLOADS_SLOWDOWN = "downloads_slowdown" diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index 3fd5bb551..7c6f382ca 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -17,7 +17,6 @@ import androidx.lifecycle.lifecycleScope import androidx.transition.TransitionManager import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout.LayoutParams.* -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.navigation.NavigationBarView import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.Dispatchers @@ -32,10 +31,10 @@ import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.explore.ui.ExploreFragment import org.koitharu.kotatsu.library.ui.LibraryFragment import org.koitharu.kotatsu.parsers.model.Manga +import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.search.ui.MangaListActivity -import org.koitharu.kotatsu.search.ui.SearchActivity import org.koitharu.kotatsu.search.ui.multi.MultiSearchActivity import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionFragment import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener @@ -187,12 +186,7 @@ class MainActivity : binding.searchView.query = query if (submit) { if (query.isNotEmpty()) { - val source = searchSuggestionViewModel.getLocalSearchSource() - if (source != null) { - startActivity(SearchActivity.newIntent(this, source, query)) - } else { - startActivity(MultiSearchActivity.newIntent(this, query)) - } + startActivity(MultiSearchActivity.newIntent(this, query)) searchSuggestionViewModel.saveQuery(query) } } @@ -219,15 +213,13 @@ class MainActivity : voiceInputLauncher.tryLaunch(binding.searchView.hint?.toString(), options) } - override fun onClearSearchHistory() { - MaterialAlertDialogBuilder(this, materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered) - .setTitle(R.string.clear_search_history) - .setIcon(R.drawable.ic_clear_all) - .setMessage(R.string.text_clear_search_history_prompt) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(R.string.clear) { _, _ -> - searchSuggestionViewModel.clearSearchHistory() - }.show() + override fun onSourceToggle(source: MangaSource, isEnabled: Boolean) { + searchSuggestionViewModel.onSourceToggle(source, isEnabled) + } + + override fun onSourceClick(source: MangaSource) { + val intent = MangaListActivity.newIntent(this, source) + startActivity(intent) } override fun onSupportActionModeStarted(mode: ActionMode) { diff --git a/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt b/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt index 2c95fb632..0d29da468 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt @@ -91,6 +91,19 @@ class MangaSearchRepository( } } + fun getSourcesSuggestion(query: String, limit: Int): List { + if (query.length < 3) { + return emptyList() + } + val sources = settings.remoteMangaSources + .filter { x -> x.title.contains(query, ignoreCase = true) } + return if (limit == 0) { + sources + } else { + sources.take(limit) + } + } + fun saveSearchQuery(query: String) { recentSuggestions.saveRecentQuery(query, null) } diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt index 21b5a9104..15c375382 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionFragment.kt @@ -12,9 +12,8 @@ import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.databinding.FragmentSearchSuggestionBinding -import org.koitharu.kotatsu.main.ui.AppBarOwner import org.koitharu.kotatsu.search.ui.suggestion.adapter.SearchSuggestionAdapter -import org.koitharu.kotatsu.utils.ext.measureHeight +import org.koitharu.kotatsu.utils.ext.addMenuProvider class SearchSuggestionFragment : BaseFragment(), @@ -34,7 +33,9 @@ class SearchSuggestionFragment : lifecycleOwner = viewLifecycleOwner, listener = requireActivity() as SearchSuggestionListener, ) + addMenuProvider(SearchSuggestionMenuProvider(view.context, viewModel)) binding.root.adapter = adapter + binding.root.setHasFixedSize(true) viewModel.suggestion.observe(viewLifecycleOwner) { adapter.items = it } diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionListener.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionListener.kt index ea9dfd6f2..cef229058 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionListener.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.search.ui.suggestion import org.koitharu.kotatsu.parsers.model.Manga +import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaTag interface SearchSuggestionListener { @@ -11,7 +12,9 @@ interface SearchSuggestionListener { fun onQueryChanged(query: String) - fun onClearSearchHistory() + fun onSourceToggle(source: MangaSource, isEnabled: Boolean) + + fun onSourceClick(source: MangaSource) fun onTagClick(tag: MangaTag) diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt new file mode 100644 index 000000000..036d7ce32 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt @@ -0,0 +1,41 @@ +package org.koitharu.kotatsu.search.ui.suggestion + +import android.content.Context +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.koitharu.kotatsu.R +import com.google.android.material.R as materialR + +class SearchSuggestionMenuProvider( + private val context: Context, + private val viewModel: SearchSuggestionViewModel, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_search_suggestion, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when (menuItem.itemId) { + R.id.action_clear -> { + clearSearchHistory() + true + } + else -> false + } + } + + private fun clearSearchHistory() { + MaterialAlertDialogBuilder(context, materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered) + .setTitle(R.string.clear_search_history) + .setIcon(R.drawable.ic_clear_all) + .setMessage(R.string.text_clear_search_history_prompt) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton(R.string.clear) { _, _ -> + viewModel.clearSearchHistory() + }.show() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionViewModel.kt index 605f3a231..184b3e746 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionViewModel.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.* import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.base.ui.widgets.ChipsView import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.core.prefs.observeAsFlow import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.search.domain.MangaSearchRepository @@ -16,6 +17,7 @@ private const val DEBOUNCE_TIMEOUT = 500L private const val MAX_MANGA_ITEMS = 6 private const val MAX_QUERY_ITEMS = 16 private const val MAX_TAGS_ITEMS = 8 +private const val MAX_SOURCES_ITEMS = 6 class SearchSuggestionViewModel( private val repository: MangaSearchRepository, @@ -23,41 +25,36 @@ class SearchSuggestionViewModel( ) : BaseViewModel() { private val query = MutableStateFlow("") - private val source = MutableStateFlow(null) - private val isLocalSearch = MutableStateFlow(settings.isSearchSingleSource) private var suggestionJob: Job? = null val suggestion = MutableLiveData>() init { setupSuggestion() - isLocalSearch.onEach { - settings.isSearchSingleSource = it - }.launchIn(viewModelScope) } fun onQueryChanged(newQuery: String) { query.value = newQuery } - fun onSourceChanged(newSource: MangaSource?) { - source.value = newSource - } - fun saveQuery(query: String) { repository.saveSearchQuery(query) } - fun getLocalSearchSource(): MangaSource? { - return source.value?.takeIf { isLocalSearch.value } - } - fun clearSearchHistory() { launchJob { repository.clearSearchHistory() setupSuggestion() } } + + fun onSourceToggle(source: MangaSource, isEnabled: Boolean) { + settings.hiddenSources = if (isEnabled) { + settings.hiddenSources - source.name + } else { + settings.hiddenSources + source.name + } + } fun deleteQuery(query: String) { launchJob { @@ -70,11 +67,10 @@ class SearchSuggestionViewModel( suggestionJob?.cancel() suggestionJob = combine( query.debounce(DEBOUNCE_TIMEOUT), - source, - isLocalSearch, - ::Triple, - ).mapLatest { (searchQuery, src, srcOnly) -> - buildSearchSuggestion(searchQuery, src, srcOnly) + settings.observeAsFlow(AppSettings.KEY_SOURCES_HIDDEN) { hiddenSources }, + ::Pair, + ).mapLatest { (searchQuery, hiddenSources) -> + buildSearchSuggestion(searchQuery, hiddenSources) }.distinctUntilChanged() .onEach { suggestion.postValue(it) @@ -83,27 +79,24 @@ class SearchSuggestionViewModel( private suspend fun buildSearchSuggestion( searchQuery: String, - src: MangaSource?, - srcOnly: Boolean, + hiddenSources: Set, ): List = coroutineScope { val queriesDeferred = async { repository.getQuerySuggestion(searchQuery, MAX_QUERY_ITEMS) } val tagsDeferred = async { - repository.getTagsSuggestion(searchQuery, MAX_TAGS_ITEMS, src.takeIf { srcOnly }) + repository.getTagsSuggestion(searchQuery, MAX_TAGS_ITEMS, null) } val mangaDeferred = async { - repository.getMangaSuggestion(searchQuery, MAX_MANGA_ITEMS, src.takeIf { srcOnly }) + repository.getMangaSuggestion(searchQuery, MAX_MANGA_ITEMS, null) } + val sources = repository.getSourcesSuggestion(searchQuery, MAX_SOURCES_ITEMS) val tags = tagsDeferred.await() val mangaList = mangaDeferred.await() val queries = queriesDeferred.await() - buildList(queries.size + 3) { - if (src != null) { - add(SearchSuggestionItem.Header(src, isLocalSearch)) - } + buildList(queries.size + sources.size + 2) { if (tags.isNotEmpty()) { add(SearchSuggestionItem.Tags(mapTags(tags))) } @@ -111,6 +104,7 @@ class SearchSuggestionViewModel( add(SearchSuggestionItem.MangaList(mangaList)) } queries.mapTo(this) { SearchSuggestionItem.RecentQuery(it) } + sources.mapTo(this) { SearchSuggestionItem.Source(it, it.name !in hiddenSources) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt index 86a8d5283..121ef63f7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt @@ -19,7 +19,7 @@ class SearchSuggestionAdapter( init { delegatesManager .addDelegate(SEARCH_SUGGESTION_ITEM_TYPE_QUERY, searchSuggestionQueryAD(listener)) - .addDelegate(searchSuggestionHeaderAD(listener)) + .addDelegate(searchSuggestionSourceAD(coil, lifecycleOwner, listener)) .addDelegate(searchSuggestionTagsAD(listener)) .addDelegate(searchSuggestionMangaListAD(coil, lifecycleOwner, listener)) } @@ -33,6 +33,9 @@ class SearchSuggestionAdapter( oldItem is SearchSuggestionItem.RecentQuery && newItem is SearchSuggestionItem.RecentQuery -> { oldItem.query == newItem.query } + oldItem is SearchSuggestionItem.Source && newItem is SearchSuggestionItem.Source -> { + oldItem.source == newItem.source + } else -> oldItem.javaClass == newItem.javaClass } @@ -40,5 +43,15 @@ class SearchSuggestionAdapter( oldItem: SearchSuggestionItem, newItem: SearchSuggestionItem, ): Boolean = Intrinsics.areEqual(oldItem, newItem) + + override fun getChangePayload(oldItem: SearchSuggestionItem, newItem: SearchSuggestionItem): Any? { + return when { + oldItem is SearchSuggestionItem.MangaList && newItem is SearchSuggestionItem.MangaList -> Unit + oldItem is SearchSuggestionItem.Source && newItem is SearchSuggestionItem.Source -> { + if (oldItem.isEnabled != newItem.isEnabled) Unit else super.getChangePayload(oldItem, newItem) + } + else -> super.getChangePayload(oldItem, newItem) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionHeaderAD.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionHeaderAD.kt deleted file mode 100644 index be60708cd..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionHeaderAD.kt +++ /dev/null @@ -1,29 +0,0 @@ -package org.koitharu.kotatsu.search.ui.suggestion.adapter - -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding -import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.databinding.ItemSearchSuggestionHeaderBinding -import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener -import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem - -fun searchSuggestionHeaderAD( - listener: SearchSuggestionListener, -) = adapterDelegateViewBinding( - { inflater, parent -> ItemSearchSuggestionHeaderBinding.inflate(inflater, parent, false) } - ) { - - binding.switchLocal.setOnCheckedChangeListener { _, isChecked -> - item.isChecked.value = isChecked - } - binding.buttonClear.setOnClickListener { - listener.onClearSearchHistory() - } - - bind { - binding.switchLocal.text = getString( - R.string.search_only_on_s, - item.source.title, - ) - binding.switchLocal.isChecked = item.isChecked.value - } - } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionSourceAD.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionSourceAD.kt new file mode 100644 index 000000000..ce80c6bc3 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionSourceAD.kt @@ -0,0 +1,49 @@ +package org.koitharu.kotatsu.search.ui.suggestion.adapter + +import androidx.lifecycle.LifecycleOwner +import coil.ImageLoader +import coil.request.Disposable +import coil.request.ImageRequest +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding +import org.koitharu.kotatsu.databinding.ItemSearchSuggestionSourceBinding +import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener +import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem +import org.koitharu.kotatsu.utils.ext.enqueueWith +import org.koitharu.kotatsu.utils.image.FaviconFallbackDrawable + +fun searchSuggestionSourceAD( + coil: ImageLoader, + lifecycleOwner: LifecycleOwner, + listener: SearchSuggestionListener, +) = adapterDelegateViewBinding( + { inflater, parent -> ItemSearchSuggestionSourceBinding.inflate(inflater, parent, false) } +) { + + var imageRequest: Disposable? = null + + binding.switchLocal.setOnCheckedChangeListener { _, isChecked -> + listener.onSourceToggle(item.source, isChecked) + } + binding.root.setOnClickListener { + listener.onSourceClick(item.source) + } + + bind { + binding.textViewTitle.text = item.source.title + binding.switchLocal.isChecked = item.isEnabled + val fallbackIcon = FaviconFallbackDrawable(context, item.source.name) + imageRequest = ImageRequest.Builder(context) + .data(item.faviconUrl) + .fallback(fallbackIcon) + .placeholder(fallbackIcon) + .error(fallbackIcon) + .target(binding.imageViewCover) + .lifecycle(lifecycleOwner) + .enqueueWith(coil) + } + + onViewRecycled { + imageRequest?.dispose() + imageRequest = null + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt index 341c89ac8..d1126f59c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt @@ -1,6 +1,6 @@ package org.koitharu.kotatsu.search.ui.suggestion.model -import kotlinx.coroutines.flow.MutableStateFlow +import android.net.Uri import org.koitharu.kotatsu.base.ui.widgets.ChipsView import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaSource @@ -52,26 +52,29 @@ sealed interface SearchSuggestionItem { } } - class Header( + class Source( val source: MangaSource, - val isChecked: MutableStateFlow, + val isEnabled: Boolean, ) : SearchSuggestionItem { + val faviconUrl: Uri + get() = Uri.fromParts("favicon", source.name, null) + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false - other as Header + other as Source if (source != other.source) return false - if (isChecked !== other.isChecked) return false + if (isEnabled != other.isEnabled) return false return true } override fun hashCode(): Int { var result = source.hashCode() - result = 31 * result + isChecked.hashCode() + result = 31 * result + isEnabled.hashCode() return result } } diff --git a/app/src/main/res/layout/item_search_suggestion_header.xml b/app/src/main/res/layout/item_search_suggestion_header.xml deleted file mode 100644 index 7dfd54154..000000000 --- a/app/src/main/res/layout/item_search_suggestion_header.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_search_suggestion_source.xml b/app/src/main/res/layout/item_search_suggestion_source.xml new file mode 100644 index 000000000..23636ad87 --- /dev/null +++ b/app/src/main/res/layout/item_search_suggestion_source.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/opt_search_suggestion.xml b/app/src/main/res/menu/opt_search_suggestion.xml new file mode 100644 index 000000000..9570cd8a3 --- /dev/null +++ b/app/src/main/res/menu/opt_search_suggestion.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file