mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Migrate more preferences
This commit is contained in:
		@@ -76,51 +76,53 @@ class PreferencesHelper(val context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun rotation() = rxPrefs.getInteger(Keys.rotation, 1)
 | 
			
		||||
 | 
			
		||||
    fun pageTransitions() = rxPrefs.getBoolean(Keys.enableTransitions, true)
 | 
			
		||||
    fun pageTransitions() = flowPrefs.getBoolean(Keys.enableTransitions, true)
 | 
			
		||||
 | 
			
		||||
    fun doubleTapAnimSpeed() = rxPrefs.getInteger(Keys.doubleTapAnimationSpeed, 500)
 | 
			
		||||
    fun doubleTapAnimSpeed() = flowPrefs.getInt(Keys.doubleTapAnimationSpeed, 500)
 | 
			
		||||
 | 
			
		||||
    fun showPageNumber() = rxPrefs.getBoolean(Keys.showPageNumber, true)
 | 
			
		||||
    fun showPageNumber() = flowPrefs.getBoolean(Keys.showPageNumber, true)
 | 
			
		||||
 | 
			
		||||
    fun trueColor() = rxPrefs.getBoolean(Keys.trueColor, false)
 | 
			
		||||
    fun trueColor() = flowPrefs.getBoolean(Keys.trueColor, false)
 | 
			
		||||
 | 
			
		||||
    fun fullscreen() = rxPrefs.getBoolean(Keys.fullscreen, true)
 | 
			
		||||
    fun fullscreen() = flowPrefs.getBoolean(Keys.fullscreen, true)
 | 
			
		||||
 | 
			
		||||
    fun cutoutShort() = rxPrefs.getBoolean(Keys.cutoutShort, true)
 | 
			
		||||
    fun cutoutShort() = flowPrefs.getBoolean(Keys.cutoutShort, true)
 | 
			
		||||
 | 
			
		||||
    fun keepScreenOn() = rxPrefs.getBoolean(Keys.keepScreenOn, true)
 | 
			
		||||
    fun keepScreenOn() = flowPrefs.getBoolean(Keys.keepScreenOn, true)
 | 
			
		||||
 | 
			
		||||
    fun customBrightness() = rxPrefs.getBoolean(Keys.customBrightness, false)
 | 
			
		||||
    fun customBrightness() = flowPrefs.getBoolean(Keys.customBrightness, false)
 | 
			
		||||
 | 
			
		||||
    fun customBrightnessValue() = rxPrefs.getInteger(Keys.customBrightnessValue, 0)
 | 
			
		||||
    fun customBrightnessValue() = flowPrefs.getInt(Keys.customBrightnessValue, 0)
 | 
			
		||||
 | 
			
		||||
    fun colorFilter() = rxPrefs.getBoolean(Keys.colorFilter, false)
 | 
			
		||||
    fun colorFilter() = flowPrefs.getBoolean(Keys.colorFilter, false)
 | 
			
		||||
 | 
			
		||||
    fun colorFilterValue() = rxPrefs.getInteger(Keys.colorFilterValue, 0)
 | 
			
		||||
    fun colorFilterValue() = flowPrefs.getInt(Keys.colorFilterValue, 0)
 | 
			
		||||
 | 
			
		||||
    fun colorFilterMode() = rxPrefs.getInteger(Keys.colorFilterMode, 0)
 | 
			
		||||
    fun colorFilterMode() = flowPrefs.getInt(Keys.colorFilterMode, 0)
 | 
			
		||||
 | 
			
		||||
    fun defaultViewer() = prefs.getInt(Keys.defaultViewer, 1)
 | 
			
		||||
 | 
			
		||||
    fun imageScaleType() = rxPrefs.getInteger(Keys.imageScaleType, 1)
 | 
			
		||||
    fun imageScaleType() = flowPrefs.getInt(Keys.imageScaleType, 1)
 | 
			
		||||
 | 
			
		||||
    fun zoomStart() = rxPrefs.getInteger(Keys.zoomStart, 1)
 | 
			
		||||
    fun zoomStart() = flowPrefs.getInt(Keys.zoomStart, 1)
 | 
			
		||||
 | 
			
		||||
    fun readerTheme() = rxPrefs.getInteger(Keys.readerTheme, 1)
 | 
			
		||||
    fun readerTheme() = flowPrefs.getInt(Keys.readerTheme, 1)
 | 
			
		||||
 | 
			
		||||
    fun cropBorders() = rxPrefs.getBoolean(Keys.cropBorders, false)
 | 
			
		||||
    fun alwaysShowChapterTransition() = flowPrefs.getBoolean(Keys.alwaysShowChapterTransition, true)
 | 
			
		||||
 | 
			
		||||
    fun cropBordersWebtoon() = rxPrefs.getBoolean(Keys.cropBordersWebtoon, false)
 | 
			
		||||
    fun cropBorders() = flowPrefs.getBoolean(Keys.cropBorders, false)
 | 
			
		||||
 | 
			
		||||
    fun webtoonSidePadding() = rxPrefs.getInteger(Keys.webtoonSidePadding, 0)
 | 
			
		||||
    fun cropBordersWebtoon() = flowPrefs.getBoolean(Keys.cropBordersWebtoon, false)
 | 
			
		||||
 | 
			
		||||
    fun readWithTapping() = rxPrefs.getBoolean(Keys.readWithTapping, true)
 | 
			
		||||
    fun webtoonSidePadding() = flowPrefs.getInt(Keys.webtoonSidePadding, 0)
 | 
			
		||||
 | 
			
		||||
    fun readWithLongTap() = rxPrefs.getBoolean(Keys.readWithLongTap, true)
 | 
			
		||||
    fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
 | 
			
		||||
 | 
			
		||||
    fun readWithVolumeKeys() = rxPrefs.getBoolean(Keys.readWithVolumeKeys, false)
 | 
			
		||||
    fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true)
 | 
			
		||||
 | 
			
		||||
    fun readWithVolumeKeysInverted() = rxPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
 | 
			
		||||
    fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false)
 | 
			
		||||
 | 
			
		||||
    fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
 | 
			
		||||
 | 
			
		||||
    fun portraitColumns() = rxPrefs.getInteger(Keys.portraitColumns, 0)
 | 
			
		||||
 | 
			
		||||
@@ -132,13 +134,13 @@ class PreferencesHelper(val context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun lastUsedCatalogueSource() = rxPrefs.getLong(Keys.lastUsedCatalogueSource, -1)
 | 
			
		||||
 | 
			
		||||
    fun lastUsedCategory() = rxPrefs.getInteger(Keys.lastUsedCategory, 0)
 | 
			
		||||
    fun lastUsedCategory() = flowPrefs.getInt(Keys.lastUsedCategory, 0)
 | 
			
		||||
 | 
			
		||||
    fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0)
 | 
			
		||||
 | 
			
		||||
    fun catalogueAsList() = rxPrefs.getBoolean(Keys.catalogueAsList, false)
 | 
			
		||||
 | 
			
		||||
    fun enabledLanguages() = rxPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language))
 | 
			
		||||
    fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language))
 | 
			
		||||
 | 
			
		||||
    fun trackUsername(sync: TrackService) = prefs.getString(Keys.trackUsername(sync.id), "")
 | 
			
		||||
 | 
			
		||||
