diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index aff4f37cc..00e5c6912 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -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) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt index 01068aa76..07a8b7049 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseActivity.kt @@ -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 : AppCompatActivity() { val preferences: PreferencesHelper by injectLazy() + val scope = lifecycleScope lateinit var binding: VB @Suppress("LeakingThis") diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt index 396e9e64f..9358da75b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseRxActivity.kt @@ -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> : NucleusA @Suppress("LeakingThis") private val secureActivityDelegate = SecureActivityDelegate(this) + val scope = lifecycleScope lateinit var binding: VB init { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/NucleusController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/NucleusController.kt index 0786d5e13..247b6d8bd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/NucleusController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/NucleusController.kt @@ -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>(val bundle: private val delegate = NucleusConductorDelegate(this) + val scope = CoroutineScope(Job() + Dispatchers.Main) + val presenter: P get() = delegate.presenter!! diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt index 0a2a5f84f..ba4d68a88 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt @@ -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().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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt index cf493bc69..528d3b3e0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt @@ -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 { val context = Injekt.get() - val activeLangs = preferences.enabledLanguages().getOrDefault() + val activeLangs = preferences.enabledLanguages().get() val (installed, untrusted, available) = tuple diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 070b8a9aa..8bcd07965 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -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() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 34273af92..596c6107e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -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() { setExtensionsBadge() preferences.extensionUpdatesCount().asFlow() .onEach { setExtensionsBadge() } - .launchIn(lifecycleScope) + .launchIn(scope) } override fun onNewIntent(intent: Intent) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index 2b188b3bc..323f7cfd1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -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 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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 4bb3f4e5a..0b89b122e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -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() * 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() 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() 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() binding.readerMenuBottom.startAnimation(bottomAnimation) } - if (preferences.showPageNumber().getOrDefault()) { + if (preferences.showPageNumber().get()) { config?.setPageNumberVisibility(true) } } @@ -605,16 +607,6 @@ class ReaderActivity : BaseRxActivity() */ 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() 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() */ fun destroy() { subscriptions.unsubscribe() - customBrightnessSubscription = null - customFilterColorSubscription = null } /** @@ -732,13 +730,11 @@ class ReaderActivity : BaseRxActivity() */ 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() */ 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() */ private fun setColorFilterValue(value: Int) { binding.colorOverlay.visible() - binding.colorOverlay.setFilterColor(value, preferences.colorFilterMode().getOrDefault()) + binding.colorOverlay.setFilterColor(value, preferences.colorFilterMode().get()) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt index 8b5096967..c4f5a18e2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt @@ -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() 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) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt index 944f3df71..e6fa18ab9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt @@ -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) { - 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, 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, @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) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt index b645432e9..fab295831 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt @@ -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 com.f2prateek.rx.preferences.Preference.register( - valueAssignment: (T) -> Unit, - onChanged: (T) -> Unit = {} - ) { - asObservable() - .doOnNext(valueAssignment) - .skip(1) - .distinctUntilChanged() - .doOnNext(onChanged) - .subscribe() - .addTo(subscriptions) - } - fun Preference.register( valueAssignment: (T) -> Unit, onChanged: (T) -> Unit = {} ) { asFlow() - .onEach { valueAssignment(it) } - .distinctUntilChanged() - .onEach { onChanged(it) } - .launchInUI() + .onEach { + valueAssignment(it) + onChanged(it) + } + .launchIn(scope) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt index 552b76af2..5912aa990 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt @@ -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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt index 8e968bcac..3f6464b99 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt @@ -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 */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt index 569d52605..6f108b892 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonConfig.kt @@ -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() }) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt index b69be2d14..850fbf222 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonViewer.kt @@ -155,7 +155,6 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr */ override fun destroy() { super.destroy() - config.unsubscribe() subscriptions.unsubscribe() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt index cb04357c0..3a0a0704d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt @@ -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 Observable.subscribeUntilDestroy(): Subscription { - return subscribe().also { untilDestroySubscriptions.add(it) } - } - fun Observable.subscribeUntilDestroy(onNext: (T) -> Unit): Subscription { return subscribe(onNext).also { untilDestroySubscriptions.add(it) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt index 96b60c6b6..b58fe3851 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt @@ -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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt index 0a157eb21..c9207f502 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSecurityController.kt @@ -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) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSourcesController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSourcesController.kt index 3ba9d1b00..f1fcbdd7a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSourcesController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsSourcesController.kt @@ -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) { - 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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/source/SourceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/source/SourceController.kt index bf8caac08..4909ec591 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/source/SourceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/source/SourceController.kt @@ -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() - val pinnedCatalogues = preferences.pinnedCatalogues().getOrDefault() + val pinnedCatalogues = preferences.pinnedCatalogues().get() val map = TreeMap> { 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 { - 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 } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt index 0721da28e..452bfcfd2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/source/browse/BrowseSourceController.kt @@ -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() }, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchController.kt index 7e19e1de0..32da8a8e3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchController.kt @@ -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) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchPresenter.kt index 17e30ad49..d48713c9f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/source/global_search/GlobalSearchPresenter.kt @@ -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 { - 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 } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt index 35eec06ba..1dedec97e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/lang/CoroutinesExtensions.kt @@ -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 Flow.launchInUI(): Job = CoroutineScope(Dispatchers.Main).launch { - collect() // tail-call -} - fun launchUI(block: suspend CoroutineScope.() -> Unit): Job = GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT, block)