|
@@ -10,7 +10,6 @@ import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.view.ViewGroup
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.appcompat.view.ActionMode
|
|
import androidx.appcompat.view.ActionMode
|
|
-import androidx.appcompat.widget.SearchView
|
|
|
|
import androidx.core.graphics.drawable.DrawableCompat
|
|
import androidx.core.graphics.drawable.DrawableCompat
|
|
import androidx.core.view.isVisible
|
|
import androidx.core.view.isVisible
|
|
import com.bluelinelabs.conductor.ControllerChangeHandler
|
|
import com.bluelinelabs.conductor.ControllerChangeHandler
|
|
@@ -27,21 +26,16 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
|
import eu.kanade.tachiyomi.databinding.LibraryControllerBinding
|
|
import eu.kanade.tachiyomi.databinding.LibraryControllerBinding
|
|
import eu.kanade.tachiyomi.source.LocalSource
|
|
import eu.kanade.tachiyomi.source.LocalSource
|
|
-import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
|
|
|
-import eu.kanade.tachiyomi.ui.base.controller.RootController
|
|
|
|
-import eu.kanade.tachiyomi.ui.base.controller.TabbedController
|
|
|
|
-import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
|
|
|
|
|
+import eu.kanade.tachiyomi.ui.base.controller.*
|
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
|
|
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.manga.MangaController
|
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
|
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 kotlinx.coroutines.flow.drop
|
|
import kotlinx.coroutines.flow.drop
|
|
-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.android.view.clicks
|
|
-import reactivecircus.flowbinding.appcompat.queryTextChanges
|
|
|
|
import reactivecircus.flowbinding.viewpager.pageSelections
|
|
import reactivecircus.flowbinding.viewpager.pageSelections
|
|
import rx.Subscription
|
|
import rx.Subscription
|
|
import uy.kohesive.injekt.Injekt
|
|
import uy.kohesive.injekt.Injekt
|
|
@@ -50,7 +44,7 @@ import uy.kohesive.injekt.api.get
|
|
class LibraryController(
|
|
class LibraryController(
|
|
bundle: Bundle? = null,
|
|
bundle: Bundle? = null,
|
|
private val preferences: PreferencesHelper = Injekt.get()
|
|
private val preferences: PreferencesHelper = Injekt.get()
|
|
-) : NucleusController<LibraryControllerBinding, LibraryPresenter>(bundle),
|
|
|
|
|
|
+) : SearchableNucleusController<LibraryControllerBinding, LibraryPresenter>(bundle),
|
|
RootController,
|
|
RootController,
|
|
TabbedController,
|
|
TabbedController,
|
|
ActionMode.Callback,
|
|
ActionMode.Callback,
|
|
@@ -67,11 +61,6 @@ class LibraryController(
|
|
*/
|
|
*/
|
|
private var actionMode: ActionMode? = null
|
|
private var actionMode: ActionMode? = null
|
|
|
|
|
|
- /**
|
|
|
|
- * Library search query.
|
|
|
|
- */
|
|
|
|
- private var query: String = ""
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Currently selected mangas.
|
|
* Currently selected mangas.
|
|
*/
|
|
*/
|
|
@@ -212,7 +201,7 @@ class LibraryController(
|
|
binding.btnGlobalSearch.clicks()
|
|
binding.btnGlobalSearch.clicks()
|
|
.onEach {
|
|
.onEach {
|
|
router.pushController(
|
|
router.pushController(
|
|
- GlobalSearchController(query).withFadeTransaction()
|
|
|
|
|
|
+ GlobalSearchController(presenter.query).withFadeTransaction()
|
|
)
|
|
)
|
|
}
|
|
}
|
|
.launchIn(viewScope)
|
|
.launchIn(viewScope)
|
|
@@ -384,52 +373,21 @@ class LibraryController(
|
|
}
|
|
}
|
|
|
|
|
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
|
- inflater.inflate(R.menu.library, menu)
|
|
|
|
-
|
|
|
|
- val searchItem = menu.findItem(R.id.action_search)
|
|
|
|
- val searchView = searchItem.actionView as SearchView
|
|
|
|
- searchView.maxWidth = Int.MAX_VALUE
|
|
|
|
- searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
|
|
|
-
|
|
|
|
- if (query.isNotEmpty()) {
|
|
|
|
- searchItem.expandActionView()
|
|
|
|
- searchView.setQuery(query, true)
|
|
|
|
- searchView.clearFocus()
|
|
|
|
-
|
|
|
|
- performSearch()
|
|
|
|
-
|
|
|
|
- // Workaround for weird behavior where searchview gets empty text change despite
|
|
|
|
- // query being set already
|
|
|
|
- searchView.postDelayed({ initSearchHandler(searchView) }, 500)
|
|
|
|
- } else {
|
|
|
|
- initSearchHandler(searchView)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ createOptionsMenu(menu, inflater, R.menu.library, R.id.action_search)
|
|
// 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) {
|
|
- this.query = query
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private fun initSearchHandler(searchView: SearchView) {
|
|
|
|
- searchView.queryTextChanges()
|
|
|
|
- // Ignore events if this controller isn't at the top to avoid query being reset
|
|
|
|
- .filter { router.backstack.lastOrNull()?.controller() == this }
|
|
|
|
- .onEach {
|
|
|
|
- query = it.toString()
|
|
|
|
- performSearch()
|
|
|
|
- }
|
|
|
|
- .launchIn(viewScope)
|
|
|
|
|
|
+ presenter.query = query
|
|
}
|
|
}
|
|
|
|
|
|
private fun performSearch() {
|
|
private fun performSearch() {
|
|
- searchRelay.call(query)
|
|
|
|
- if (query.isNotEmpty()) {
|
|
|
|
|
|
+ searchRelay.call(presenter.query)
|
|
|
|
+ if (presenter.query.isNotEmpty()) {
|
|
binding.btnGlobalSearch.isVisible = true
|
|
binding.btnGlobalSearch.isVisible = true
|
|
binding.btnGlobalSearch.text =
|
|
binding.btnGlobalSearch.text =
|
|
- resources?.getString(R.string.action_global_search_query, query)
|
|
|
|
|
|
+ resources?.getString(R.string.action_global_search_query, presenter.query)
|
|
} else {
|
|
} else {
|
|
binding.btnGlobalSearch.isVisible = false
|
|
binding.btnGlobalSearch.isVisible = false
|
|
}
|
|
}
|
|
@@ -611,4 +569,12 @@ class LibraryController(
|
|
selectInverseRelay.call(it)
|
|
selectInverseRelay.call(it)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ override fun onSearchViewQueryTextChange(newText: String?) {
|
|
|
|
+ // Ignore events if this controller isn't at the top to avoid query being reset
|
|
|
|
+ if (router.backstack.lastOrNull()?.controller() == this) {
|
|
|
|
+ presenter.query = newText ?: ""
|
|
|
|
+ performSearch()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|