diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt index b4ef7f708..fb098de43 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt @@ -4,16 +4,31 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import org.koin.core.KoinComponent import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.SortOrder +import java.util.* class MangaSearchRepository : KoinComponent { - fun globalSearch(query: String): Flow> = flow { + fun globalSearch(query: String, batchSize: Int = 4): Flow> = flow { val sources = MangaProviderFactory.getSources(false) - for (source in sources) { - val provider = MangaProviderFactory.create(source) - val list = provider.getList(0, query, SortOrder.POPULARITY) - emit(list.take(4)) + val lists = EnumMap>(MangaSource::class.java) + var i = 0 + while (true) { + var isEmitted = false + for (source in sources) { + val list = lists.getOrPut(source) { + MangaProviderFactory.create(source).getList(0, query, SortOrder.POPULARITY) + } + if (i < list.size) { + emit(list.subList(i, (i + batchSize).coerceAtMost(list.lastIndex))) + isEmitted = true + } + } + i += batchSize + if (!isEmitted) { + return@flow + } } } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt index f085b479d..636a9df22 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt @@ -2,12 +2,13 @@ package org.koitharu.kotatsu.ui.list.remote import android.view.Menu import android.view.MenuInflater +import android.view.MenuItem import moxy.ktx.moxyPresenter import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaFilter import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.ui.list.MangaListFragment -import org.koitharu.kotatsu.ui.search.SearchHelper +import org.koitharu.kotatsu.ui.search.SearchActivity import org.koitharu.kotatsu.utils.ext.withArgs class RemoteListFragment : MangaListFragment() { @@ -31,12 +32,17 @@ class RemoteListFragment : MangaListFragment() { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.opt_remote, menu) - menu.findItem(R.id.action_search)?.let { menuItem -> - SearchHelper.setupSearchView(menuItem, source) - } super.onCreateOptionsMenu(menu, inflater) } + override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { + R.id.action_search_internal -> { + context?.startActivity(SearchActivity.newIntent(requireContext(), source, null)) + true + } + else -> super.onOptionsItemSelected(item) + } + companion object { private const val ARG_SOURCE = "provider" diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchActivity.kt index eb43b0727..0fe84d044 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchActivity.kt @@ -4,38 +4,60 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.os.Parcelable +import androidx.appcompat.widget.SearchView +import kotlinx.android.synthetic.main.activity_search.* import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.ui.common.BaseActivity +import org.koitharu.kotatsu.utils.ext.showKeyboard -class SearchActivity : BaseActivity() { +class SearchActivity : BaseActivity(), SearchView.OnQueryTextListener { + + private lateinit var source: MangaSource override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_search) - val source = intent.getParcelableExtra(EXTRA_SOURCE) - val query = intent.getStringExtra(EXTRA_QUERY) - - if (source == null || query == null) { + source = intent.getParcelableExtra(EXTRA_SOURCE) ?: run { finish() return } - + val query = intent.getStringExtra(EXTRA_QUERY) supportActionBar?.setDisplayHomeAsUpEnabled(true) - title = query - supportActionBar?.subtitle = getString(R.string.search_results_on_s, source.title) - supportFragmentManager - .beginTransaction() - .replace(R.id.container, SearchFragment.newInstance(source, query)) - .commit() + searchView.queryHint = getString(R.string.search_on_s, source.title) + searchView.suggestionsAdapter = MangaSuggestionsProvider.getSuggestionAdapter(this) + searchView.setOnSuggestionListener(SearchHelper.SuggestionListener(searchView)) + searchView.setOnQueryTextListener(this) + + if (query.isNullOrBlank()) { + searchView.requestFocus() + searchView.showKeyboard() + } else { + searchView.setQuery(query, true) + } } + override fun onQueryTextSubmit(query: String?): Boolean { + return if (!query.isNullOrBlank()) { + title = query + supportFragmentManager + .beginTransaction() + .replace(R.id.container, SearchFragment.newInstance(source, query)) + .commit() + searchView.clearFocus() + MangaSuggestionsProvider.saveQuery(this, query) + true + } else false + } + + override fun onQueryTextChange(newText: String?) = false + companion object { private const val EXTRA_SOURCE = "source" private const val EXTRA_QUERY = "query" - fun newIntent(context: Context, source: MangaSource, query: String) = + fun newIntent(context: Context, source: MangaSource, query: String?) = Intent(context, SearchActivity::class.java) .putExtra(EXTRA_SOURCE, source as Parcelable) .putExtra(EXTRA_QUERY, query) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchHelper.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchHelper.kt index aed6383cd..231804de8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchHelper.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchHelper.kt @@ -6,22 +6,11 @@ import android.database.Cursor import android.view.MenuItem import androidx.appcompat.widget.SearchView import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.ui.search.global.GlobalSearchActivity import org.koitharu.kotatsu.utils.ext.safe object SearchHelper { - @JvmStatic - fun setupSearchView(menuItem: MenuItem, source: MangaSource) { - val view = menuItem.actionView as? SearchView ?: return - val context = view.context - view.queryHint = context.getString(R.string.search_manga) - view.suggestionsAdapter = MangaSuggestionsProvider.getSuggestionAdapter(context) - view.setOnQueryTextListener(QueryListener(context, source)) - view.setOnSuggestionListener(SuggestionListener(view)) - } - @JvmStatic fun setupSearchView(menuItem: MenuItem) { val view = menuItem.actionView as? SearchView ?: return @@ -32,16 +21,12 @@ object SearchHelper { view.setOnSuggestionListener(SuggestionListener(view)) } - private class QueryListener(private val context: Context, private val source: MangaSource? = null) : + private class QueryListener(private val context: Context) : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String?): Boolean { return if (!query.isNullOrBlank()) { - if (source == null) { - context.startActivity(GlobalSearchActivity.newIntent(context, query.trim())) - } else { - context.startActivity(SearchActivity.newIntent(context, source, query.trim())) - } + context.startActivity(GlobalSearchActivity.newIntent(context, query.trim())) MangaSuggestionsProvider.saveQuery(context, query) true } else false @@ -50,7 +35,7 @@ object SearchHelper { override fun onQueryTextChange(newText: String?) = false } - private class SuggestionListener(private val view: SearchView) : + class SuggestionListener(private val view: SearchView) : SearchView.OnSuggestionListener { override fun onSuggestionSelect(position: Int) = false diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchActivity.kt index 0c5ce0822..a39d9bd5b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchActivity.kt @@ -10,7 +10,7 @@ class GlobalSearchActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_search) + setContentView(R.layout.activity_search_global) val query = intent.getStringExtra(EXTRA_QUERY) if (query == null) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt index 7227fa02e..730dc9ec8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt @@ -34,6 +34,7 @@ class GlobalSearchPresenter : BasePresenter>() { } } .onFirst { + viewState.onListChanged(emptyList()) viewState.onLoadingStateChanged(isLoading = false) } .onEmpty { diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index d787f32d6..871e7273b 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -9,8 +9,8 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fitsSystemWindows="true" android:background="?colorPrimary" + android:fitsSystemWindows="true" android:theme="@style/AppToolbarTheme"> + app:popupTheme="@style/AppPopupTheme"> + + + + diff --git a/app/src/main/res/layout/activity_search_global.xml b/app/src/main/res/layout/activity_search_global.xml new file mode 100644 index 000000000..d787f32d6 --- /dev/null +++ b/app/src/main/res/layout/activity_search_global.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/opt_remote.xml b/app/src/main/res/menu/opt_remote.xml index 598d68e1d..e18367ea1 100644 --- a/app/src/main/res/menu/opt_remote.xml +++ b/app/src/main/res/menu/opt_remote.xml @@ -5,10 +5,8 @@ + app:showAsAction="never" /> \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index b90171d43..cab7c4605 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -78,6 +78,7 @@ Режим чтения Размер таблицы Результаты поиска по %s + Поиск по %s Удалить мангу Вы уверены, что хотите удалить \"%s\" с устройства? \nЭто действие нельзя будет отменить. Настройки чтения diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 526a8e6c3..8cb973dc5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -79,6 +79,7 @@ Read mode Grid size Search results on %s + Search on %s Delete manga Do you really want to delete \"%s\" from your phone\'s local storage? \nThis operation cannot be undone. Reader settings