Address coroutine scope leaks for SY
This commit is contained in:
parent
3683665e8a
commit
fca7dad7b0
@ -1,9 +1,9 @@
|
||||
package eu.kanade.tachiyomi.source.online
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
|
||||
interface BrowseSourceFilterHeader : CatalogueSource {
|
||||
fun getFilterHeader(controller: Controller): RecyclerView.Adapter<*>
|
||||
fun getFilterHeader(controller: BaseController<*>): RecyclerView.Adapter<*>
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import androidx.core.text.HtmlCompat
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
@ -27,6 +26,7 @@ import eu.kanade.tachiyomi.source.online.LoginSource
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.RandomMangaSource
|
||||
import eu.kanade.tachiyomi.source.online.UrlImportableSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import eu.kanade.tachiyomi.util.lang.asObservable
|
||||
@ -267,7 +267,7 @@ class MangaDex(delegate: HttpSource, val context: Context) :
|
||||
return withContext(Dispatchers.IO) { FollowsHandler(client, headers, Injekt.get(), useLowQualityThumbnail()).updateFollowStatus(mangaID, followStatus) }
|
||||
}
|
||||
|
||||
override fun getFilterHeader(controller: Controller): MangaDexFabHeaderAdapter {
|
||||
override fun getFilterHeader(controller: BaseController<*>): MangaDexFabHeaderAdapter {
|
||||
return MangaDexFabHeaderAdapter(controller, this)
|
||||
}
|
||||
|
||||
|
@ -17,20 +17,10 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class MigrationBottomSheetDialog(activity: Activity, theme: Int, private val listener: StartMigrationListener) : BottomSheetDialog(activity, theme) {
|
||||
/**
|
||||
* Preferences helper.
|
||||
*/
|
||||
private val preferences by injectLazy<PreferencesHelper>()
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
private val binding: MigrationBottomSheetBinding = MigrationBottomSheetBinding.inflate(activity.layoutInflater)
|
||||
|
||||
@ -50,7 +40,7 @@ class MigrationBottomSheetDialog(activity: Activity, theme: Int, private val lis
|
||||
|
||||
initPreferences()
|
||||
|
||||
binding.fab.clicks().onEach {
|
||||
binding.fab.setOnClickListener {
|
||||
preferences.skipPreMigration().set(binding.skipStep.isChecked)
|
||||
listener.startMigration(
|
||||
if (binding.useSmartSearch.isChecked && binding.extraSearchParamText.text.isNotBlank()) {
|
||||
@ -58,7 +48,7 @@ class MigrationBottomSheetDialog(activity: Activity, theme: Int, private val lis
|
||||
} else null
|
||||
)
|
||||
dismiss()
|
||||
}.launchIn(scope)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,7 +65,7 @@ class MigrationBottomSheetDialog(activity: Activity, theme: Int, private val lis
|
||||
binding.migChapters.setOnCheckedChangeListener { _, _ -> setFlags() }
|
||||
binding.migCategories.setOnCheckedChangeListener { _, _ -> setFlags() }
|
||||
binding.migTracking.setOnCheckedChangeListener { _, _ -> setFlags() }
|
||||
binding.migExtra.setOnCheckedChangeListener { buttonView, isChecked -> setFlags() }
|
||||
binding.migExtra.setOnCheckedChangeListener { _, _ -> setFlags() }
|
||||
|
||||
binding.useSmartSearch.bindToPreference(preferences.smartMigration())
|
||||
binding.extraSearchParamText.isVisible = false
|
||||
|
@ -27,9 +27,6 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListController
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationProcedureConfig
|
||||
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class PreMigrationController(bundle: Bundle? = null) :
|
||||
@ -44,8 +41,6 @@ class PreMigrationController(bundle: Bundle? = null) :
|
||||
|
||||
private val config: LongArray = args.getLongArray(MANGA_IDS_EXTRA) ?: LongArray(0)
|
||||
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
private var actionFab: ExtendedFloatingActionButton? = null
|
||||
private var actionFabScrollListener: RecyclerView.OnScrollListener? = null
|
||||
|
||||
|
@ -66,8 +66,6 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
private var adapter: MigrationProcessAdapter? = null
|
||||
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
|
||||
val config: MigrationProcedureConfig? = args.getParcelable(CONFIG_EXTRA)
|
||||
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
@ -89,7 +87,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun getTitle(): String? {
|
||||
override fun getTitle(): String {
|
||||
return resources?.getString(R.string.migration) + " (${adapter?.items?.count {
|
||||
it.manga.migrationStatus != MigrationStatus.RUNNING
|
||||
}}/${adapter?.itemCount ?: 0})"
|
||||
@ -102,7 +100,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
|
||||
val newMigratingManga = migratingManga ?: run {
|
||||
val new = config.mangaIds.map {
|
||||
MigratingManga(db, sourceManager, it, scope.coroutineContext)
|
||||
MigratingManga(db, sourceManager, it, viewScope.coroutineContext + Dispatchers.IO)
|
||||
}
|
||||
migratingManga = new.toMutableList()
|
||||
new
|
||||
@ -117,7 +115,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||
adapter?.updateDataSet(newMigratingManga.map { it.toModal() })
|
||||
|
||||
if (migrationsJob == null) {
|
||||
migrationsJob = scope.launch {
|
||||
migrationsJob = viewScope.launch(Dispatchers.IO) {
|
||||
runMigrations(newMigratingManga)
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +22,11 @@ import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||
import exh.MERGED_SOURCE_ID
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.withContext
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.text.DecimalFormat
|
||||
|
||||
@ -41,7 +38,6 @@ class MigrationProcessHolder(
|
||||
private val sourceManager: SourceManager by injectLazy()
|
||||
|
||||
private var item: MigrationProcessItem? = null
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private val binding = MigrationProcessItemBinding.bind(view)
|
||||
|
||||
init {
|
||||
@ -84,7 +80,7 @@ class MigrationProcessHolder(
|
||||
true
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}.launchIn(scope)
|
||||
}.launchIn(adapter.controller.viewScope)
|
||||
}
|
||||
|
||||
/*launchUI {
|
||||
@ -120,7 +116,7 @@ class MigrationProcessHolder(
|
||||
true
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}.launchIn(scope)
|
||||
}.launchIn(adapter.controller.viewScope)
|
||||
} else {
|
||||
binding.migrationMangaCardTo.loadingGroup.isVisible = false
|
||||
binding.migrationMangaCardTo.title.text = view.context.applicationContext
|
||||
|
@ -9,7 +9,6 @@ import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.ConcatAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.chip.Chip
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
@ -17,6 +16,7 @@ import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.databinding.SourceFilterSheetBinding
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.online.BrowseSourceFilterHeader
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.widget.SimpleNavigationView
|
||||
import exh.savedsearches.EXHSavedSearch
|
||||
import exh.source.getMainSource
|
||||
@ -24,7 +24,7 @@ import exh.source.getMainSource
|
||||
class SourceFilterSheet(
|
||||
activity: Activity,
|
||||
// SY -->
|
||||
controller: Controller,
|
||||
controller: BaseController<*>,
|
||||
source: CatalogueSource,
|
||||
searches: List<EXHSavedSearch> = emptyList(),
|
||||
// SY <--
|
||||
@ -72,7 +72,7 @@ class SourceFilterSheet(
|
||||
}
|
||||
// SY <--
|
||||
|
||||
class FilterNavigationView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null /* SY --> */, searches: List<EXHSavedSearch> = emptyList(), source: CatalogueSource? = null, controller: Controller? = null/* SY <-- */) :
|
||||
class FilterNavigationView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null /* SY --> */, searches: List<EXHSavedSearch> = emptyList(), source: CatalogueSource? = null, controller: BaseController<*>? = null/* SY <-- */) :
|
||||
SimpleNavigationView(context, attrs) {
|
||||
|
||||
var onFilterClicked = {}
|
||||
|
@ -8,12 +8,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.databinding.IndexAdapterBinding
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
/**
|
||||
* Adapter that holds the search cards.
|
||||
@ -26,7 +20,6 @@ class IndexAdapter(val controller: IndexController) :
|
||||
val clickListener: ClickListener = controller
|
||||
|
||||
private lateinit var binding: IndexAdapterBinding
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
var holder: IndexAdapter.ViewHolder? = null
|
||||
|
||||
@ -50,16 +43,12 @@ class IndexAdapter(val controller: IndexController) :
|
||||
private var browseLastBoundResults: List<IndexCardItem>? = null
|
||||
|
||||
init {
|
||||
binding.browseBarWrapper.clicks()
|
||||
.onEach {
|
||||
clickListener.onBrowseClick()
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.latestBarWrapper.clicks()
|
||||
.onEach {
|
||||
clickListener.onLatestClick()
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.browseBarWrapper.setOnClickListener {
|
||||
clickListener.onBrowseClick()
|
||||
}
|
||||
binding.latestBarWrapper.setOnClickListener {
|
||||
clickListener.onLatestClick()
|
||||
}
|
||||
|
||||
binding.latestRecycler.layoutManager = LinearLayoutManager(itemView.context, LinearLayoutManager.HORIZONTAL, false)
|
||||
binding.latestRecycler.adapter = latestAdapter
|
||||
|
@ -17,9 +17,7 @@ import eu.kanade.tachiyomi.util.lang.asFlow
|
||||
import eu.kanade.tachiyomi.util.lang.runAsObservable
|
||||
import exh.savedsearches.EXHSavedSearch
|
||||
import exh.savedsearches.JsonSavedSearch
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.singleOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -55,8 +53,6 @@ open class IndexPresenter(
|
||||
*/
|
||||
private var fetchSourcesSubscription: Subscription? = null
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
/**
|
||||
* Query from the view.
|
||||
*/
|
||||
@ -102,7 +98,7 @@ open class IndexPresenter(
|
||||
// Create image fetch subscription
|
||||
initializeFetchImageSubscription()
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
presenterScope.launch(Dispatchers.IO) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Observable.just(null).subscribeLatestCache({ view, results ->
|
||||
view.setLatestManga(results)
|
||||
@ -130,7 +126,7 @@ open class IndexPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
presenterScope.launch(Dispatchers.IO) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Observable.just(null).subscribeLatestCache({ view, results ->
|
||||
view.setBrowseManga(results)
|
||||
|
@ -5,9 +5,6 @@ import com.elvishew.xlog.XLog
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import rx.Observable
|
||||
@ -29,8 +26,6 @@ class BiometricTimesPresenter : BasePresenter<BiometricTimesController>() {
|
||||
|
||||
val preferences: PreferencesHelper = Injekt.get()
|
||||
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
/**
|
||||
* Called when the presenter is created.
|
||||
*
|
||||
@ -47,7 +42,7 @@ class BiometricTimesPresenter : BasePresenter<BiometricTimesController>() {
|
||||
.map { it.map(::BiometricTimesItem) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeLatestCache(BiometricTimesController::setBiometricTimeItems)
|
||||
}.launchIn(scope)
|
||||
}.launchIn(presenterScope)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,9 +5,6 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.minusAssign
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import rx.Observable
|
||||
@ -27,8 +24,6 @@ class SortTagPresenter : BasePresenter<SortTagController>() {
|
||||
|
||||
val preferences: PreferencesHelper = Injekt.get()
|
||||
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
/**
|
||||
* Called when the presenter is created.
|
||||
*
|
||||
@ -46,7 +41,7 @@ class SortTagPresenter : BasePresenter<SortTagController>() {
|
||||
.map { tagPairs -> tagPairs.map { it.second }.map(::SortTagItem) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeLatestCache(SortTagController::setCategories)
|
||||
}.launchIn(scope)
|
||||
}.launchIn(presenterScope)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,9 +3,6 @@ package eu.kanade.tachiyomi.ui.category.repos
|
||||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import rx.Observable
|
||||
@ -19,8 +16,6 @@ import uy.kohesive.injekt.api.get
|
||||
class RepoPresenter(
|
||||
private val preferences: PreferencesHelper = Injekt.get()
|
||||
) : BasePresenter<RepoController>() {
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
/**
|
||||
* List containing repos.
|
||||
*/
|
||||
@ -41,7 +36,7 @@ class RepoPresenter(
|
||||
.map { it.map(::RepoItem) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeLatestCache(RepoController::setRepos)
|
||||
}.launchIn(scope)
|
||||
}.launchIn(presenterScope)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,9 +4,6 @@ import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import rx.Observable
|
||||
@ -28,8 +25,6 @@ class SourceCategoryPresenter(
|
||||
|
||||
val preferences: PreferencesHelper = Injekt.get()
|
||||
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
/**
|
||||
* Called when the presenter is created.
|
||||
*
|
||||
@ -45,7 +40,7 @@ class SourceCategoryPresenter(
|
||||
.map { it.map(::SourceCategoryItem) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeLatestCache(SourceCategoryController::setCategories)
|
||||
}.launchIn(scope)
|
||||
}.launchIn(presenterScope)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -738,5 +738,10 @@ class LibraryPresenter(
|
||||
|
||||
return map to categories
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
favoritesSync.onDestroy()
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
@ -57,8 +57,6 @@ import exh.metadata.metadata.base.insertFlatMetadata
|
||||
import exh.source.getMainSource
|
||||
import exh.util.shouldDeleteChapters
|
||||
import exh.util.trimOrNull
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
@ -88,8 +86,6 @@ class MangaPresenter(
|
||||
private val sourceManager: SourceManager = Injekt.get()
|
||||
) : BasePresenter<MangaController>() {
|
||||
|
||||
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||
|
||||
/**
|
||||
* Subscription to update the manga from the source.
|
||||
*/
|
||||
@ -236,7 +232,7 @@ class MangaPresenter(
|
||||
)
|
||||
)
|
||||
}
|
||||
}.launchIn(scope)
|
||||
}.launchIn(presenterScope)
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
|
@ -71,15 +71,15 @@ import eu.kanade.tachiyomi.util.view.snack
|
||||
import eu.kanade.tachiyomi.widget.SimpleAnimationListener
|
||||
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
|
||||
import exh.util.defaultReaderType
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.sample
|
||||
import kotlinx.coroutines.launch
|
||||
import nucleus.factory.RequiresPresenter
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.widget.checkedChanges
|
||||
@ -122,7 +122,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||
// SY -->
|
||||
private var ehUtilsVisible = false
|
||||
|
||||
private var autoscrollScope: CoroutineScope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private val autoScrollFlow = MutableSharedFlow<Unit>()
|
||||
private var autoScrollJob: Job? = null
|
||||
private val sourceManager: SourceManager by injectLazy()
|
||||
|
||||
@ -219,19 +219,12 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||
if (interval == -1.0) return
|
||||
|
||||
val duration = interval.seconds
|
||||
autoScrollJob =
|
||||
flow {
|
||||
while (true) {
|
||||
delay(duration)
|
||||
emit(Unit)
|
||||
}
|
||||
}.onEach {
|
||||
viewer.let { v ->
|
||||
if (v is PagerViewer) v.moveToNext()
|
||||
else if (v is WebtoonViewer) v.scrollDown()
|
||||
}
|
||||
autoScrollJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||
while (true) {
|
||||
delay(duration)
|
||||
autoScrollFlow.emit(Unit)
|
||||
}
|
||||
.launchIn(autoscrollScope)
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
|
||||
@ -591,6 +584,15 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
autoScrollFlow
|
||||
.onEach {
|
||||
viewer.let { v ->
|
||||
if (v is PagerViewer) v.moveToNext()
|
||||
else if (v is WebtoonViewer) v.scrollDown()
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
// <-- EH
|
||||
|
||||
// Set initial visibility
|
||||
|
@ -30,6 +30,7 @@ import exh.util.wifiManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.FormBody
|
||||
@ -418,6 +419,10 @@ class FavoritesSyncHelper(val context: Context) {
|
||||
|
||||
class IgnoredException : RuntimeException()
|
||||
|
||||
fun onDestroy() {
|
||||
scope.cancel()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val THROTTLE_WARN = 1000
|
||||
}
|
||||
|
@ -4,27 +4,22 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.databinding.SourceFilterMangadexHeaderBinding
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.online.RandomMangaSource
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
|
||||
import exh.md.follows.MangaDexFollowsController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class MangaDexFabHeaderAdapter(val controller: Controller, val source: CatalogueSource) :
|
||||
class MangaDexFabHeaderAdapter(val controller: BaseController<*>, val source: CatalogueSource) :
|
||||
RecyclerView.Adapter<MangaDexFabHeaderAdapter.SavedSearchesViewHolder>() {
|
||||
|
||||
private lateinit var binding: SourceFilterMangadexHeaderBinding
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SavedSearchesViewHolder {
|
||||
binding = SourceFilterMangadexHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return SavedSearchesViewHolder(binding.root)
|
||||
@ -38,18 +33,15 @@ class MangaDexFabHeaderAdapter(val controller: Controller, val source: Catalogue
|
||||
|
||||
inner class SavedSearchesViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind() {
|
||||
binding.mangadexFollows.clicks()
|
||||
.onEach {
|
||||
controller.router.replaceTopController(MangaDexFollowsController(source).withFadeTransaction())
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.mangadexFollows.setOnClickListener {
|
||||
controller.router.replaceTopController(MangaDexFollowsController(source).withFadeTransaction())
|
||||
}
|
||||
binding.mangadexRandom.clicks()
|
||||
.onEach {
|
||||
(source as? RandomMangaSource)?.fetchRandomMangaUrl()?.let { randomMangaId ->
|
||||
controller.router.replaceTopController(BrowseSourceController(source, randomMangaId).withFadeTransaction())
|
||||
}
|
||||
}
|
||||
.launchIn(scope)
|
||||
}.launchIn(controller.viewScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@ -59,6 +60,11 @@ class ConfiguringDialogController : DialogController() {
|
||||
materialDialog = null
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
scope.cancel()
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
finish()
|
||||
|
@ -11,9 +11,7 @@ import exh.GalleryAddEvent
|
||||
import exh.GalleryAdder
|
||||
import exh.util.trimOrNull
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -23,7 +21,6 @@ import uy.kohesive.injekt.api.get
|
||||
class BatchAddPresenter : BasePresenter<BatchAddController>() {
|
||||
|
||||
private val galleryAdder by lazy { GalleryAdder() }
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
val progressTotalRelay = BehaviorRelay.create(0)!!
|
||||
val progressRelay = BehaviorRelay.create(0)!!
|
||||
@ -62,7 +59,7 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
|
||||
XLog.tag("BatchAddPresenter").enableStackTrace(2).e(throwable)
|
||||
}
|
||||
|
||||
scope.launch(Dispatchers.IO + handler) {
|
||||
presenterScope.launch(Dispatchers.IO + handler) {
|
||||
val succeeded = mutableListOf<String>()
|
||||
val failed = mutableListOf<String>()
|
||||
|
||||
|
@ -6,18 +6,11 @@ import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.databinding.MetadataViewItemBinding
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
|
||||
class MetadataViewAdapter(private var data: List<Pair<String, String>>) :
|
||||
RecyclerView.Adapter<MetadataViewAdapter.ViewHolder>() {
|
||||
|
||||
private lateinit var binding: MetadataViewItemBinding
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MetadataViewAdapter.ViewHolder {
|
||||
binding = MetadataViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
@ -42,11 +35,9 @@ class MetadataViewAdapter(private var data: List<Pair<String, String>>) :
|
||||
fun bind(position: Int) {
|
||||
binding.infoTitle.text = data[position].first
|
||||
binding.infoText.text = data[position].second
|
||||
binding.infoText.clicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(data[position].second, data[position].second)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.infoText.setOnClickListener {
|
||||
itemView.context.copyToClipboard(data[position].second, data[position].second)
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
@ -14,20 +14,12 @@ import exh.metadata.MetadataUtil
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
|
||||
class EHentaiDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<EHentaiDescriptionAdapter.EHentaiDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterEhBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EHentaiDescriptionViewHolder {
|
||||
@ -87,25 +79,22 @@ class EHentaiDescriptionAdapter(
|
||||
binding.uploader,
|
||||
binding.visible
|
||||
).forEach { textView ->
|
||||
textView.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
textView.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,20 +12,12 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.EightMusesSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
|
||||
class EightMusesDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<EightMusesDescriptionAdapter.EightMusesDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapter8mBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EightMusesDescriptionViewHolder {
|
||||
@ -48,24 +40,21 @@ class EightMusesDescriptionAdapter(
|
||||
|
||||
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||
|
||||
binding.title.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.title.text.toString(),
|
||||
binding.title.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.title.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.title.text.toString(),
|
||||
binding.title.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,20 +12,12 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.HBrowseSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
|
||||
class HBrowseDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<HBrowseDescriptionAdapter.HBrowseDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterHbBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HBrowseDescriptionViewHolder {
|
||||
@ -49,24 +41,21 @@ class HBrowseDescriptionAdapter(
|
||||
|
||||
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||
|
||||
binding.pages.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.pages.text.toString(),
|
||||
binding.pages.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.pages.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.pages.text.toString(),
|
||||
binding.pages.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,20 +12,12 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.HentaiCafeSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
|
||||
class HentaiCafeDescriptionAdapter(
|
||||
private val controller: MangaController
|
||||
) :
|
||||
RecyclerView.Adapter<HentaiCafeDescriptionAdapter.HentaiCafeDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterHcBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HentaiCafeDescriptionViewHolder {
|
||||
@ -48,24 +40,21 @@ class HentaiCafeDescriptionAdapter(
|
||||
|
||||
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||
|
||||
binding.artist.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.artist.text.toString(),
|
||||
binding.artist.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.artist.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.artist.text.toString(),
|
||||
binding.artist.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,6 @@ import exh.metadata.MetadataUtil
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.HitomiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
import java.util.Date
|
||||
|
||||
class HitomiDescriptionAdapter(
|
||||
@ -27,7 +20,6 @@ class HitomiDescriptionAdapter(
|
||||
) :
|
||||
RecyclerView.Adapter<HitomiDescriptionAdapter.HitomiDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterHiBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HitomiDescriptionViewHolder {
|
||||
@ -63,25 +55,22 @@ class HitomiDescriptionAdapter(
|
||||
binding.language,
|
||||
binding.whenPosted
|
||||
).forEach { textView ->
|
||||
textView.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
textView.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,6 @@ import exh.metadata.MetadataUtil.getRatingString
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
import kotlin.math.round
|
||||
|
||||
class MangaDexDescriptionAdapter(
|
||||
@ -28,7 +21,6 @@ class MangaDexDescriptionAdapter(
|
||||
) :
|
||||
RecyclerView.Adapter<MangaDexDescriptionAdapter.MangaDexDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterMdBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MangaDexDescriptionViewHolder {
|
||||
@ -55,24 +47,21 @@ class MangaDexDescriptionAdapter(
|
||||
|
||||
binding.moreInfo.bindDrawable(itemView.context, R.drawable.ic_info_24dp)
|
||||
|
||||
binding.rating.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.rating.text.toString(),
|
||||
binding.rating.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.rating.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
binding.rating.text.toString(),
|
||||
binding.rating.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,6 @@ import exh.metadata.MetadataUtil
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.NHentaiSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
import java.util.Date
|
||||
|
||||
class NHentaiDescriptionAdapter(
|
||||
@ -28,7 +21,6 @@ class NHentaiDescriptionAdapter(
|
||||
) :
|
||||
RecyclerView.Adapter<NHentaiDescriptionAdapter.NHentaiDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterNhBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NHentaiDescriptionViewHolder {
|
||||
@ -80,25 +72,22 @@ class NHentaiDescriptionAdapter(
|
||||
binding.pages,
|
||||
binding.whenPosted
|
||||
).forEach { textView ->
|
||||
textView.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
textView.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,6 @@ import exh.metadata.MetadataUtil
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.PervEdenSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
import java.util.Locale
|
||||
import kotlin.math.round
|
||||
|
||||
@ -29,7 +22,6 @@ class PervEdenDescriptionAdapter(
|
||||
) :
|
||||
RecyclerView.Adapter<PervEdenDescriptionAdapter.PervEdenDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterPeBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PervEdenDescriptionViewHolder {
|
||||
@ -70,25 +62,22 @@ class PervEdenDescriptionAdapter(
|
||||
binding.language,
|
||||
binding.rating
|
||||
).forEach { textView ->
|
||||
textView.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
textView.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,6 @@ import exh.metadata.MetadataUtil
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.PururinSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
import kotlin.math.round
|
||||
|
||||
class PururinDescriptionAdapter(
|
||||
@ -28,7 +21,6 @@ class PururinDescriptionAdapter(
|
||||
) :
|
||||
RecyclerView.Adapter<PururinDescriptionAdapter.PururinDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterPuBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PururinDescriptionViewHolder {
|
||||
@ -76,25 +68,22 @@ class PururinDescriptionAdapter(
|
||||
binding.size,
|
||||
binding.uploader
|
||||
).forEach { textView ->
|
||||
textView.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
textView.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,6 @@ import exh.metadata.MetadataUtil
|
||||
import exh.metadata.bindDrawable
|
||||
import exh.metadata.metadata.TsuminoSearchMetadata
|
||||
import exh.ui.metadata.MetadataViewController
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.view.clicks
|
||||
import reactivecircus.flowbinding.android.view.longClicks
|
||||
import java.util.Date
|
||||
import kotlin.math.round
|
||||
|
||||
@ -29,7 +22,6 @@ class TsuminoDescriptionAdapter(
|
||||
) :
|
||||
RecyclerView.Adapter<TsuminoDescriptionAdapter.TsuminoDescriptionViewHolder>() {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
private lateinit var binding: DescriptionAdapterTsBinding
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TsuminoDescriptionViewHolder {
|
||||
@ -77,25 +69,22 @@ class TsuminoDescriptionAdapter(
|
||||
binding.uploader,
|
||||
binding.whenPosted
|
||||
).forEach { textView ->
|
||||
textView.longClicks()
|
||||
.onEach {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
textView.setOnLongClickListener {
|
||||
itemView.context.copyToClipboard(
|
||||
textView.text.toString(),
|
||||
textView.text.toString()
|
||||
)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
binding.moreInfo.clicks()
|
||||
.onEach {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
.launchIn(scope)
|
||||
binding.moreInfo.setOnClickListener {
|
||||
controller.router?.pushController(
|
||||
MetadataViewController(
|
||||
controller.manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,6 +134,11 @@ class MangadexLoginDialog(bundle: Bundle? = null) : DialogController(bundle) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
scope.cancel()
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun siteLoginDialogClosed(source: Source)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user