@@ -203,9 +205,9 @@ class PreferencesHelper(val context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun lastExtCheck() = flowPrefs.getLong("last_ext_check", 0)
 | 
			
		||||
 | 
			
		||||
    fun hiddenCatalogues() = rxPrefs.getStringSet("hidden_catalogues", emptySet())
 | 
			
		||||
    fun hiddenCatalogues() = flowPrefs.getStringSet("hidden_catalogues", emptySet())
 | 
			
		||||
 | 
			
		||||
    fun pinnedCatalogues() = rxPrefs.getStringSet("pinned_catalogues", emptySet())
 | 
			
		||||
    fun pinnedCatalogues() = flowPrefs.getStringSet("pinned_catalogues", emptySet())
 | 
			
		||||
 | 
			
		||||
    fun downloadNew() = rxPrefs.getBoolean(Keys.downloadNew, false)
 | 
			
		||||
 | 
			
		||||
@@ -222,6 +224,4 @@ class PreferencesHelper(val context: Context) {
 | 
			
		||||
    fun migrateFlags() = flowPrefs.getInt("migrate_flags", Int.MAX_VALUE)
 | 
			
		||||
 | 
			
		||||
    fun trustedSignatures() = flowPrefs.getStringSet("trusted_signatures", emptySet())
 | 
			
		||||
 | 
			
		||||
    fun alwaysShowChapterTransition() = rxPrefs.getBoolean(Keys.alwaysShowChapterTransition, true)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import android.content.res.Configuration
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import androidx.lifecycle.lifecycleScope
 | 
			
		||||
import androidx.viewbinding.ViewBinding
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
 | 
			
		||||
@@ -16,6 +17,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
    val preferences: PreferencesHelper by injectLazy()
 | 
			
		||||
 | 
			
		||||
    val scope = lifecycleScope
 | 
			
		||||
    lateinit var binding: VB
 | 
			
		||||
 | 
			
		||||
    @Suppress("LeakingThis")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.base.activity
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import androidx.lifecycle.lifecycleScope
 | 
			
		||||
import androidx.viewbinding.ViewBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
 | 
			
		||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
 | 
			
		||||
@@ -12,6 +13,7 @@ abstract class BaseRxActivity<VB : ViewBinding, P : BasePresenter<*>> : NucleusA
 | 
			
		||||
    @Suppress("LeakingThis")
 | 
			
		||||
    private val secureActivityDelegate = SecureActivityDelegate(this)
 | 
			
		||||
 | 
			
		||||
    val scope = lifecycleScope
 | 
			
		||||
    lateinit var binding: VB
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,9 @@ import android.os.Bundle
 | 
			
		||||
import androidx.viewbinding.ViewBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.presenter.NucleusConductorDelegate
 | 
			
		||||
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.presenter.Presenter
 | 
			
		||||
 | 
			
		||||
@@ -14,6 +17,8 @@ abstract class NucleusController<VB : ViewBinding, P : Presenter<*>>(val bundle:
 | 
			
		||||
 | 
			
		||||
    private val delegate = NucleusConductorDelegate(this)
 | 
			
		||||
 | 
			
		||||
    val scope = CoroutineScope(Job() + Dispatchers.Main)
 | 
			
		||||
 | 
			
		||||
    val presenter: P
 | 
			
		||||
        get() = delegate.presenter!!
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,8 @@ import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Category
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import reactivecircus.flowbinding.android.view.clicks
 | 
			
		||||
 | 
			
		||||
@@ -91,7 +91,7 @@ class CategoryController : NucleusController<CategoriesControllerBinding, Catego
 | 
			
		||||
            .onEach {
 | 
			
		||||
                CategoryCreateDialog(this@CategoryController).showDialog(router, null)
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -21,8 +21,8 @@ import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
 | 
			
		||||
import eu.kanade.tachiyomi.extension.model.Extension
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
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
 | 
			
		||||
@@ -72,7 +72,7 @@ open class ExtensionController : NucleusController<ExtensionControllerBinding, E
 | 
			
		||||
        binding.extSwipeRefresh.isRefreshing = true
 | 
			
		||||
        binding.extSwipeRefresh.refreshes()
 | 
			
		||||
            .onEach { presenter.findAvailableExtensions() }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        // Initialize adapter, scroll listener and recycler views
 | 
			
		||||
        adapter = ExtensionAdapter(this)
 | 
			
		||||
@@ -151,7 +151,7 @@ open class ExtensionController : NucleusController<ExtensionControllerBinding, E
 | 
			
		||||
                query = it.toString()
 | 
			
		||||
                drawExtensions()
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        // Fixes problem with the overflow icon showing up in lieu of search
 | 
			
		||||
        searchItem.fixExpand(onExpand = { invalidateMenuOnExpand() })
 | 
			
		||||
 
 | 
			
		||||
@@ -29,10 +29,10 @@ import eu.kanade.tachiyomi.databinding.ExtensionDetailControllerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.source.ConfigurableSource
 | 
			
		||||
import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.preferenceCategory
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.visible
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import reactivecircus.flowbinding.android.view.clicks
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +78,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
 | 
			
		||||
        extension.getApplicationIcon(context)?.let { binding.extensionIcon.setImageDrawable(it) }
 | 
			
		||||
        binding.extensionUninstallButton.clicks()
 | 
			
		||||
            .onEach { presenter.uninstallExtension() }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        if (extension.isObsolete) {
 | 
			
		||||
            binding.extensionObsolete.visible()
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.extension
 | 
			
		||||
 | 
			
		||||
import androidx.preference.PreferenceScreen
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.extension.ExtensionManager
 | 
			
		||||
import eu.kanade.tachiyomi.ui.setting.SettingsController
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.onChange
 | 
			
		||||
@@ -17,7 +16,7 @@ class ExtensionFilterController : SettingsController() {
 | 
			
		||||
    override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
 | 
			
		||||
        titleRes = R.string.action_filter
 | 
			
		||||
 | 
			
		||||
        val activeLangs = preferences.enabledLanguages().getOrDefault()
 | 
			
		||||
        val activeLangs = preferences.enabledLanguages().get()
 | 
			
		||||
 | 
			
		||||
        val availableLangs =
 | 
			
		||||
                Injekt.get<ExtensionManager>().availableExtensions.groupBy {
 | 
			
		||||
@@ -37,7 +36,7 @@ class ExtensionFilterController : SettingsController() {
 | 
			
		||||
 | 
			
		||||
                onChange { newValue ->
 | 
			
		||||
                    val checked = newValue as Boolean
 | 
			
		||||
                    val currentActiveLangs = preferences.enabledLanguages().getOrDefault()
 | 
			
		||||
                    val currentActiveLangs = preferences.enabledLanguages().get()
 | 
			
		||||
 | 
			
		||||
                    if (checked) {
 | 
			
		||||
                        preferences.enabledLanguages().set(currentActiveLangs + it)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ import android.app.Application
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.extension.ExtensionManager
 | 
			
		||||
import eu.kanade.tachiyomi.extension.model.Extension
 | 
			
		||||
import eu.kanade.tachiyomi.extension.model.InstallStep
 | 
			
		||||
@@ -55,7 +54,7 @@ open class ExtensionPresenter(
 | 
			
		||||
    @Synchronized
 | 
			
		||||
    private fun toItems(tuple: ExtensionTuple): List<ExtensionItem> {
 | 
			
		||||
        val context = Injekt.get<Application>()
 | 
			
		||||
        val activeLangs = preferences.enabledLanguages().getOrDefault()
 | 
			
		||||
        val activeLangs = preferences.enabledLanguages().get()
 | 
			
		||||
 | 
			
		||||
        val (installed, untrusted, available) = tuple
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,6 @@ import eu.kanade.tachiyomi.data.database.models.Category
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.LibraryControllerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.RootController
 | 
			
		||||
@@ -34,12 +33,12 @@ import eu.kanade.tachiyomi.ui.base.controller.TabbedController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 | 
			
		||||
import eu.kanade.tachiyomi.ui.main.MainActivity
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.MangaController
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.getResourceColor
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import java.io.IOException
 | 
			
		||||
import kotlinx.android.synthetic.main.main_activity.tabs
 | 
			
		||||
import kotlinx.coroutines.flow.filter
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import reactivecircus.flowbinding.appcompat.queryTextChanges
 | 
			
		||||
import reactivecircus.flowbinding.viewpager.pageSelections
 | 
			
		||||
@@ -61,8 +60,7 @@ class LibraryController(
 | 
			
		||||
    /**
 | 
			
		||||
     * Position of the active category.
 | 
			
		||||
     */
 | 
			
		||||
    var activeCategory: Int = preferences.lastUsedCategory().getOrDefault()
 | 
			
		||||
        private set
 | 
			
		||||
    private var activeCategory: Int = preferences.lastUsedCategory().get()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Action mode for selections.
 | 
			
		||||
@@ -154,7 +152,7 @@ class LibraryController(
 | 
			
		||||
                preferences.lastUsedCategory().set(it)
 | 
			
		||||
                activeCategory = it
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        getColumnsPreferenceForCurrentOrientation().asObservable()
 | 
			
		||||
                .doOnNext { mangaPerRow = it }
 | 
			
		||||
@@ -334,7 +332,7 @@ class LibraryController(
 | 
			
		||||
                query = it.toString()
 | 
			
		||||
                searchRelay.call(query)
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        if (query.isNotEmpty()) {
 | 
			
		||||
            searchItem.expandActionView()
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ import android.content.Intent
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.ViewGroup
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import androidx.lifecycle.lifecycleScope
 | 
			
		||||
import com.bluelinelabs.conductor.Conductor
 | 
			
		||||
import com.bluelinelabs.conductor.Controller
 | 
			
		||||
import com.bluelinelabs.conductor.ControllerChangeHandler
 | 
			
		||||
@@ -157,7 +156,7 @@ class MainActivity : BaseActivity<MainActivityBinding>() {
 | 
			
		||||
        setExtensionsBadge()
 | 
			
		||||
        preferences.extensionUpdatesCount().asFlow()
 | 
			
		||||
            .onEach { setExtensionsBadge() }
 | 
			
		||||
            .launchIn(lifecycleScope)
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onNewIntent(intent: Intent) {
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,6 @@ import eu.kanade.tachiyomi.databinding.ChaptersControllerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.MangaController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.getResourceColor
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.getCoordinates
 | 
			
		||||
@@ -34,6 +33,7 @@ import eu.kanade.tachiyomi.util.view.gone
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.shrinkOnScroll
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.snack
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.visible
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import reactivecircus.flowbinding.android.view.clicks
 | 
			
		||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
 | 
			
		||||
@@ -92,7 +92,7 @@ class ChaptersController : NucleusController<ChaptersControllerBinding, Chapters
 | 
			
		||||
 | 
			
		||||
        binding.swipeRefresh.refreshes()
 | 
			
		||||
            .onEach { fetchChaptersFromSource() }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.fab.clicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
@@ -114,7 +114,7 @@ class ChaptersController : NucleusController<ChaptersControllerBinding, Chapters
 | 
			
		||||
                    view.context.toast(R.string.no_next_chapter)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.fab.shrinkOnScroll(binding.recycler)
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,13 +34,13 @@ import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.truncateCenter
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.gone
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.snack
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.toggle
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.visible
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import reactivecircus.flowbinding.android.view.clicks
 | 
			
		||||
import reactivecircus.flowbinding.android.view.longClicks
 | 
			
		||||
@@ -80,12 +80,12 @@ class MangaInfoController(private val fromSource: Boolean = false) :
 | 
			
		||||
        // Set onclickListener to toggle favorite when favorite button clicked.
 | 
			
		||||
        binding.btnFavorite.clicks()
 | 
			
		||||
            .onEach { onFavoriteClick() }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        // Set onLongClickListener to manage categories when favorite button is clicked.
 | 
			
		||||
        binding.btnFavorite.longClicks()
 | 
			
		||||
            .onEach { onFavoriteLongClick() }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        if (presenter.source is HttpSource) {
 | 
			
		||||
            binding.btnWebview.visible()
 | 
			
		||||
@@ -93,64 +93,64 @@ class MangaInfoController(private val fromSource: Boolean = false) :
 | 
			
		||||
 | 
			
		||||
            binding.btnWebview.clicks()
 | 
			
		||||
                .onEach { openInWebView() }
 | 
			
		||||
                .launchInUI()
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
            binding.btnShare.clicks()
 | 
			
		||||
                .onEach { shareManga() }
 | 
			
		||||
                .launchInUI()
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set SwipeRefresh to refresh manga data.
 | 
			
		||||
        binding.swipeRefresh.refreshes()
 | 
			
		||||
            .onEach { fetchMangaFromSource() }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaFullTitle.longClicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                copyToClipboard(view.context.getString(R.string.title), binding.mangaFullTitle.text.toString())
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaFullTitle.clicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                performGlobalSearch(binding.mangaFullTitle.text.toString())
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaArtist.longClicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                copyToClipboard(binding.mangaArtistLabel.text.toString(), binding.mangaArtist.text.toString())
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaArtist.clicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                performGlobalSearch(binding.mangaArtist.text.toString())
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaAuthor.longClicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                copyToClipboard(binding.mangaAuthor.text.toString(), binding.mangaAuthor.text.toString())
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaAuthor.clicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                performGlobalSearch(binding.mangaAuthor.text.toString())
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaSummary.longClicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                copyToClipboard(view.context.getString(R.string.description), binding.mangaSummary.text.toString())
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.mangaCover.longClicks()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                copyToClipboard(view.context.getString(R.string.title), presenter.manga.title)
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -272,10 +272,10 @@ class MangaInfoController(private val fromSource: Boolean = false) :
 | 
			
		||||
            // Handle showing more or less info
 | 
			
		||||
            binding.mangaSummary.clicks()
 | 
			
		||||
                .onEach { toggleMangaInfo(view.context) }
 | 
			
		||||
                .launchInUI()
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
            binding.mangaInfoToggle.clicks()
 | 
			
		||||
                .onEach { toggleMangaInfo(view.context) }
 | 
			
		||||
                .launchInUI()
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
            // Expand manga info if navigated from source listing
 | 
			
		||||
            if (initialLoad && fromSource) {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,8 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.TrackControllerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.MangaController
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
@@ -50,7 +50,7 @@ class TrackController : NucleusController<TrackControllerBinding, TrackPresenter
 | 
			
		||||
        binding.swipeRefresh.isEnabled = false
 | 
			
		||||
        binding.swipeRefresh.refreshes()
 | 
			
		||||
            .onEach { presenter.refresh() }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroyView(view: View) {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.TrackService
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.invisible
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.visible
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
@@ -20,6 +19,7 @@ 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.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
 | 
			
		||||
@@ -78,7 +78,7 @@ class TrackSearchDialog : DialogController {
 | 
			
		||||
            .onEach { position ->
 | 
			
		||||
                selectedItem = adapter.getItem(position)
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(trackController.scope)
 | 
			
		||||
 | 
			
		||||
        // Do an initial search based on the manga's title
 | 
			
		||||
        if (savedState == null) {
 | 
			
		||||
@@ -101,7 +101,7 @@ class TrackSearchDialog : DialogController {
 | 
			
		||||
            .map { it.toString() }
 | 
			
		||||
            .filter { it.isNotBlank() }
 | 
			
		||||
            .onEach { search(it) }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(trackController.scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun search(query: String) {
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
 | 
			
		||||
import eu.kanade.tachiyomi.data.notification.Notifications
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.ReaderActivityBinding
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst
 | 
			
		||||
@@ -57,9 +56,12 @@ import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
import kotlin.math.abs
 | 
			
		||||
import kotlinx.coroutines.flow.drop
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import kotlinx.coroutines.flow.sample
 | 
			
		||||
import nucleus.factory.RequiresPresenter
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
@@ -125,7 +127,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
     * Called when the activity is created. Initializes the presenter and configuration.
 | 
			
		||||
     */
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        setTheme(when (preferences.readerTheme().getOrDefault()) {
 | 
			
		||||
        setTheme(when (preferences.readerTheme().get()) {
 | 
			
		||||
            0 -> R.style.Theme_Reader_Light
 | 
			
		||||
            else -> R.style.Theme_Reader
 | 
			
		||||
        })
 | 
			
		||||
@@ -317,7 +319,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
    private fun setMenuVisibility(visible: Boolean, animate: Boolean = true) {
 | 
			
		||||
        menuVisible = visible
 | 
			
		||||
        if (visible) {
 | 
			
		||||
            if (preferences.fullscreen().getOrDefault()) {
 | 
			
		||||
            if (preferences.fullscreen().get()) {
 | 
			
		||||
                window.showBar()
 | 
			
		||||
            } else {
 | 
			
		||||
                resetDefaultMenuAndBar()
 | 
			
		||||
@@ -338,11 +340,11 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
                binding.readerMenuBottom.startAnimation(bottomAnimation)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (preferences.showPageNumber().getOrDefault()) {
 | 
			
		||||
            if (preferences.showPageNumber().get()) {
 | 
			
		||||
                config?.setPageNumberVisibility(false)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (preferences.fullscreen().getOrDefault()) {
 | 
			
		||||
            if (preferences.fullscreen().get()) {
 | 
			
		||||
                window.hideBar()
 | 
			
		||||
            } else {
 | 
			
		||||
                resetDefaultMenuAndBar()
 | 
			
		||||
@@ -361,7 +363,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
                binding.readerMenuBottom.startAnimation(bottomAnimation)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (preferences.showPageNumber().getOrDefault()) {
 | 
			
		||||
            if (preferences.showPageNumber().get()) {
 | 
			
		||||
                config?.setPageNumberVisibility(true)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -605,16 +607,6 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
         */
 | 
			
		||||
        private val subscriptions = CompositeSubscription()
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Custom brightness subscription.
 | 
			
		||||
         */
 | 
			
		||||
        private var customBrightnessSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Custom color filter subscription.
 | 
			
		||||
         */
 | 
			
		||||
        private var customFilterColorSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Initializes the reader subscriptions.
 | 
			
		||||
         */
 | 
			
		||||
@@ -627,32 +619,40 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
            subscriptions += Observable.merge(initialRotation, rotationUpdates)
 | 
			
		||||
                    .subscribe { setOrientation(it) }
 | 
			
		||||
 | 
			
		||||
            subscriptions += preferences.readerTheme().asObservable()
 | 
			
		||||
                    .skip(1) // We only care about updates
 | 
			
		||||
                    .subscribe { recreate() }
 | 
			
		||||
            preferences.readerTheme().asFlow()
 | 
			
		||||
                .drop(1) // We only care about updates
 | 
			
		||||
                .onEach { recreate() }
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
            subscriptions += preferences.showPageNumber().asObservable()
 | 
			
		||||
                    .subscribe { setPageNumberVisibility(it) }
 | 
			
		||||
            preferences.showPageNumber().asFlow()
 | 
			
		||||
                .onEach { setPageNumberVisibility(it) }
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
            subscriptions += preferences.trueColor().asObservable()
 | 
			
		||||
                    .subscribe { setTrueColor(it) }
 | 
			
		||||
            preferences.trueColor().asFlow()
 | 
			
		||||
                .onEach { setTrueColor(it) }
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
 | 
			
		||||
                subscriptions += preferences.cutoutShort().asObservable()
 | 
			
		||||
                        .subscribe { setCutoutShort(it) }
 | 
			
		||||
                preferences.cutoutShort().asFlow()
 | 
			
		||||
                    .onEach { setCutoutShort(it) }
 | 
			
		||||
                    .launchIn(scope)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            subscriptions += preferences.keepScreenOn().asObservable()
 | 
			
		||||
                    .subscribe { setKeepScreenOn(it) }
 | 
			
		||||
            preferences.keepScreenOn().asFlow()
 | 
			
		||||
                .onEach { setKeepScreenOn(it) }
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
            subscriptions += preferences.customBrightness().asObservable()
 | 
			
		||||
                    .subscribe { setCustomBrightness(it) }
 | 
			
		||||
            preferences.customBrightness().asFlow()
 | 
			
		||||
                .onEach { setCustomBrightness(it) }
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
            subscriptions += preferences.colorFilter().asObservable()
 | 
			
		||||
                    .subscribe { setColorFilter(it) }
 | 
			
		||||
            preferences.colorFilter().asFlow()
 | 
			
		||||
                .onEach { setColorFilter(it) }
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
            subscriptions += preferences.colorFilterMode().asObservable()
 | 
			
		||||
                    .subscribe { setColorFilter(preferences.colorFilter().getOrDefault()) }
 | 
			
		||||
            preferences.colorFilterMode().asFlow()
 | 
			
		||||
                .onEach { setColorFilter(preferences.colorFilter().get()) }
 | 
			
		||||
                .launchIn(scope)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -660,8 +660,6 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
         */
 | 
			
		||||
        fun destroy() {
 | 
			
		||||
            subscriptions.unsubscribe()
 | 
			
		||||
            customBrightnessSubscription = null
 | 
			
		||||
            customFilterColorSubscription = null
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -732,13 +730,11 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
         */
 | 
			
		||||
        private fun setCustomBrightness(enabled: Boolean) {
 | 
			
		||||
            if (enabled) {
 | 
			
		||||
                customBrightnessSubscription = preferences.customBrightnessValue().asObservable()
 | 
			
		||||
                        .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                        .subscribe { setCustomBrightnessValue(it) }
 | 
			
		||||
 | 
			
		||||
                subscriptions.add(customBrightnessSubscription)
 | 
			
		||||
                preferences.customBrightnessValue().asFlow()
 | 
			
		||||
                    .sample(100)
 | 
			
		||||
                    .onEach { setCustomBrightnessValue(it) }
 | 
			
		||||
                    .launchIn(scope)
 | 
			
		||||
            } else {
 | 
			
		||||
                customBrightnessSubscription?.let { subscriptions.remove(it) }
 | 
			
		||||
                setCustomBrightnessValue(0)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -748,13 +744,11 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
         */
 | 
			
		||||
        private fun setColorFilter(enabled: Boolean) {
 | 
			
		||||
            if (enabled) {
 | 
			
		||||
                customFilterColorSubscription = preferences.colorFilterValue().asObservable()
 | 
			
		||||
                        .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                        .subscribe { setColorFilterValue(it) }
 | 
			
		||||
 | 
			
		||||
                subscriptions.add(customFilterColorSubscription)
 | 
			
		||||
                preferences.colorFilterValue().asFlow()
 | 
			
		||||
                    .sample(100)
 | 
			
		||||
                    .onEach { setColorFilterValue(it) }
 | 
			
		||||
                    .launchIn(scope)
 | 
			
		||||
            } else {
 | 
			
		||||
                customFilterColorSubscription?.let { subscriptions.remove(it) }
 | 
			
		||||
                binding.colorOverlay.gone()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -794,7 +788,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
         */
 | 
			
		||||
        private fun setColorFilterValue(value: Int) {
 | 
			
		||||
            binding.colorOverlay.visible()
 | 
			
		||||
            binding.colorOverlay.setFilterColor(value, preferences.colorFilterMode().getOrDefault())
 | 
			
		||||
            binding.colorOverlay.setFilterColor(value, preferences.colorFilterMode().get())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,13 +9,10 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
 | 
			
		||||
import com.google.android.material.bottomsheet.BottomSheetDialog
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.plusAssign
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.gone
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.visible
 | 
			
		||||
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
 | 
			
		||||
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
import kotlin.math.abs
 | 
			
		||||
import kotlinx.android.synthetic.main.reader_color_filter.brightness_seekbar
 | 
			
		||||
import kotlinx.android.synthetic.main.reader_color_filter.color_filter_mode
 | 
			
		||||
@@ -32,54 +29,41 @@ import kotlinx.android.synthetic.main.reader_color_filter.txt_color_filter_green
 | 
			
		||||
import kotlinx.android.synthetic.main.reader_color_filter.txt_color_filter_red_value
 | 
			
		||||
import kotlinx.android.synthetic.main.reader_color_filter_sheet.brightness_overlay
 | 
			
		||||
import kotlinx.android.synthetic.main.reader_color_filter_sheet.color_overlay
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import kotlinx.coroutines.flow.sample
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Color filter sheet to toggle custom filter and brightness overlay.
 | 
			
		||||
 */
 | 
			
		||||
class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activity) {
 | 
			
		||||
class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheetDialog(activity) {
 | 
			
		||||
 | 
			
		||||
    private val preferences by injectLazy<PreferencesHelper>()
 | 
			
		||||
 | 
			
		||||
    private var sheetBehavior: BottomSheetBehavior<*>? = null
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscriptions used for this dialog
 | 
			
		||||
     */
 | 
			
		||||
    private val subscriptions = CompositeSubscription()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscription used for custom brightness overlay
 | 
			
		||||
     */
 | 
			
		||||
    private var customBrightnessSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscription used for color filter overlay
 | 
			
		||||
     */
 | 
			
		||||
    private var customFilterColorSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        val view = activity.layoutInflater.inflate(R.layout.reader_color_filter_sheet, null)
 | 
			
		||||
        setContentView(view)
 | 
			
		||||
 | 
			
		||||
        sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
 | 
			
		||||
 | 
			
		||||
        // Initialize subscriptions.
 | 
			
		||||
        subscriptions += preferences.colorFilter().asObservable()
 | 
			
		||||
                .subscribe { setColorFilter(it, view) }
 | 
			
		||||
        preferences.colorFilter().asFlow()
 | 
			
		||||
            .onEach { setColorFilter(it, view) }
 | 
			
		||||
            .launchIn(activity.scope)
 | 
			
		||||
 | 
			
		||||
        subscriptions += preferences.colorFilterMode().asObservable()
 | 
			
		||||
                .subscribe { setColorFilter(preferences.colorFilter().getOrDefault(), view) }
 | 
			
		||||
        preferences.colorFilterMode().asFlow()
 | 
			
		||||
            .onEach { setColorFilter(preferences.colorFilter().get(), view) }
 | 
			
		||||
            .launchIn(activity.scope)
 | 
			
		||||
 | 
			
		||||
        subscriptions += preferences.customBrightness().asObservable()
 | 
			
		||||
                .subscribe { setCustomBrightness(it, view) }
 | 
			
		||||
        preferences.customBrightness().asFlow()
 | 
			
		||||
            .onEach { setCustomBrightness(it, view) }
 | 
			
		||||
            .launchIn(activity.scope)
 | 
			
		||||
 | 
			
		||||
        // Get color and update values
 | 
			
		||||
        val color = preferences.colorFilterValue().getOrDefault()
 | 
			
		||||
        val brightness = preferences.customBrightnessValue().getOrDefault()
 | 
			
		||||
        val color = preferences.colorFilterValue().get()
 | 
			
		||||
        val brightness = preferences.customBrightnessValue().get()
 | 
			
		||||
 | 
			
		||||
        val argb = setValues(color, view)
 | 
			
		||||
 | 
			
		||||
@@ -94,12 +78,12 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
        seekbar_color_filter_blue.progress = argb[3]
 | 
			
		||||
 | 
			
		||||
        // Set listeners
 | 
			
		||||
        switch_color_filter.isChecked = preferences.colorFilter().getOrDefault()
 | 
			
		||||
        switch_color_filter.isChecked = preferences.colorFilter().get()
 | 
			
		||||
        switch_color_filter.setOnCheckedChangeListener { _, isChecked ->
 | 
			
		||||
            preferences.colorFilter().set(isChecked)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        custom_brightness.isChecked = preferences.customBrightness().getOrDefault()
 | 
			
		||||
        custom_brightness.isChecked = preferences.customBrightness().get()
 | 
			
		||||
        custom_brightness.setOnCheckedChangeListener { _, isChecked ->
 | 
			
		||||
            preferences.customBrightness().set(isChecked)
 | 
			
		||||
        }
 | 
			
		||||
@@ -107,7 +91,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
        color_filter_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
 | 
			
		||||
            preferences.colorFilterMode().set(position)
 | 
			
		||||
        }
 | 
			
		||||
        color_filter_mode.setSelection(preferences.colorFilterMode().getOrDefault(), false)
 | 
			
		||||
        color_filter_mode.setSelection(preferences.colorFilterMode().get(), false)
 | 
			
		||||
 | 
			
		||||
        seekbar_color_filter_alpha.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
@@ -156,13 +140,6 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
        sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDetachedFromWindow() {
 | 
			
		||||
        super.onDetachedFromWindow()
 | 
			
		||||
        subscriptions.unsubscribe()
 | 
			
		||||
        customBrightnessSubscription = null
 | 
			
		||||
        customFilterColorSubscription = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set enabled status of seekBars belonging to color filter
 | 
			
		||||
     * @param enabled determines if seekBar gets enabled
 | 
			
		||||
@@ -196,15 +173,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
        val blue = getBlueFromColor(color)
 | 
			
		||||
 | 
			
		||||
        // Initialize values
 | 
			
		||||
        with(view) {
 | 
			
		||||
            txt_color_filter_alpha_value.text = alpha.toString()
 | 
			
		||||
        txt_color_filter_alpha_value.text = alpha.toString()
 | 
			
		||||
        txt_color_filter_red_value.text = red.toString()
 | 
			
		||||
        txt_color_filter_green_value.text = green.toString()
 | 
			
		||||
        txt_color_filter_blue_value.text = blue.toString()
 | 
			
		||||
 | 
			
		||||
            txt_color_filter_red_value.text = red.toString()
 | 
			
		||||
 | 
			
		||||
            txt_color_filter_green_value.text = green.toString()
 | 
			
		||||
 | 
			
		||||
            txt_color_filter_blue_value.text = blue.toString()
 | 
			
		||||
        }
 | 
			
		||||
        return arrayOf(alpha, red, green, blue)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -215,13 +188,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
     */
 | 
			
		||||
    private fun setCustomBrightness(enabled: Boolean, view: View) {
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            customBrightnessSubscription = preferences.customBrightnessValue().asObservable()
 | 
			
		||||
                    .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                    .subscribe { setCustomBrightnessValue(it, view) }
 | 
			
		||||
 | 
			
		||||
            subscriptions.add(customBrightnessSubscription)
 | 
			
		||||
            preferences.customBrightnessValue().asFlow()
 | 
			
		||||
                .sample(100)
 | 
			
		||||
                .onEach { setCustomBrightnessValue(it, view) }
 | 
			
		||||
                .launchIn(activity.scope)
 | 
			
		||||
        } else {
 | 
			
		||||
            customBrightnessSubscription?.let { subscriptions.remove(it) }
 | 
			
		||||
            setCustomBrightnessValue(0, view, true)
 | 
			
		||||
        }
 | 
			
		||||
        setCustomBrightnessSeekBar(enabled, view)
 | 
			
		||||
@@ -254,13 +225,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
     */
 | 
			
		||||
    private fun setColorFilter(enabled: Boolean, view: View) {
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            customFilterColorSubscription = preferences.colorFilterValue().asObservable()
 | 
			
		||||
                    .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                    .subscribe { setColorFilterValue(it, view) }
 | 
			
		||||
 | 
			
		||||
            subscriptions.add(customFilterColorSubscription)
 | 
			
		||||
            preferences.colorFilterValue().asFlow()
 | 
			
		||||
                .sample(100)
 | 
			
		||||
                .onEach { setColorFilterValue(it, view) }
 | 
			
		||||
                .launchIn(activity.scope)
 | 
			
		||||
        } else {
 | 
			
		||||
            customFilterColorSubscription?.let { subscriptions.remove(it) }
 | 
			
		||||
            color_overlay.gone()
 | 
			
		||||
        }
 | 
			
		||||
        setColorFilterSeekBar(enabled, view)
 | 
			
		||||
@@ -273,7 +242,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
     */
 | 
			
		||||
    private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) {
 | 
			
		||||
        color_overlay.visible()
 | 
			
		||||
        color_overlay.setFilterColor(color, preferences.colorFilterMode().getOrDefault())
 | 
			
		||||
        color_overlay.setFilterColor(color, preferences.colorFilterMode().get())
 | 
			
		||||
        setValues(color, view)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -284,7 +253,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
 | 
			
		||||
     * @param bitShift amounts of bits that gets shifted to receive value
 | 
			
		||||
     */
 | 
			
		||||
    fun setColorValue(color: Int, mask: Long, bitShift: Int) {
 | 
			
		||||
        val currentColor = preferences.colorFilterValue().getOrDefault()
 | 
			
		||||
        val currentColor = preferences.colorFilterValue().get()
 | 
			
		||||
        val updatedColor = (color shl bitShift) or (currentColor and mask.inv().toInt())
 | 
			
		||||
        preferences.colorFilterValue().set(updatedColor)
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,9 @@ import android.widget.CompoundButton
 | 
			
		||||
import android.widget.Spinner
 | 
			
		||||
import androidx.annotation.ArrayRes
 | 
			
		||||
import androidx.core.widget.NestedScrollView
 | 
			
		||||
import com.f2prateek.rx.preferences.Preference
 | 
			
		||||
import com.f2prateek.rx.preferences.Preference as RxPreference
 | 
			
		||||
import com.google.android.material.bottomsheet.BottomSheetDialog
 | 
			
		||||
import com.tfcporciuncula.flow.Preference
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
@@ -121,10 +122,20 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia
 | 
			
		||||
     * Binds a checkbox or switch view with a boolean preference.
 | 
			
		||||
     */
 | 
			
		||||
    private fun CompoundButton.bindToPreference(pref: Preference<Boolean>) {
 | 
			
		||||
        isChecked = pref.getOrDefault()
 | 
			
		||||
        isChecked = pref.get()
 | 
			
		||||
        setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Binds a spinner to an int preference with an optional offset for the value.
 | 
			
		||||
     */
 | 
			
		||||
    private fun Spinner.bindToPreference(pref: RxPreference<Int>, offset: Int = 0) {
 | 
			
		||||
        onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
 | 
			
		||||
            pref.set(position + offset)
 | 
			
		||||
        }
 | 
			
		||||
        setSelection(pref.getOrDefault() - offset, false)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Binds a spinner to an int preference with an optional offset for the value.
 | 
			
		||||
     */
 | 
			
		||||
@@ -132,7 +143,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia
 | 
			
		||||
        onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
 | 
			
		||||
            pref.set(position + offset)
 | 
			
		||||
        }
 | 
			
		||||
        setSelection(pref.getOrDefault() - offset, false)
 | 
			
		||||
        setSelection(pref.get() - offset, false)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -143,8 +154,8 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDia
 | 
			
		||||
    private fun Spinner.bindToIntPreference(pref: Preference<Int>, @ArrayRes intValuesResource: Int) {
 | 
			
		||||
        val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
 | 
			
		||||
        onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
 | 
			
		||||
            pref.set(intValues[position])
 | 
			
		||||
            pref.set(intValues[position]!!)
 | 
			
		||||
        }
 | 
			
		||||
        setSelection(intValues.indexOf(pref.getOrDefault()), false)
 | 
			
		||||
        setSelection(intValues.indexOf(pref.get()), false)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,20 +2,24 @@ package eu.kanade.tachiyomi.ui.reader.viewer
 | 
			
		||||
 | 
			
		||||
import com.tfcporciuncula.flow.Preference
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.addTo
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import kotlinx.coroutines.flow.distinctUntilChanged
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Common configuration for all viewers.
 | 
			
		||||
 */
 | 
			
		||||
abstract class ViewerConfig(preferences: PreferencesHelper) {
 | 
			
		||||
 | 
			
		||||
    private val subscriptions = CompositeSubscription()
 | 
			
		||||
    private val scope = CoroutineScope(Job() + Dispatchers.Main)
 | 
			
		||||
 | 
			
		||||
    var imagePropertyChangedListener: (() -> Unit)? = null
 | 
			
		||||
 | 
			
		||||
    var tappingEnabled = true
 | 
			
		||||
    var longTapEnabled = true
 | 
			
		||||
    var doubleTapAnimDuration = 500
 | 
			
		||||
    var volumeKeysEnabled = false
 | 
			
		||||
    var volumeKeysInverted = false
 | 
			
		||||
    var alwaysShowChapterTransition = true
 | 
			
		||||
@@ -27,6 +31,9 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
 | 
			
		||||
        preferences.readWithLongTap()
 | 
			
		||||
            .register({ longTapEnabled = it })
 | 
			
		||||
 | 
			
		||||
        preferences.doubleTapAnimSpeed()
 | 
			
		||||
            .register({ doubleTapAnimDuration = it })
 | 
			
		||||
 | 
			
		||||
        preferences.readWithVolumeKeys()
 | 
			
		||||
            .register({ volumeKeysEnabled = it })
 | 
			
		||||
 | 
			
		||||
@@ -37,31 +44,15 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
 | 
			
		||||
            .register({ alwaysShowChapterTransition = it })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun unsubscribe() {
 | 
			
		||||
        subscriptions.unsubscribe()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun <T> com.f2prateek.rx.preferences.Preference<T>.register(
 | 
			
		||||
        valueAssignment: (T) -> Unit,
 | 
			
		||||
        onChanged: (T) -> Unit = {}
 | 
			
		||||
    ) {
 | 
			
		||||
        asObservable()
 | 
			
		||||
            .doOnNext(valueAssignment)
 | 
			
		||||
            .skip(1)
 | 
			
		||||
            .distinctUntilChanged()
 | 
			
		||||
            .doOnNext(onChanged)
 | 
			
		||||
            .subscribe()
 | 
			
		||||
            .addTo(subscriptions)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun <T> Preference<T>.register(
 | 
			
		||||
        valueAssignment: (T) -> Unit,
 | 
			
		||||
        onChanged: (T) -> Unit = {}
 | 
			
		||||
    ) {
 | 
			
		||||
        asFlow()
 | 
			
		||||
            .onEach { valueAssignment(it) }
 | 
			
		||||
            .distinctUntilChanged()
 | 
			
		||||
            .onEach { onChanged(it) }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .onEach {
 | 
			
		||||
                valueAssignment(it)
 | 
			
		||||
                onChanged(it)
 | 
			
		||||
            }
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,24 +23,18 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
 | 
			
		||||
    var imageCropBorders = false
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    var doubleTapAnimDuration = 500
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        preferences.pageTransitions()
 | 
			
		||||
                .register({ usePageTransitions = it })
 | 
			
		||||
            .register({ usePageTransitions = it })
 | 
			
		||||
 | 
			
		||||
        preferences.imageScaleType()
 | 
			
		||||
                .register({ imageScaleType = it }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
            .register({ imageScaleType = it }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
 | 
			
		||||
        preferences.zoomStart()
 | 
			
		||||
                .register({ zoomTypeFromPreference(it) }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
            .register({ zoomTypeFromPreference(it) }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
 | 
			
		||||
        preferences.cropBorders()
 | 
			
		||||
                .register({ imageCropBorders = it }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
 | 
			
		||||
        preferences.doubleTapAnimSpeed()
 | 
			
		||||
                .register({ doubleTapAnimDuration = it })
 | 
			
		||||
            .register({ imageCropBorders = it }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun zoomTypeFromPreference(value: Int) {
 | 
			
		||||
 
 | 
			
		||||
@@ -115,14 +115,6 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
 | 
			
		||||
        return pager
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Destroys this viewer. Called when leaving the reader or swapping viewers.
 | 
			
		||||
     */
 | 
			
		||||
    override fun destroy() {
 | 
			
		||||
        super.destroy()
 | 
			
		||||
        config.unsubscribe()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called when a new page (either a [ReaderPage] or [ChapterTransition]) is marked as active
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -13,34 +13,13 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfi
 | 
			
		||||
    var imageCropBorders = false
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    var doubleTapAnimDuration = 500
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    var sidePadding = 0
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        preferences.readWithTapping()
 | 
			
		||||
            .register({ tappingEnabled = it })
 | 
			
		||||
 | 
			
		||||
        preferences.readWithLongTap()
 | 
			
		||||
            .register({ longTapEnabled = it })
 | 
			
		||||
 | 
			
		||||
        preferences.cropBordersWebtoon()
 | 
			
		||||
            .register({ imageCropBorders = it }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
 | 
			
		||||
        preferences.doubleTapAnimSpeed()
 | 
			
		||||
            .register({ doubleTapAnimDuration = it })
 | 
			
		||||
 | 
			
		||||
        preferences.readWithVolumeKeys()
 | 
			
		||||
            .register({ volumeKeysEnabled = it })
 | 
			
		||||
 | 
			
		||||
        preferences.readWithVolumeKeysInverted()
 | 
			
		||||
            .register({ volumeKeysInverted = it })
 | 
			
		||||
 | 
			
		||||
        preferences.alwaysShowChapterTransition()
 | 
			
		||||
            .register({ alwaysShowChapterTransition = it })
 | 
			
		||||
 | 
			
		||||
        preferences.webtoonSidePadding()
 | 
			
		||||
            .register({ sidePadding = it }, { imagePropertyChangedListener?.invoke() })
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -155,7 +155,6 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
 | 
			
		||||
     */
 | 
			
		||||
    override fun destroy() {
 | 
			
		||||
        super.destroy()
 | 
			
		||||
        config.unsubscribe()
 | 
			
		||||
        subscriptions.unsubscribe()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,9 @@ import eu.kanade.tachiyomi.ui.base.controller.RootController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.MangaController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.notificationManager
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import reactivecircus.flowbinding.recyclerview.scrollStateChanges
 | 
			
		||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
 | 
			
		||||
@@ -97,7 +97,7 @@ class UpdatesController : NucleusController<UpdatesControllerBinding, UpdatesPre
 | 
			
		||||
                val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
 | 
			
		||||
                binding.swipeRefresh.isEnabled = firstPos <= 0
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
 | 
			
		||||
        binding.swipeRefresh.refreshes()
 | 
			
		||||
@@ -107,7 +107,7 @@ class UpdatesController : NucleusController<UpdatesControllerBinding, UpdatesPre
 | 
			
		||||
                // It can be a very long operation, so we disable swipe refresh and show a toast.
 | 
			
		||||
                binding.swipeRefresh.isRefreshing = false
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroyView(view: View) {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,9 @@ import com.bluelinelabs.conductor.ControllerChangeType
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
@@ -24,6 +27,7 @@ import uy.kohesive.injekt.api.get
 | 
			
		||||
abstract class SettingsController : PreferenceController() {
 | 
			
		||||
 | 
			
		||||
    val preferences: PreferencesHelper = Injekt.get()
 | 
			
		||||
    val scope = CoroutineScope(Job() + Dispatchers.Main)
 | 
			
		||||
 | 
			
		||||
    var untilDestroySubscriptions = CompositeSubscription()
 | 
			
		||||
        private set
 | 
			
		||||
@@ -78,10 +82,6 @@ abstract class SettingsController : PreferenceController() {
 | 
			
		||||
        super.onChangeStarted(handler, type)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun <T> Observable<T>.subscribeUntilDestroy(): Subscription {
 | 
			
		||||
        return subscribe().also { untilDestroySubscriptions.add(it) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun <T> Observable<T>.subscribeUntilDestroy(onNext: (T) -> Unit): Subscription {
 | 
			
		||||
        return subscribe(onNext).also { untilDestroySubscriptions.add(it) }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ import androidx.preference.PreferenceScreen
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.defaultValue
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.entriesRes
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.intListPreference
 | 
			
		||||
@@ -19,6 +18,7 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.switchPreference
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.titleRes
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
 | 
			
		||||
class SettingsGeneralController : SettingsController() {
 | 
			
		||||
@@ -147,7 +147,7 @@ class SettingsGeneralController : SettingsController() {
 | 
			
		||||
                isVisible = preferences.themeMode().get() != Values.THEME_MODE_DARK
 | 
			
		||||
                preferences.themeMode().asFlow()
 | 
			
		||||
                    .onEach { isVisible = it != Values.THEME_MODE_DARK }
 | 
			
		||||
                    .launchInUI()
 | 
			
		||||
                    .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
                onChange {
 | 
			
		||||
                    if (preferences.themeMode().get() != Values.THEME_MODE_DARK) {
 | 
			
		||||
@@ -173,7 +173,7 @@ class SettingsGeneralController : SettingsController() {
 | 
			
		||||
                isVisible = preferences.themeMode().get() != Values.THEME_MODE_LIGHT
 | 
			
		||||
                preferences.themeMode().asFlow()
 | 
			
		||||
                    .onEach { isVisible = it != Values.THEME_MODE_LIGHT }
 | 
			
		||||
                    .launchInUI()
 | 
			
		||||
                    .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
                onChange {
 | 
			
		||||
                    if (preferences.themeMode().get() != Values.THEME_MODE_LIGHT) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,12 +4,12 @@ import androidx.biometric.BiometricManager
 | 
			
		||||
import androidx.preference.PreferenceScreen
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.defaultValue
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.intListPreference
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.summaryRes
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.switchPreference
 | 
			
		||||
import eu.kanade.tachiyomi.util.preference.titleRes
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
 | 
			
		||||
class SettingsSecurityController : SettingsController() {
 | 
			
		||||
@@ -41,7 +41,7 @@ class SettingsSecurityController : SettingsController() {
 | 
			
		||||
                isVisible = preferences.useBiometricLock().get()
 | 
			
		||||
                preferences.useBiometricLock().asFlow()
 | 
			
		||||
                    .onEach { isVisible = it }
 | 
			
		||||
                    .launchInUI()
 | 
			
		||||
                    .launchIn(scope)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ import androidx.preference.CheckBoxPreference
 | 
			
		||||
import androidx.preference.PreferenceGroup
 | 
			
		||||
import androidx.preference.PreferenceScreen
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.icon
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.HttpSource
 | 
			
		||||
@@ -25,7 +24,7 @@ class SettingsSourcesController : SettingsController() {
 | 
			
		||||
        titleRes = R.string.action_filter
 | 
			
		||||
 | 
			
		||||
        // Get the list of active language codes.
 | 
			
		||||
        val activeLangsCodes = preferences.enabledLanguages().getOrDefault()
 | 
			
		||||
        val activeLangsCodes = preferences.enabledLanguages().get()
 | 
			
		||||
 | 
			
		||||
        // Get a map of sources grouped by language.
 | 
			
		||||
        val sourcesByLang = onlineSources.groupByTo(TreeMap(), { it.lang })
 | 
			
		||||
@@ -49,7 +48,7 @@ class SettingsSourcesController : SettingsController() {
 | 
			
		||||
 | 
			
		||||
                onChange { newValue ->
 | 
			
		||||
                    val checked = newValue as Boolean
 | 
			
		||||
                    val current = preferences.enabledLanguages().getOrDefault()
 | 
			
		||||
                    val current = preferences.enabledLanguages().get()
 | 
			
		||||
                    if (!checked) {
 | 
			
		||||
                        preferences.enabledLanguages().set(current - lang)
 | 
			
		||||
                        removeAll()
 | 
			
		||||
@@ -73,7 +72,7 @@ class SettingsSourcesController : SettingsController() {
 | 
			
		||||
     * @param group the language category.
 | 
			
		||||
     */
 | 
			
		||||
    private fun addLanguageSources(group: PreferenceGroup, sources: List<HttpSource>) {
 | 
			
		||||
        val hiddenCatalogues = preferences.hiddenCatalogues().getOrDefault()
 | 
			
		||||
        val hiddenCatalogues = preferences.hiddenCatalogues().get()
 | 
			
		||||
 | 
			
		||||
        sources.forEach { source ->
 | 
			
		||||
            val sourcePreference = CheckBoxPreference(group.context).apply {
 | 
			
		||||
@@ -90,7 +89,7 @@ class SettingsSourcesController : SettingsController() {
 | 
			
		||||
 | 
			
		||||
                onChange { newValue ->
 | 
			
		||||
                    val checked = newValue as Boolean
 | 
			
		||||
                    val current = preferences.hiddenCatalogues().getOrDefault()
 | 
			
		||||
                    val current = preferences.hiddenCatalogues().get()
 | 
			
		||||
 | 
			
		||||
                    preferences.hiddenCatalogues().set(if (checked)
 | 
			
		||||
                        current - id
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
 | 
			
		||||
import eu.davidea.flexibleadapter.items.IFlexible
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.SourceMainControllerBinding
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
@@ -31,8 +30,8 @@ import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.source.global_search.GlobalSearchController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.source.latest.LatestUpdatesController
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
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
 | 
			
		||||
@@ -141,14 +140,14 @@ class SourceController : NucleusController<SourceMainControllerBinding, SourcePr
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun hideCatalogue(source: Source) {
 | 
			
		||||
        val current = preferences.hiddenCatalogues().getOrDefault()
 | 
			
		||||
        val current = preferences.hiddenCatalogues().get()
 | 
			
		||||
        preferences.hiddenCatalogues().set(current + source.id.toString())
 | 
			
		||||
 | 
			
		||||
        presenter.updateSources()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun pinCatalogue(source: Source, isPinned: Boolean) {
 | 
			
		||||
        val current = preferences.pinnedCatalogues().getOrDefault()
 | 
			
		||||
        val current = preferences.pinnedCatalogues().get()
 | 
			
		||||
        if (isPinned) {
 | 
			
		||||
            preferences.pinnedCatalogues().set(current - source.id.toString())
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -202,7 +201,7 @@ class SourceController : NucleusController<SourceMainControllerBinding, SourcePr
 | 
			
		||||
        searchView.queryTextEvents()
 | 
			
		||||
            .filter { it is QueryTextEvent.QuerySubmitted }
 | 
			
		||||
            .onEach { performGlobalSearch(it.queryText.toString()) }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun performGlobalSearch(query: String) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.source
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.source.LocalSource
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
@@ -49,7 +48,7 @@ class SourcePresenter(
 | 
			
		||||
        sourceSubscription?.unsubscribe()
 | 
			
		||||
 | 
			
		||||
        val pinnedSources = mutableListOf<SourceItem>()
 | 
			
		||||
        val pinnedCatalogues = preferences.pinnedCatalogues().getOrDefault()
 | 
			
		||||
        val pinnedCatalogues = preferences.pinnedCatalogues().get()
 | 
			
		||||
 | 
			
		||||
        val map = TreeMap<String, MutableList<CatalogueSource>> { d1, d2 ->
 | 
			
		||||
            // Catalogues without a lang defined will be placed at the end
 | 
			
		||||
@@ -102,8 +101,8 @@ class SourcePresenter(
 | 
			
		||||
     * @return list containing enabled sources.
 | 
			
		||||
     */
 | 
			
		||||
    private fun getEnabledSources(): List<CatalogueSource> {
 | 
			
		||||
        val languages = preferences.enabledLanguages().getOrDefault()
 | 
			
		||||
        val hiddenCatalogues = preferences.hiddenCatalogues().getOrDefault()
 | 
			
		||||
        val languages = preferences.enabledLanguages().get()
 | 
			
		||||
        val hiddenCatalogues = preferences.hiddenCatalogues().get()
 | 
			
		||||
 | 
			
		||||
        return sourceManager.getCatalogueSources()
 | 
			
		||||
                .filter { it.lang in languages }
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,6 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 | 
			
		||||
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.MangaController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.connectivityManager
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import eu.kanade.tachiyomi.util.view.gone
 | 
			
		||||
@@ -43,6 +42,7 @@ import eu.kanade.tachiyomi.util.view.visible
 | 
			
		||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
 | 
			
		||||
import eu.kanade.tachiyomi.widget.EmptyView
 | 
			
		||||
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
 | 
			
		||||
@@ -241,7 +241,7 @@ open class BrowseSourceController(bundle: Bundle) :
 | 
			
		||||
            .filter { router.backstack.lastOrNull()?.controller() == this@BrowseSourceController }
 | 
			
		||||
            .filter { it is QueryTextEvent.QuerySubmitted }
 | 
			
		||||
            .onEach { searchWithQuery(it.queryText.toString()) }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
 | 
			
		||||
        searchItem.fixExpand(
 | 
			
		||||
                onExpand = { invalidateMenuOnExpand() },
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,8 @@ import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 | 
			
		||||
import eu.kanade.tachiyomi.ui.manga.MangaController
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.launchInUI
 | 
			
		||||
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
 | 
			
		||||
@@ -120,7 +120,7 @@ open class GlobalSearchController(
 | 
			
		||||
                searchItem.collapseActionView()
 | 
			
		||||
                setTitle() // Update toolbar title
 | 
			
		||||
            }
 | 
			
		||||
            .launchInUI()
 | 
			
		||||
            .launchIn(scope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ import android.os.Bundle
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.extension.ExtensionManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
@@ -100,9 +99,9 @@ open class GlobalSearchPresenter(
 | 
			
		||||
     * @return list containing enabled sources.
 | 
			
		||||
     */
 | 
			
		||||
    protected open fun getEnabledSources(): List<CatalogueSource> {
 | 
			
		||||
        val languages = preferences.enabledLanguages().getOrDefault()
 | 
			
		||||
        val hiddenCatalogues = preferences.hiddenCatalogues().getOrDefault()
 | 
			
		||||
        val pinnedCatalogues = preferences.pinnedCatalogues().getOrDefault()
 | 
			
		||||
        val languages = preferences.enabledLanguages().get()
 | 
			
		||||
        val hiddenCatalogues = preferences.hiddenCatalogues().get()
 | 
			
		||||
        val pinnedCatalogues = preferences.pinnedCatalogues().get()
 | 
			
		||||
 | 
			
		||||
        return sourceManager.getCatalogueSources()
 | 
			
		||||
                .filter { it.lang in languages }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,14 +6,8 @@ import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
 | 
			
		||||
import kotlinx.coroutines.GlobalScope
 | 
			
		||||
import kotlinx.coroutines.Job
 | 
			
		||||
import kotlinx.coroutines.flow.Flow
 | 
			
		||||
import kotlinx.coroutines.flow.collect
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
 | 
			
		||||
fun <T> Flow<T>.launchInUI(): Job = CoroutineScope(Dispatchers.Main).launch {
 | 
			
		||||
        collect() // tail-call
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun launchUI(block: suspend CoroutineScope.() -> Unit): Job =
 | 
			
		||||
        GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT, block)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user