Add shortcut to global search query from library (closes #2183)

This commit is contained in:
arkon 2020-07-10 17:33:16 -04:00
parent 1813dbbf59
commit 763da19c9d
4 changed files with 61 additions and 20 deletions

View File

@ -129,6 +129,9 @@ open class ExtensionController :
val searchView = searchItem.actionView as SearchView val searchView = searchItem.actionView as SearchView
searchView.maxWidth = Int.MAX_VALUE searchView.maxWidth = Int.MAX_VALUE
// Fixes problem with the overflow icon showing up in lieu of search
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
if (query.isNotEmpty()) { if (query.isNotEmpty()) {
searchItem.expandActionView() searchItem.expandActionView()
searchView.setQuery(query, true) searchView.setQuery(query, true)
@ -142,9 +145,6 @@ open class ExtensionController :
drawExtensions() drawExtensions()
} }
.launchIn(scope) .launchIn(scope)
// Fixes problem with the overflow icon showing up in lieu of search
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
} }
override fun onItemClick(view: View, position: Int): Boolean { override fun onItemClick(view: View, position: Int): Boolean {

View File

@ -33,18 +33,22 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.RootController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.hasCustomCover import eu.kanade.tachiyomi.util.hasCustomCover
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visible
import kotlinx.android.synthetic.main.main_activity.tabs import kotlinx.android.synthetic.main.main_activity.tabs
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.view.clicks
import reactivecircus.flowbinding.appcompat.queryTextChanges import reactivecircus.flowbinding.appcompat.queryTextChanges
import reactivecircus.flowbinding.viewpager.pageSelections import reactivecircus.flowbinding.viewpager.pageSelections
import rx.Subscription import rx.Subscription
@ -77,7 +81,7 @@ class LibraryController(
/** /**
* Library search query. * Library search query.
*/ */
private var query = "" private var query: String? = ""
/** /**
* Currently selected mangas. * Currently selected mangas.
@ -204,6 +208,14 @@ class LibraryController(
binding.downloadedOnly.visible() binding.downloadedOnly.visible()
} }
binding.btnGlobalSearch.clicks()
.onEach {
router.pushController(
GlobalSearchController(query).withFadeTransaction()
)
}
.launchIn(scope)
binding.actionToolbar.offsetAppbarHeight(activity!!) binding.actionToolbar.offsetAppbarHeight(activity!!)
} }
@ -364,33 +376,48 @@ class LibraryController(
val searchItem = menu.findItem(R.id.action_search) val searchItem = menu.findItem(R.id.action_search)
val searchView = searchItem.actionView as SearchView val searchView = searchItem.actionView as SearchView
searchView.maxWidth = Int.MAX_VALUE searchView.maxWidth = Int.MAX_VALUE
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
searchView.queryTextChanges() if (!query.isNullOrEmpty()) {
// Ignore events if this controller isn't at the top
.filter { router.backstack.lastOrNull()?.controller() == this }
.onEach {
query = it.toString()
searchRelay.call(query)
}
.launchIn(scope)
if (query.isNotEmpty()) {
searchItem.expandActionView() searchItem.expandActionView()
searchView.setQuery(query, true) searchView.setQuery(query, true)
searchView.clearFocus() searchView.clearFocus()
// Manually trigger the search since the binding doesn't trigger for some reason // If we re-enter the controller with a prior search still active
searchRelay.call(query) view?.post {
performSearch()
}
} }
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() }) searchView.queryTextChanges()
.distinctUntilChanged()
.onEach {
query = it.toString()
performSearch()
}
.launchIn(scope)
// Mutate the filter icon because it needs to be tinted and the resource is shared. // Mutate the filter icon because it needs to be tinted and the resource is shared.
menu.findItem(R.id.action_filter).icon.mutate() menu.findItem(R.id.action_filter).icon.mutate()
} }
fun search(query: String) { fun search(query: String?) {
// Delay to let contents load first for searches from manga info
view?.post {
this.query = query this.query = query
performSearch()
}
}
private fun performSearch() {
searchRelay.call(query)
if (!query.isNullOrEmpty()) {
binding.btnGlobalSearch.visible()
binding.btnGlobalSearch.text =
resources?.getString(R.string.action_global_search_query, query)
} else {
binding.btnGlobalSearch.gone()
}
} }
override fun onPrepareOptionsMenu(menu: Menu) { override fun onPrepareOptionsMenu(menu: Menu) {

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -14,7 +15,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/pale_green" android:background="@color/pale_green"
android:visibility="gone"> android:visibility="gone"
tools:visibility="visible">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -26,6 +28,17 @@
</FrameLayout> </FrameLayout>
<Button
android:id="@+id/btn_global_search"
style="@style/Theme.Widget.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:textAllCaps="false"
android:visibility="gone"
tools:text="Search"
tools:visibility="visible" />
<androidx.viewpager.widget.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/library_pager" android:id="@+id/library_pager"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -448,6 +448,7 @@
<string name="invalid_combination">Default can\'t be selected with other categories</string> <string name="invalid_combination">Default can\'t be selected with other categories</string>
<string name="added_to_library">The manga has been added to your library</string> <string name="added_to_library">The manga has been added to your library</string>
<string name="action_global_search_hint">Global search…</string> <string name="action_global_search_hint">Global search…</string>
<string name="action_global_search_query">Search for \"%1$s\" globally</string>
<string name="latest">Latest</string> <string name="latest">Latest</string>
<string name="browse">Browse</string> <string name="browse">Browse</string>
<string name="local_source_help_guide">Local source guide</string> <string name="local_source_help_guide">Local source guide</string>