mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-22 21:01:50 +01:00
Mostly migrate rxbinding to Kotlin Flow version
This commit is contained in:
parent
fae763dbb0
commit
bdf322ceb0
@ -232,10 +232,15 @@ dependencies {
|
|||||||
|
|
||||||
// RxBindings
|
// RxBindings
|
||||||
final rxbindings_version = '1.0.1'
|
final rxbindings_version = '1.0.1'
|
||||||
implementation "com.jakewharton.rxbinding:rxbinding-kotlin:$rxbindings_version"
|
|
||||||
implementation "com.jakewharton.rxbinding:rxbinding-appcompat-v7-kotlin:$rxbindings_version"
|
implementation "com.jakewharton.rxbinding:rxbinding-appcompat-v7-kotlin:$rxbindings_version"
|
||||||
implementation "com.jakewharton.rxbinding:rxbinding-support-v4-kotlin:$rxbindings_version"
|
implementation "com.jakewharton.rxbinding:rxbinding-support-v4-kotlin:$rxbindings_version"
|
||||||
implementation "com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindings_version"
|
|
||||||
|
// FlowBinding
|
||||||
|
final flowbinding_version = '0.10.2'
|
||||||
|
implementation "io.github.reactivecircus.flowbinding:flowbinding-android:$flowbinding_version"
|
||||||
|
implementation "io.github.reactivecircus.flowbinding:flowbinding-appcompat:$flowbinding_version"
|
||||||
|
implementation "io.github.reactivecircus.flowbinding:flowbinding-recyclerview:$flowbinding_version"
|
||||||
|
implementation "io.github.reactivecircus.flowbinding:flowbinding-swiperefreshlayout:$flowbinding_version"
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
testImplementation 'junit:junit:4.13'
|
testImplementation 'junit:junit:4.13'
|
||||||
|
@ -10,7 +10,6 @@ import androidx.appcompat.view.ActionMode
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.jakewharton.rxbinding.view.clicks
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.davidea.flexibleadapter.helpers.UndoHelper
|
import eu.davidea.flexibleadapter.helpers.UndoHelper
|
||||||
@ -19,6 +18,11 @@ import eu.kanade.tachiyomi.data.database.models.Category
|
|||||||
import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding
|
import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.android.view.clicks
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller to manage the categories for the users' library.
|
* Controller to manage the categories for the users' library.
|
||||||
@ -47,6 +51,8 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
*/
|
*/
|
||||||
private var undoHelper: UndoHelper? = null
|
private var undoHelper: UndoHelper? = null
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: CategoriesControllerBinding
|
private lateinit var binding: CategoriesControllerBinding
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,9 +93,11 @@ class CategoryController : NucleusController<CategoryPresenter>(),
|
|||||||
adapter?.isHandleDragEnabled = true
|
adapter?.isHandleDragEnabled = true
|
||||||
adapter?.isPermanentDelete = false
|
adapter?.isPermanentDelete = false
|
||||||
|
|
||||||
binding.fab.clicks().subscribeUntilDestroy {
|
binding.fab.clicks()
|
||||||
CategoryCreateDialog(this@CategoryController).showDialog(router, null)
|
.onEach {
|
||||||
}
|
CategoryCreateDialog(this@CategoryController).showDialog(router, null)
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,8 +12,6 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
|
|||||||
import com.bluelinelabs.conductor.ControllerChangeType
|
import com.bluelinelabs.conductor.ControllerChangeType
|
||||||
import com.bluelinelabs.conductor.RouterTransaction
|
import com.bluelinelabs.conductor.RouterTransaction
|
||||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
|
||||||
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -24,6 +22,13 @@ import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
|||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.appcompat.queryTextChanges
|
||||||
|
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -47,6 +52,8 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
|
|||||||
|
|
||||||
private var query = ""
|
private var query = ""
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: ExtensionControllerBinding
|
private lateinit var binding: ExtensionControllerBinding
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -70,9 +77,9 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
|
|||||||
super.onViewCreated(view)
|
super.onViewCreated(view)
|
||||||
|
|
||||||
binding.extSwipeRefresh.isRefreshing = true
|
binding.extSwipeRefresh.isRefreshing = true
|
||||||
binding.extSwipeRefresh.refreshes().subscribeUntilDestroy {
|
binding.extSwipeRefresh.refreshes()
|
||||||
presenter.findAvailableExtensions()
|
.onEach { presenter.findAvailableExtensions() }
|
||||||
}
|
.launchIn(uiScope)
|
||||||
|
|
||||||
// Initialize adapter, scroll listener and recycler views
|
// Initialize adapter, scroll listener and recycler views
|
||||||
adapter = ExtensionAdapter(this)
|
adapter = ExtensionAdapter(this)
|
||||||
@ -146,11 +153,12 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
searchView.queryTextChanges()
|
searchView.queryTextChanges()
|
||||||
.filter { router.backstack.lastOrNull()?.controller() == this }
|
.filter { router.backstack.lastOrNull()?.controller() == this }
|
||||||
.subscribeUntilDestroy {
|
.onEach {
|
||||||
query = it.toString()
|
query = it.toString()
|
||||||
drawExtensions()
|
drawExtensions()
|
||||||
}
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
// Fixes problem with the overflow icon showing up in lieu of search
|
// Fixes problem with the overflow icon showing up in lieu of search
|
||||||
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
||||||
|
@ -22,7 +22,6 @@ import androidx.preference.PreferenceScreen
|
|||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL
|
import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.jakewharton.rxbinding.view.clicks
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore
|
import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore
|
||||||
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
|
import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
|
||||||
@ -33,6 +32,11 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
|||||||
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
import eu.kanade.tachiyomi.util.preference.preferenceCategory
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.android.view.clicks
|
||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
class ExtensionDetailsController(bundle: Bundle? = null) :
|
class ExtensionDetailsController(bundle: Bundle? = null) :
|
||||||
@ -44,6 +48,8 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
|
|
||||||
private var preferenceScreen: PreferenceScreen? = null
|
private var preferenceScreen: PreferenceScreen? = null
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: ExtensionDetailControllerBinding
|
private lateinit var binding: ExtensionDetailControllerBinding
|
||||||
|
|
||||||
constructor(pkgName: String) : this(Bundle().apply {
|
constructor(pkgName: String) : this(Bundle().apply {
|
||||||
@ -76,9 +82,9 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
binding.extensionLang.text = context.getString(R.string.ext_language_info, LocaleHelper.getDisplayName(extension.lang, context))
|
binding.extensionLang.text = context.getString(R.string.ext_language_info, LocaleHelper.getDisplayName(extension.lang, context))
|
||||||
binding.extensionPkg.text = extension.pkgName
|
binding.extensionPkg.text = extension.pkgName
|
||||||
extension.getApplicationIcon(context)?.let { binding.extensionIcon.setImageDrawable(it) }
|
extension.getApplicationIcon(context)?.let { binding.extensionIcon.setImageDrawable(it) }
|
||||||
binding.extensionUninstallButton.clicks().subscribeUntilDestroy {
|
binding.extensionUninstallButton.clicks()
|
||||||
presenter.uninstallExtension()
|
.onEach { presenter.uninstallExtension() }
|
||||||
}
|
.launchIn(uiScope)
|
||||||
|
|
||||||
if (extension.isObsolete) {
|
if (extension.isObsolete) {
|
||||||
binding.extensionObsolete.visible()
|
binding.extensionObsolete.visible()
|
||||||
|
@ -20,7 +20,6 @@ import com.bluelinelabs.conductor.ControllerChangeType
|
|||||||
import com.f2prateek.rx.preferences.Preference
|
import com.f2prateek.rx.preferences.Preference
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import com.jakewharton.rxbinding.support.v4.view.pageSelections
|
import com.jakewharton.rxbinding.support.v4.view.pageSelections
|
||||||
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
|
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
import com.jakewharton.rxrelay.PublishRelay
|
import com.jakewharton.rxrelay.PublishRelay
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -40,6 +39,12 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
|
|||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import kotlinx.android.synthetic.main.main_activity.tabs
|
import kotlinx.android.synthetic.main.main_activity.tabs
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.appcompat.queryTextChanges
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -123,7 +128,7 @@ class LibraryController(
|
|||||||
|
|
||||||
private var tabsVisibilitySubscription: Subscription? = null
|
private var tabsVisibilitySubscription: Subscription? = null
|
||||||
|
|
||||||
private var searchViewSubscription: Subscription? = null
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: LibraryControllerBinding
|
private lateinit var binding: LibraryControllerBinding
|
||||||
|
|
||||||
@ -335,14 +340,14 @@ class LibraryController(
|
|||||||
// 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()
|
||||||
|
|
||||||
searchViewSubscription?.unsubscribe()
|
searchView.queryTextChanges()
|
||||||
searchViewSubscription = searchView.queryTextChanges()
|
// Ignore events if this controller isn't at the top
|
||||||
// Ignore events if this controller isn't at the top
|
.filter { router.backstack.lastOrNull()?.controller() == this }
|
||||||
.filter { router.backstack.lastOrNull()?.controller() == this }
|
.onEach {
|
||||||
.subscribeUntilDestroy {
|
query = it.toString()
|
||||||
query = it.toString()
|
searchRelay.call(query)
|
||||||
searchRelay.call(query)
|
}
|
||||||
}
|
.launchIn(uiScope)
|
||||||
|
|
||||||
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,6 @@ import androidx.core.graphics.drawable.DrawableCompat
|
|||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
|
||||||
import com.jakewharton.rxbinding.view.clicks
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -36,6 +34,12 @@ import eu.kanade.tachiyomi.util.view.gone
|
|||||||
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
||||||
import eu.kanade.tachiyomi.util.view.snack
|
import eu.kanade.tachiyomi.util.view.snack
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.android.view.clicks
|
||||||
|
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class ChaptersController : NucleusController<ChaptersPresenter>(),
|
class ChaptersController : NucleusController<ChaptersPresenter>(),
|
||||||
@ -62,6 +66,8 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
|
|||||||
|
|
||||||
private var lastClickPosition = -1
|
private var lastClickPosition = -1
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: ChaptersControllerBinding
|
private lateinit var binding: ChaptersControllerBinding
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -91,27 +97,32 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
|
|||||||
binding.recycler.setHasFixedSize(true)
|
binding.recycler.setHasFixedSize(true)
|
||||||
adapter?.fastScroller = binding.fastScroller
|
adapter?.fastScroller = binding.fastScroller
|
||||||
|
|
||||||
binding.swipeRefresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
|
binding.swipeRefresh.refreshes()
|
||||||
|
.onEach { fetchChaptersFromSource() }
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.fab.clicks().subscribeUntilDestroy {
|
binding.fab.clicks()
|
||||||
val item = presenter.getNextUnreadChapter()
|
.onEach {
|
||||||
if (item != null) {
|
val item = presenter.getNextUnreadChapter()
|
||||||
// Create animation listener
|
if (item != null) {
|
||||||
val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
|
// Create animation listener
|
||||||
override fun onAnimationStart(animation: Animator?) {
|
val revealAnimationListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
|
||||||
openChapter(item.chapter, true)
|
override fun onAnimationStart(animation: Animator?) {
|
||||||
|
openChapter(item.chapter, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Get coordinates and start animation
|
// Get coordinates and start animation
|
||||||
val coordinates = binding.fab.getCoordinates()
|
val coordinates = binding.fab.getCoordinates()
|
||||||
if (!binding.revealView.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
|
if (!binding.revealView.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
|
||||||
openChapter(item.chapter)
|
openChapter(item.chapter)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view.context.toast(R.string.no_next_chapter)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
view.context.toast(R.string.no_next_chapter)
|
|
||||||
}
|
}
|
||||||
}
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.fab.shrinkOnScroll(binding.recycler)
|
binding.fab.shrinkOnScroll(binding.recycler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,6 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
|||||||
import com.bumptech.glide.request.target.CustomTarget
|
import com.bumptech.glide.request.target.CustomTarget
|
||||||
import com.bumptech.glide.request.transition.Transition
|
import com.bumptech.glide.request.transition.Transition
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
|
||||||
import com.jakewharton.rxbinding.view.clicks
|
|
||||||
import com.jakewharton.rxbinding.view.longClicks
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
@ -56,6 +53,13 @@ import eu.kanade.tachiyomi.util.system.toast
|
|||||||
import eu.kanade.tachiyomi.util.view.snack
|
import eu.kanade.tachiyomi.util.view.snack
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
import jp.wasabeef.glide.transformations.CropSquareTransformation
|
import jp.wasabeef.glide.transformations.CropSquareTransformation
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.android.view.clicks
|
||||||
|
import reactivecircus.flowbinding.android.view.longClicks
|
||||||
|
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
@ -70,6 +74,8 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
|
|||||||
|
|
||||||
private val preferences: PreferencesHelper by injectLazy()
|
private val preferences: PreferencesHelper by injectLazy()
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: MangaInfoControllerBinding
|
private lateinit var binding: MangaInfoControllerBinding
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -91,53 +97,79 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
|
|||||||
super.onViewCreated(view)
|
super.onViewCreated(view)
|
||||||
|
|
||||||
// Set onclickListener to toggle favorite when favorite button clicked.
|
// Set onclickListener to toggle favorite when favorite button clicked.
|
||||||
binding.btnFavorite.clicks().subscribeUntilDestroy { onFavoriteClick() }
|
binding.btnFavorite.clicks()
|
||||||
|
.onEach { onFavoriteClick() }
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
// Set onLongClickListener to manage categories when favorite button is clicked.
|
// Set onLongClickListener to manage categories when favorite button is clicked.
|
||||||
binding.btnFavorite.longClicks().subscribeUntilDestroy { onFavoriteLongClick() }
|
binding.btnFavorite.longClicks()
|
||||||
|
.onEach { onFavoriteLongClick() }
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
if (presenter.source is HttpSource) {
|
if (presenter.source is HttpSource) {
|
||||||
binding.btnWebview.visible()
|
binding.btnWebview.visible()
|
||||||
binding.btnShare.visible()
|
binding.btnShare.visible()
|
||||||
|
|
||||||
binding.btnWebview.clicks().subscribeUntilDestroy { openInWebView() }
|
binding.btnWebview.clicks()
|
||||||
binding.btnShare.clicks().subscribeUntilDestroy { shareManga() }
|
.onEach { openInWebView() }
|
||||||
|
.launchIn(uiScope)
|
||||||
|
binding.btnShare.clicks()
|
||||||
|
.onEach { shareManga() }
|
||||||
|
.launchIn(uiScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set SwipeRefresh to refresh manga data.
|
// Set SwipeRefresh to refresh manga data.
|
||||||
binding.swipeRefresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() }
|
binding.swipeRefresh.refreshes()
|
||||||
|
.onEach { fetchMangaFromSource() }
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaFullTitle.longClicks().subscribeUntilDestroy {
|
binding.mangaFullTitle.longClicks()
|
||||||
copyToClipboard(view.context.getString(R.string.title), binding.mangaFullTitle.text.toString())
|
.onEach {
|
||||||
}
|
copyToClipboard(view.context.getString(R.string.title), binding.mangaFullTitle.text.toString())
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaFullTitle.clicks().subscribeUntilDestroy {
|
binding.mangaFullTitle.clicks()
|
||||||
performGlobalSearch(binding.mangaFullTitle.text.toString())
|
.onEach {
|
||||||
}
|
performGlobalSearch(binding.mangaFullTitle.text.toString())
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaArtist.longClicks().subscribeUntilDestroy {
|
binding.mangaArtist.longClicks()
|
||||||
copyToClipboard(binding.mangaArtistLabel.text.toString(), binding.mangaArtist.text.toString())
|
.onEach {
|
||||||
}
|
copyToClipboard(binding.mangaArtistLabel.text.toString(), binding.mangaArtist.text.toString())
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaArtist.clicks().subscribeUntilDestroy {
|
binding.mangaArtist.clicks()
|
||||||
performGlobalSearch(binding.mangaArtist.text.toString())
|
.onEach {
|
||||||
}
|
performGlobalSearch(binding.mangaArtist.text.toString())
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaAuthor.longClicks().subscribeUntilDestroy {
|
binding.mangaAuthor.longClicks()
|
||||||
copyToClipboard(binding.mangaAuthor.text.toString(), binding.mangaAuthor.text.toString())
|
.onEach {
|
||||||
}
|
copyToClipboard(binding.mangaAuthor.text.toString(), binding.mangaAuthor.text.toString())
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaAuthor.clicks().subscribeUntilDestroy {
|
binding.mangaAuthor.clicks()
|
||||||
performGlobalSearch(binding.mangaAuthor.text.toString())
|
.onEach {
|
||||||
}
|
performGlobalSearch(binding.mangaAuthor.text.toString())
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaSummary.longClicks().subscribeUntilDestroy {
|
binding.mangaSummary.longClicks()
|
||||||
copyToClipboard(view.context.getString(R.string.description), binding.mangaSummary.text.toString())
|
.onEach {
|
||||||
}
|
copyToClipboard(view.context.getString(R.string.description), binding.mangaSummary.text.toString())
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.mangaCover.longClicks().subscribeUntilDestroy {
|
binding.mangaCover.longClicks()
|
||||||
copyToClipboard(view.context.getString(R.string.title), presenter.manga.title)
|
.onEach {
|
||||||
}
|
copyToClipboard(view.context.getString(R.string.title), presenter.manga.title)
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
@ -6,13 +6,17 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.databinding.TrackControllerBinding
|
import eu.kanade.tachiyomi.databinding.TrackControllerBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class TrackController : NucleusController<TrackPresenter>(),
|
class TrackController : NucleusController<TrackPresenter>(),
|
||||||
@ -23,6 +27,8 @@ class TrackController : NucleusController<TrackPresenter>(),
|
|||||||
|
|
||||||
private var adapter: TrackAdapter? = null
|
private var adapter: TrackAdapter? = null
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: TrackControllerBinding
|
private lateinit var binding: TrackControllerBinding
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -47,7 +53,9 @@ class TrackController : NucleusController<TrackPresenter>(),
|
|||||||
binding.trackRecycler.layoutManager = LinearLayoutManager(view.context)
|
binding.trackRecycler.layoutManager = LinearLayoutManager(view.context)
|
||||||
binding.trackRecycler.adapter = adapter
|
binding.trackRecycler.adapter = adapter
|
||||||
binding.swipeRefresh.isEnabled = false
|
binding.swipeRefresh.isEnabled = false
|
||||||
binding.swipeRefresh.refreshes().subscribeUntilDestroy { presenter.refresh() }
|
binding.swipeRefresh.refreshes()
|
||||||
|
.onEach { presenter.refresh() }
|
||||||
|
.launchIn(uiScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
|
@ -4,24 +4,27 @@ import android.app.Dialog
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.jakewharton.rxbinding.widget.itemClicks
|
|
||||||
import com.jakewharton.rxbinding.widget.textChanges
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.util.lang.plusAssign
|
|
||||||
import eu.kanade.tachiyomi.util.view.invisible
|
import eu.kanade.tachiyomi.util.view.invisible
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlinx.android.synthetic.main.track_search_dialog.view.progress
|
import kotlinx.android.synthetic.main.track_search_dialog.view.progress
|
||||||
import kotlinx.android.synthetic.main.track_search_dialog.view.track_search
|
import kotlinx.android.synthetic.main.track_search_dialog.view.track_search
|
||||||
import kotlinx.android.synthetic.main.track_search_dialog.view.track_search_list
|
import kotlinx.android.synthetic.main.track_search_dialog.view.track_search_list
|
||||||
import rx.Subscription
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import rx.subscriptions.CompositeSubscription
|
import kotlinx.coroutines.flow.debounce
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.android.widget.itemClicks
|
||||||
|
import reactivecircus.flowbinding.android.widget.textChanges
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -35,13 +38,11 @@ class TrackSearchDialog : DialogController {
|
|||||||
|
|
||||||
private val service: TrackService
|
private val service: TrackService
|
||||||
|
|
||||||
private var subscriptions = CompositeSubscription()
|
|
||||||
|
|
||||||
private var searchTextSubscription: Subscription? = null
|
|
||||||
|
|
||||||
private val trackController
|
private val trackController
|
||||||
get() = targetController as TrackController
|
get() = targetController as TrackController
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
constructor(target: TrackController, service: TrackService) : super(Bundle().apply {
|
constructor(target: TrackController, service: TrackService) : super(Bundle().apply {
|
||||||
putInt(KEY_SERVICE, service.id)
|
putInt(KEY_SERVICE, service.id)
|
||||||
}) {
|
}) {
|
||||||
@ -64,10 +65,6 @@ class TrackSearchDialog : DialogController {
|
|||||||
.onNeutral { _, _ -> onRemoveButtonClick() }
|
.onNeutral { _, _ -> onRemoveButtonClick() }
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
if (subscriptions.isUnsubscribed) {
|
|
||||||
subscriptions = CompositeSubscription()
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogView = dialog.view
|
dialogView = dialog.view
|
||||||
onViewCreated(dialog.view, savedViewState)
|
onViewCreated(dialog.view, savedViewState)
|
||||||
|
|
||||||
@ -83,9 +80,11 @@ class TrackSearchDialog : DialogController {
|
|||||||
// Set listeners
|
// Set listeners
|
||||||
selectedItem = null
|
selectedItem = null
|
||||||
|
|
||||||
subscriptions += view.track_search_list.itemClicks().subscribe { position ->
|
view.track_search_list.itemClicks()
|
||||||
selectedItem = adapter.getItem(position)
|
.onEach { position ->
|
||||||
}
|
selectedItem = adapter.getItem(position)
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
// Do an initial search based on the manga's title
|
// Do an initial search based on the manga's title
|
||||||
if (savedState == null) {
|
if (savedState == null) {
|
||||||
@ -97,24 +96,18 @@ class TrackSearchDialog : DialogController {
|
|||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
super.onDestroyView(view)
|
super.onDestroyView(view)
|
||||||
subscriptions.unsubscribe()
|
|
||||||
dialogView = null
|
dialogView = null
|
||||||
adapter = null
|
adapter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAttach(view: View) {
|
override fun onAttach(view: View) {
|
||||||
super.onAttach(view)
|
super.onAttach(view)
|
||||||
searchTextSubscription = dialogView!!.track_search.textChanges()
|
dialogView!!.track_search.textChanges(false)
|
||||||
.skip(1)
|
.debounce(TimeUnit.SECONDS.toMillis(1))
|
||||||
.debounce(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
|
|
||||||
.map { it.toString() }
|
.map { it.toString() }
|
||||||
.filter(String::isNotBlank)
|
.filter { it.isNotBlank() }
|
||||||
.subscribe { search(it) }
|
.onEach { search(it) }
|
||||||
}
|
.launchIn(uiScope)
|
||||||
|
|
||||||
override fun onDetach(view: View) {
|
|
||||||
super.onDetach(view)
|
|
||||||
searchTextSubscription?.unsubscribe()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun search(query: String) {
|
private fun search(query: String) {
|
||||||
|
@ -10,8 +10,6 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
|
||||||
import com.jakewharton.rxbinding.support.v7.widget.scrollStateChanges
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
@ -29,6 +27,12 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
|
|||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.recyclerview.scrollStateChanges
|
||||||
|
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +61,8 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
var adapter: UpdatesAdapter? = null
|
var adapter: UpdatesAdapter? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: UpdatesControllerBinding
|
private lateinit var binding: UpdatesControllerBinding
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -92,19 +98,23 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
|
|||||||
adapter = UpdatesAdapter(this@UpdatesController)
|
adapter = UpdatesAdapter(this@UpdatesController)
|
||||||
binding.recycler.adapter = adapter
|
binding.recycler.adapter = adapter
|
||||||
|
|
||||||
binding.recycler.scrollStateChanges().subscribeUntilDestroy {
|
binding.recycler.scrollStateChanges()
|
||||||
// Disable swipe refresh when view is not at the top
|
.onEach {
|
||||||
val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
|
// Disable swipe refresh when view is not at the top
|
||||||
binding.swipeRefresh.isEnabled = firstPos <= 0
|
val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
|
||||||
}
|
binding.swipeRefresh.isEnabled = firstPos <= 0
|
||||||
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
|
|
||||||
binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
|
binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
|
||||||
binding.swipeRefresh.refreshes().subscribeUntilDestroy {
|
binding.swipeRefresh.refreshes()
|
||||||
updateLibrary()
|
.onEach {
|
||||||
|
updateLibrary()
|
||||||
|
|
||||||
// It can be a very long operation, so we disable swipe refresh and show a toast.
|
// It can be a very long operation, so we disable swipe refresh and show a toast.
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
|
@ -14,7 +14,6 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
|
|||||||
import com.bluelinelabs.conductor.ControllerChangeType
|
import com.bluelinelabs.conductor.ControllerChangeType
|
||||||
import com.bluelinelabs.conductor.RouterTransaction
|
import com.bluelinelabs.conductor.RouterTransaction
|
||||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||||
import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -31,6 +30,13 @@ import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController
|
|||||||
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
|
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
|
||||||
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
|
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
|
||||||
import eu.kanade.tachiyomi.ui.source.latest.LatestUpdatesController
|
import eu.kanade.tachiyomi.ui.source.latest.LatestUpdatesController
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.appcompat.QueryTextEvent
|
||||||
|
import reactivecircus.flowbinding.appcompat.queryTextEvents
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -54,6 +60,8 @@ class SourceController : NucleusController<SourcePresenter>(),
|
|||||||
*/
|
*/
|
||||||
private var adapter: SourceAdapter? = null
|
private var adapter: SourceAdapter? = null
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: SourceMainControllerBinding
|
private lateinit var binding: SourceMainControllerBinding
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -192,9 +200,10 @@ class SourceController : NucleusController<SourcePresenter>(),
|
|||||||
searchView.queryHint = applicationContext?.getString(R.string.action_global_search_hint)
|
searchView.queryHint = applicationContext?.getString(R.string.action_global_search_hint)
|
||||||
|
|
||||||
// Create query listener which opens the global search view.
|
// Create query listener which opens the global search view.
|
||||||
searchView.queryTextChangeEvents()
|
searchView.queryTextEvents()
|
||||||
.filter { it.isSubmitted }
|
.filter { it is QueryTextEvent.QuerySubmitted }
|
||||||
.subscribeUntilDestroy { performGlobalSearch(it.queryText().toString()) }
|
.onEach { performGlobalSearch(it.queryText.toString()) }
|
||||||
|
.launchIn(uiScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun performGlobalSearch(query: String) {
|
fun performGlobalSearch(query: String) {
|
||||||
|
@ -9,7 +9,6 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.databinding.GlobalSearchControllerBinding
|
import eu.kanade.tachiyomi.databinding.GlobalSearchControllerBinding
|
||||||
@ -17,6 +16,13 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import reactivecircus.flowbinding.appcompat.QueryTextEvent
|
||||||
|
import reactivecircus.flowbinding.appcompat.queryTextEvents
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This controller shows and manages the different search result in global search.
|
* This controller shows and manages the different search result in global search.
|
||||||
@ -34,6 +40,8 @@ open class GlobalSearchController(
|
|||||||
*/
|
*/
|
||||||
protected var adapter: GlobalSearchAdapter? = null
|
protected var adapter: GlobalSearchAdapter? = null
|
||||||
|
|
||||||
|
private val uiScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
private lateinit var binding: GlobalSearchControllerBinding
|
private lateinit var binding: GlobalSearchControllerBinding
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,13 +127,14 @@ open class GlobalSearchController(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
searchView.queryTextChangeEvents()
|
searchView.queryTextEvents()
|
||||||
.filter { it.isSubmitted }
|
.filter { it is QueryTextEvent.QuerySubmitted }
|
||||||
.subscribeUntilDestroy {
|
.onEach {
|
||||||
presenter.search(it.queryText().toString())
|
presenter.search(it.queryText.toString())
|
||||||
searchItem.collapseActionView()
|
searchItem.collapseActionView()
|
||||||
setTitle() // Update toolbar title
|
setTitle() // Update toolbar title
|
||||||
}
|
}
|
||||||
|
.launchIn(uiScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user