Minor fixes regarding leaks
(cherry picked from commit 36f81b4a623ede11f10049f5869de5b6efa7803a) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt # app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
This commit is contained in:
parent
1b41546bc9
commit
c8dd2190ba
@ -12,6 +12,9 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
|
|||||||
import com.bluelinelabs.conductor.ControllerChangeType
|
import com.bluelinelabs.conductor.ControllerChangeType
|
||||||
import com.bluelinelabs.conductor.RestoreViewOnCreateController
|
import com.bluelinelabs.conductor.RestoreViewOnCreateController
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
||||||
@ -20,6 +23,8 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
|||||||
|
|
||||||
lateinit var binding: VB
|
lateinit var binding: VB
|
||||||
|
|
||||||
|
lateinit var viewScope: CoroutineScope
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addLifecycleListener(
|
addLifecycleListener(
|
||||||
object : LifecycleListener() {
|
object : LifecycleListener() {
|
||||||
@ -28,6 +33,7 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun preCreateView(controller: Controller) {
|
override fun preCreateView(controller: Controller) {
|
||||||
|
viewScope = MainScope()
|
||||||
Timber.d("Create view for ${controller.instance()}")
|
Timber.d("Create view for ${controller.instance()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +46,7 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun preDestroyView(controller: Controller, view: View) {
|
override fun preDestroyView(controller: Controller, view: View) {
|
||||||
|
viewScope.cancel()
|
||||||
Timber.d("Destroy view for ${controller.instance()}")
|
Timber.d("Destroy view for ${controller.instance()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,6 @@ import android.os.Bundle
|
|||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.NucleusConductorDelegate
|
import eu.kanade.tachiyomi.ui.base.presenter.NucleusConductorDelegate
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.NucleusConductorLifecycleListener
|
import eu.kanade.tachiyomi.ui.base.presenter.NucleusConductorLifecycleListener
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import nucleus.factory.PresenterFactory
|
import nucleus.factory.PresenterFactory
|
||||||
import nucleus.presenter.Presenter
|
import nucleus.presenter.Presenter
|
||||||
|
|
||||||
@ -17,8 +14,6 @@ abstract class NucleusController<VB : ViewBinding, P : Presenter<*>>(val bundle:
|
|||||||
|
|
||||||
private val delegate = NucleusConductorDelegate(this)
|
private val delegate = NucleusConductorDelegate(this)
|
||||||
|
|
||||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
|
||||||
|
|
||||||
val presenter: P
|
val presenter: P
|
||||||
get() = delegate.presenter!!
|
get() = delegate.presenter!!
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ open class ExtensionController :
|
|||||||
binding.swipeRefresh.isRefreshing = true
|
binding.swipeRefresh.isRefreshing = true
|
||||||
binding.swipeRefresh.refreshes()
|
binding.swipeRefresh.refreshes()
|
||||||
.onEach { presenter.findAvailableExtensions() }
|
.onEach { presenter.findAvailableExtensions() }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
// Initialize adapter, scroll listener and recycler views
|
// Initialize adapter, scroll listener and recycler views
|
||||||
adapter = ExtensionAdapter(this)
|
adapter = ExtensionAdapter(this)
|
||||||
@ -142,7 +142,7 @@ open class ExtensionController :
|
|||||||
query = it.toString()
|
query = it.toString()
|
||||||
drawExtensions()
|
drawExtensions()
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(view: View, position: Int): Boolean {
|
override fun onItemClick(view: View, position: Int): Boolean {
|
||||||
|
@ -134,7 +134,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
|||||||
isChecked = enabled
|
isChecked = enabled
|
||||||
sourcePrefs.forEach { pref -> pref.isVisible = enabled }
|
sourcePrefs.forEach { pref -> pref.isVisible = enabled }
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Source enable/disable
|
// Source enable/disable
|
||||||
|
@ -126,7 +126,7 @@ open class LatestController :
|
|||||||
|
|
||||||
presenter.preferences.latestTabSources()
|
presenter.preferences.latestTabSources()
|
||||||
.asImmediateFlow { presenter.getLatest() }
|
.asImmediateFlow { presenter.getLatest() }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
|
@ -83,8 +83,7 @@ class PreMigrationController(bundle: Bundle? = null) :
|
|||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.setText(R.string.action_migrate)
|
fab.setText(R.string.action_migrate)
|
||||||
fab.setIconResource(R.drawable.ic_arrow_forward_24dp)
|
fab.setIconResource(R.drawable.ic_arrow_forward_24dp)
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
|
||||||
if (dialog?.isShowing != true) {
|
if (dialog?.isShowing != true) {
|
||||||
dialog = MigrationBottomSheetDialog(activity!!, R.style.SheetDialog, this)
|
dialog = MigrationBottomSheetDialog(activity!!, R.style.SheetDialog, this)
|
||||||
dialog?.show()
|
dialog?.show()
|
||||||
@ -98,10 +97,10 @@ class PreMigrationController(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,6 @@ class SearchController(
|
|||||||
searchItem.collapseActionView()
|
searchItem.collapseActionView()
|
||||||
setTitle() // Update toolbar title
|
setTitle() // Update toolbar title
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ class SourceController(bundle: Bundle? = null) :
|
|||||||
searchView.queryTextEvents()
|
searchView.queryTextEvents()
|
||||||
.filterIsInstance<QueryTextEvent.QuerySubmitted>()
|
.filterIsInstance<QueryTextEvent.QuerySubmitted>()
|
||||||
.onEach { performGlobalSearch(it.queryText.toString()) }
|
.onEach { performGlobalSearch(it.queryText.toString()) }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun performGlobalSearch(query: String) {
|
private fun performGlobalSearch(query: String) {
|
||||||
|
@ -329,6 +329,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { recycler?.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { recycler?.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
@ -366,7 +367,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||||||
.drop(1)
|
.drop(1)
|
||||||
// Set again the adapter to recalculate the covers height
|
// Set again the adapter to recalculate the covers height
|
||||||
.onEach { adapter = this@BrowseSourceController.adapter }
|
.onEach { adapter = this@BrowseSourceController.adapter }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
(layoutManager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
(layoutManager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||||
override fun getSpanSize(position: Int): Int {
|
override fun getSpanSize(position: Int): Int {
|
||||||
@ -417,7 +418,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||||||
.filter { router.backstack.lastOrNull()?.controller() == this@BrowseSourceController }
|
.filter { router.backstack.lastOrNull()?.controller() == this@BrowseSourceController }
|
||||||
.filterIsInstance<QueryTextEvent.QuerySubmitted>()
|
.filterIsInstance<QueryTextEvent.QuerySubmitted>()
|
||||||
.onEach { searchWithQuery(it.queryText.toString()) }
|
.onEach { searchWithQuery(it.queryText.toString()) }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
searchItem.fixExpand(
|
searchItem.fixExpand(
|
||||||
onExpand = { invalidateMenuOnExpand() },
|
onExpand = { invalidateMenuOnExpand() },
|
||||||
|
@ -129,7 +129,7 @@ open class GlobalSearchController(
|
|||||||
searchItem.collapseActionView()
|
searchItem.collapseActionView()
|
||||||
setTitle() // Update toolbar title
|
setTitle() // Update toolbar title
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,7 +159,7 @@ open class IndexController :
|
|||||||
onBrowseClick(presenter.query.nullIfBlank())
|
onBrowseClick(presenter.query.nullIfBlank())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
searchItem.fixExpand(
|
searchItem.fixExpand(
|
||||||
onExpand = { invalidateMenuOnExpand() }
|
onExpand = { invalidateMenuOnExpand() }
|
||||||
@ -247,7 +247,7 @@ open class IndexController :
|
|||||||
|
|
||||||
actionFab?.clicks()
|
actionFab?.clicks()
|
||||||
?.onEach { filterSheet?.show() }
|
?.onEach { filterSheet?.show() }
|
||||||
?.launchIn(scope)
|
?.launchIn(viewScope)
|
||||||
|
|
||||||
actionFab?.isVisible = true
|
actionFab?.isVisible = true
|
||||||
}
|
}
|
||||||
@ -263,6 +263,7 @@ open class IndexController :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,6 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
|||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
||||||
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.
|
||||||
@ -103,14 +100,13 @@ class CategoryController :
|
|||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.setText(R.string.action_add)
|
fab.setText(R.string.action_add)
|
||||||
fab.setIconResource(R.drawable.ic_add_24dp)
|
fab.setIconResource(R.drawable.ic_add_24dp)
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
|
||||||
CategoryCreateDialog(this@CategoryController).showDialog(router, null)
|
CategoryCreateDialog(this@CategoryController).showDialog(router, null)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -102,14 +102,13 @@ class BiometricTimesController :
|
|||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.setText(R.string.action_add)
|
fab.setText(R.string.action_add)
|
||||||
fab.setIconResource(R.drawable.ic_add_24dp)
|
fab.setIconResource(R.drawable.ic_add_24dp)
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
|
||||||
BiometricTimesCreateDialog(this@BiometricTimesController).showDialog(router, null)
|
BiometricTimesCreateDialog(this@BiometricTimesController).showDialog(router, null)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,7 @@ class SortTagController :
|
|||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.setText(R.string.action_add)
|
fab.setText(R.string.action_add)
|
||||||
fab.setIconResource(R.drawable.ic_add_24dp)
|
fab.setIconResource(R.drawable.ic_add_24dp)
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
|
||||||
if (!shownHelpDialog) {
|
if (!shownHelpDialog) {
|
||||||
shownHelpDialog = true
|
shownHelpDialog = true
|
||||||
helpDialog(true)
|
helpDialog(true)
|
||||||
@ -118,10 +117,10 @@ class SortTagController :
|
|||||||
SortTagCreateDialog(this@SortTagController).showDialog(router, null)
|
SortTagCreateDialog(this@SortTagController).showDialog(router, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -99,14 +99,13 @@ class RepoController :
|
|||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.setText(R.string.action_add)
|
fab.setText(R.string.action_add)
|
||||||
fab.setIconResource(R.drawable.ic_add_24dp)
|
fab.setIconResource(R.drawable.ic_add_24dp)
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
|
||||||
RepoCreateDialog(this@RepoController).showDialog(router, null)
|
RepoCreateDialog(this@RepoController).showDialog(router, null)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -100,14 +100,13 @@ class SourceCategoryController :
|
|||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.setText(R.string.action_add)
|
fab.setText(R.string.action_add)
|
||||||
fab.setIconResource(R.drawable.ic_add_24dp)
|
fab.setIconResource(R.drawable.ic_add_24dp)
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
|
||||||
SourceCategoryCreateDialog(this@SourceCategoryController).showDialog(router, null)
|
SourceCategoryCreateDialog(this@SourceCategoryController).showDialog(router, null)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,6 @@ import eu.kanade.tachiyomi.source.model.Page
|
|||||||
import eu.kanade.tachiyomi.ui.base.controller.FabController
|
import eu.kanade.tachiyomi.ui.base.controller.FabController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import reactivecircus.flowbinding.android.view.clicks
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
@ -104,9 +101,8 @@ class DownloadController :
|
|||||||
|
|
||||||
override fun configureFab(fab: ExtendedFloatingActionButton) {
|
override fun configureFab(fab: ExtendedFloatingActionButton) {
|
||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
val context = applicationContext ?: return@setOnClickListener
|
||||||
val context = applicationContext ?: return@onEach
|
|
||||||
|
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
DownloadService.stop(context)
|
DownloadService.stop(context)
|
||||||
@ -117,10 +113,10 @@ class DownloadController :
|
|||||||
|
|
||||||
setInformationView()
|
setInformationView()
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ class LibraryComfortableGridHolder(
|
|||||||
.onEach {
|
.onEach {
|
||||||
playButtonClicked()
|
playButtonClicked()
|
||||||
}
|
}
|
||||||
.launchIn((adapter as LibraryCategoryAdapter).controller.scope)
|
.launchIn((adapter as LibraryCategoryAdapter).controller.viewScope)
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class LibraryCompactGridHolder(
|
|||||||
.onEach {
|
.onEach {
|
||||||
playButtonClicked()
|
playButtonClicked()
|
||||||
}
|
}
|
||||||
.launchIn((adapter as LibraryCategoryAdapter).controller.scope)
|
.launchIn((adapter as LibraryCategoryAdapter).controller.viewScope)
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
|
@ -200,13 +200,13 @@ class LibraryController(
|
|||||||
activeCategory = it
|
activeCategory = it
|
||||||
updateTitle()
|
updateTitle()
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
getColumnsPreferenceForCurrentOrientation().asImmediateFlow { mangaPerRow = it }
|
getColumnsPreferenceForCurrentOrientation().asImmediateFlow { mangaPerRow = it }
|
||||||
.drop(1)
|
.drop(1)
|
||||||
// Set again the adapter to recalculate the covers height
|
// Set again the adapter to recalculate the covers height
|
||||||
.onEach { reattachAdapter() }
|
.onEach { reattachAdapter() }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
if (selectedMangas.isNotEmpty()) {
|
if (selectedMangas.isNotEmpty()) {
|
||||||
createActionModeIfNeeded()
|
createActionModeIfNeeded()
|
||||||
@ -234,7 +234,7 @@ class LibraryController(
|
|||||||
GlobalSearchController(query).withFadeTransaction()
|
GlobalSearchController(query).withFadeTransaction()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
(activity!! as MainActivity).fixViewToBottom(binding.actionToolbar)
|
(activity!! as MainActivity).fixViewToBottom(binding.actionToolbar)
|
||||||
}
|
}
|
||||||
@ -249,6 +249,7 @@ class LibraryController(
|
|||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
|
(activity!! as MainActivity).clearFixViewToBottom(binding.actionToolbar)
|
||||||
binding.actionToolbar.destroy()
|
binding.actionToolbar.destroy()
|
||||||
adapter?.onDestroy()
|
adapter?.onDestroy()
|
||||||
adapter = null
|
adapter = null
|
||||||
@ -445,7 +446,7 @@ class LibraryController(
|
|||||||
query = it.toString()
|
query = it.toString()
|
||||||
performSearch()
|
performSearch()
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun performSearch() {
|
private fun performSearch() {
|
||||||
@ -693,7 +694,7 @@ class LibraryController(
|
|||||||
.onEach {
|
.onEach {
|
||||||
updateSyncStatus(it)
|
updateSyncStatus(it)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
// <-- EXH
|
// <-- EXH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,8 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
|
|||||||
private var isConfirmingExit: Boolean = false
|
private var isConfirmingExit: Boolean = false
|
||||||
private var isHandlingShortcut: Boolean = false
|
private var isHandlingShortcut: Boolean = false
|
||||||
|
|
||||||
|
private var fixedViewsToBottom = mutableMapOf<View, AppBarLayout.OnOffsetChangedListener>()
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
// Idle-until-urgent
|
// Idle-until-urgent
|
||||||
private var firstPaint = false
|
private var firstPaint = false
|
||||||
@ -466,12 +468,17 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
|
|||||||
* the collapsing AppBarLayout.
|
* the collapsing AppBarLayout.
|
||||||
*/
|
*/
|
||||||
fun fixViewToBottom(view: View) {
|
fun fixViewToBottom(view: View) {
|
||||||
binding.appbar.addOnOffsetChangedListener(
|
val listener = AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
|
||||||
AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
|
|
||||||
val maxAbsOffset = appBarLayout.measuredHeight - binding.tabs.measuredHeight
|
val maxAbsOffset = appBarLayout.measuredHeight - binding.tabs.measuredHeight
|
||||||
view.translationY = -maxAbsOffset - verticalOffset.toFloat()
|
view.translationY = -maxAbsOffset - verticalOffset.toFloat()
|
||||||
}
|
}
|
||||||
)
|
binding.appbar.addOnOffsetChangedListener(listener)
|
||||||
|
fixedViewsToBottom[view] = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearFixViewToBottom(view: View) {
|
||||||
|
val listener = fixedViewsToBottom.remove(view)
|
||||||
|
binding.appbar.removeOnOffsetChangedListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setBottomNavBehaviorOnScroll() {
|
private fun setBottomNavBehaviorOnScroll() {
|
||||||
|
@ -125,17 +125,17 @@ class EditMangaDialog : DialogController {
|
|||||||
binding.mangaGenresTags.clearFocus()
|
binding.mangaGenresTags.clearFocus()
|
||||||
binding.coverLayout.clicks()
|
binding.coverLayout.clicks()
|
||||||
.onEach { infoController.changeCover() }
|
.onEach { infoController.changeCover() }
|
||||||
.launchIn(infoController.scope)
|
.launchIn(infoController.viewScope)
|
||||||
binding.resetTags.clicks()
|
binding.resetTags.clicks()
|
||||||
.onEach { resetTags() }
|
.onEach { resetTags() }
|
||||||
.launchIn(infoController.scope)
|
.launchIn(infoController.viewScope)
|
||||||
binding.resetCover.isVisible = !isLocal
|
binding.resetCover.isVisible = !isLocal
|
||||||
binding.resetCover.clicks()
|
binding.resetCover.clicks()
|
||||||
.onEach {
|
.onEach {
|
||||||
binding.root.context.toast(R.string.cover_reset_toast)
|
binding.root.context.toast(R.string.cover_reset_toast)
|
||||||
customCoverUri = null
|
customCoverUri = null
|
||||||
willResetCover = true
|
willResetCover = true
|
||||||
}.launchIn(infoController.scope)
|
}.launchIn(infoController.viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetTags() {
|
private fun resetTags() {
|
||||||
@ -203,7 +203,7 @@ class EditMangaDialog : DialogController {
|
|||||||
}
|
}
|
||||||
.negativeButton(android.R.string.cancel)
|
.negativeButton(android.R.string.cancel)
|
||||||
.show()
|
.show()
|
||||||
}.launchIn(infoController.scope)
|
}.launchIn(infoController.viewScope)
|
||||||
}
|
}
|
||||||
addView(addTagChip)
|
addView(addTagChip)
|
||||||
}
|
}
|
||||||
|
@ -327,14 +327,14 @@ class MangaController :
|
|||||||
|
|
||||||
binding.recycler.scrollEvents()
|
binding.recycler.scrollEvents()
|
||||||
.onEach { updateToolbarTitleAlpha() }
|
.onEach { updateToolbarTitleAlpha() }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
binding.swipeRefresh.refreshes()
|
binding.swipeRefresh.refreshes()
|
||||||
.onEach {
|
.onEach {
|
||||||
fetchMangaInfoFromSource(manualFetch = true)
|
fetchMangaInfoFromSource(manualFetch = true)
|
||||||
fetchChaptersFromSource(manualFetch = true)
|
fetchChaptersFromSource(manualFetch = true)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
(activity!! as MainActivity).fixViewToBottom(binding.actionToolbar)
|
(activity!! as MainActivity).fixViewToBottom(binding.actionToolbar)
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ class MangaController :
|
|||||||
// Replace self
|
// Replace self
|
||||||
router?.replaceTopController(MangaController(redirect).withFadeTransaction())
|
router?.replaceTopController(MangaController(redirect).withFadeTransaction())
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
updateFilterIconState()
|
updateFilterIconState()
|
||||||
}
|
}
|
||||||
@ -386,8 +386,7 @@ class MangaController :
|
|||||||
actionFab = fab
|
actionFab = fab
|
||||||
fab.setText(R.string.action_start)
|
fab.setText(R.string.action_start)
|
||||||
fab.setIconResource(R.drawable.ic_play_arrow_24dp)
|
fab.setIconResource(R.drawable.ic_play_arrow_24dp)
|
||||||
fab.clicks()
|
fab.setOnClickListener {
|
||||||
.onEach {
|
|
||||||
val item = presenter.getNextUnreadChapter()
|
val item = presenter.getNextUnreadChapter()
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
// Create animation listener
|
// Create animation listener
|
||||||
@ -412,16 +411,17 @@ class MangaController :
|
|||||||
view?.context?.toast(R.string.no_next_chapter)
|
view?.context?.toast(R.string.no_next_chapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
override fun cleanupFab(fab: ExtendedFloatingActionButton) {
|
||||||
|
fab.setOnClickListener(null)
|
||||||
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
actionFabScrollListener?.let { binding.recycler.removeOnScrollListener(it) }
|
||||||
actionFab = null
|
actionFab = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
|
(activity!! as MainActivity).clearFixViewToBottom(binding.actionToolbar)
|
||||||
binding.actionToolbar.destroy()
|
binding.actionToolbar.destroy()
|
||||||
mangaInfoAdapter = null
|
mangaInfoAdapter = null
|
||||||
chaptersHeaderAdapter = null
|
chaptersHeaderAdapter = null
|
||||||
@ -926,7 +926,7 @@ class MangaController :
|
|||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class TrackController :
|
|||||||
binding.swipeRefresh.isEnabled = false
|
binding.swipeRefresh.isEnabled = false
|
||||||
binding.swipeRefresh.refreshes()
|
binding.swipeRefresh.refreshes()
|
||||||
.onEach { presenter.refresh() }
|
.onEach { presenter.refresh() }
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
|
@ -77,7 +77,7 @@ class TrackSearchDialog : DialogController {
|
|||||||
.onEach { position ->
|
.onEach { position ->
|
||||||
selectedItem = adapter.getItem(position)
|
selectedItem = adapter.getItem(position)
|
||||||
}
|
}
|
||||||
.launchIn(trackController.scope)
|
.launchIn(trackController.viewScope)
|
||||||
|
|
||||||
// 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) {
|
||||||
@ -99,7 +99,7 @@ class TrackSearchDialog : DialogController {
|
|||||||
.debounce(TimeUnit.SECONDS.toMillis(1))
|
.debounce(TimeUnit.SECONDS.toMillis(1))
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
.onEach { search(it.toString()) }
|
.onEach { search(it.toString()) }
|
||||||
.launchIn(trackController.scope)
|
.launchIn(trackController.viewScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun search(query: String) {
|
private fun search(query: String) {
|
||||||
|
@ -189,7 +189,7 @@ class HistoryController :
|
|||||||
query = it.toString()
|
query = it.toString()
|
||||||
presenter.updateList(query)
|
presenter.updateList(query)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
// 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(
|
searchItem.fixExpand(
|
||||||
|
@ -97,7 +97,7 @@ class UpdatesController :
|
|||||||
val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
|
val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
|
||||||
binding.swipeRefresh.isEnabled = firstPos <= 0
|
binding.swipeRefresh.isEnabled = firstPos <= 0
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
|
binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
|
||||||
binding.swipeRefresh.refreshes()
|
binding.swipeRefresh.refreshes()
|
||||||
@ -107,13 +107,14 @@ class UpdatesController :
|
|||||||
// 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(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
(activity!! as MainActivity).fixViewToBottom(binding.actionToolbar)
|
(activity!! as MainActivity).fixViewToBottom(binding.actionToolbar)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
override fun onDestroyView(view: View) {
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
|
(activity!! as MainActivity).clearFixViewToBottom(binding.actionToolbar)
|
||||||
binding.actionToolbar.destroy()
|
binding.actionToolbar.destroy()
|
||||||
adapter = null
|
adapter = null
|
||||||
super.onDestroyView(view)
|
super.onDestroyView(view)
|
||||||
|
@ -604,7 +604,7 @@ class SettingsEhController : SettingsController() {
|
|||||||
multiSelectListPreference {
|
multiSelectListPreference {
|
||||||
key = PreferenceKeys.eh_autoUpdateRestrictions
|
key = PreferenceKeys.eh_autoUpdateRestrictions
|
||||||
titleRes = R.string.auto_update_restrictions
|
titleRes = R.string.auto_update_restrictions
|
||||||
entriesRes = arrayOf(R.string.wifi, R.string.charging)
|
entriesRes = arrayOf(R.string.network_unmetered, R.string.charging)
|
||||||
entryValues = arrayOf("wifi", "ac")
|
entryValues = arrayOf("wifi", "ac")
|
||||||
summaryRes = R.string.pref_library_update_restriction_summary
|
summaryRes = R.string.pref_library_update_restriction_summary
|
||||||
|
|
||||||
|
@ -37,13 +37,13 @@ class BatchAddController : NucleusController<EhFragmentBatchAddBinding, BatchAdd
|
|||||||
.onEach {
|
.onEach {
|
||||||
addGalleries(binding.galleriesBox.text.toString())
|
addGalleries(binding.galleriesBox.text.toString())
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
binding.progressDismissBtn.clicks()
|
binding.progressDismissBtn.clicks()
|
||||||
.onEach {
|
.onEach {
|
||||||
presenter.currentlyAddingRelay.call(BatchAddPresenter.STATE_PROGRESS_TO_INPUT)
|
presenter.currentlyAddingRelay.call(BatchAddPresenter.STATE_PROGRESS_TO_INPUT)
|
||||||
}
|
}
|
||||||
.launchIn(scope)
|
.launchIn(viewScope)
|
||||||
|
|
||||||
val progressSubscriptions = CompositeSubscription()
|
val progressSubscriptions = CompositeSubscription()
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(scope + Dispatchers.IO)
|
.launchIn(viewScope + Dispatchers.IO)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user