From 35d381144d010be47566ee480c311c3d13952822 Mon Sep 17 00:00:00 2001 From: Two-Ai <81279822+Two-Ai@users.noreply.github.com> Date: Sun, 26 Mar 2023 11:52:54 -0400 Subject: [PATCH] Cleanup Preference.asHotFlow() (#9257) * Drop duplicate initial call in Preference.asHotFlow Preference.changes() always starts by returning the current value of the preference, so asHotFlow calls block twice on the initial value. Possible breaking change: As implemented, asHotFlow ran block(get()) before returning the flow. After this change, the first call to block will run within the flow collection. This might cause concurrency issues if the flow collection is late to execute. * Inline Preference.asHotFlow The Preference.changes().onEach().launchIn() pattern is used widely, so the asHotFlow extension method is redundant. --- .../reader/setting/ReaderGeneralSettings.kt | 6 ++--- .../setting/ReaderReadingModeSettings.kt | 26 +++++++++---------- .../util/preference/PreferenceExtensions.kt | 8 ------ .../widget/TachiyomiTextInputEditText.kt | 6 ++--- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderGeneralSettings.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderGeneralSettings.kt index 742c1b8f21..50beac220c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderGeneralSettings.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderGeneralSettings.kt @@ -9,9 +9,9 @@ import androidx.lifecycle.lifecycleScope import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.ReaderGeneralSettingsBinding import eu.kanade.tachiyomi.ui.reader.ReaderActivity -import eu.kanade.tachiyomi.util.preference.asHotFlow import eu.kanade.tachiyomi.util.preference.bindToPreference import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import uy.kohesive.injekt.injectLazy /** @@ -37,8 +37,8 @@ class ReaderGeneralSettings @JvmOverloads constructor(context: Context, attrs: A binding.backgroundColor.bindToIntPreference(readerPreferences.readerTheme(), R.array.reader_themes_values) binding.showPageNumber.bindToPreference(readerPreferences.showPageNumber()) binding.fullscreen.bindToPreference(readerPreferences.fullscreen()) - readerPreferences.fullscreen() - .asHotFlow { + readerPreferences.fullscreen().changes() + .onEach { // If the preference is explicitly disabled, that means the setting was configured since there is a cutout binding.cutoutShort.isVisible = it && ((context as ReaderActivity).hasCutout || !readerPreferences.cutoutShort().get()) binding.cutoutShort.bindToPreference(readerPreferences.cutoutShort()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt index da9eb941f7..02bb3321d9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt @@ -13,9 +13,9 @@ import eu.kanade.tachiyomi.databinding.ReaderReadingModeSettingsBinding import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer -import eu.kanade.tachiyomi.util.preference.asHotFlow import eu.kanade.tachiyomi.util.preference.bindToPreference import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import uy.kohesive.injekt.injectLazy /** @@ -74,8 +74,8 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr binding.pagerPrefsGroup.navigatePan.bindToPreference(readerPreferences.navigateToPan()) binding.pagerPrefsGroup.pagerNav.bindToPreference(readerPreferences.navigationModePager()) - readerPreferences.navigationModePager() - .asHotFlow { + readerPreferences.navigationModePager().changes() + .onEach { val isTappingEnabled = it != 5 binding.pagerPrefsGroup.tappingInverted.isVisible = isTappingEnabled binding.pagerPrefsGroup.navigatePan.isVisible = isTappingEnabled @@ -83,8 +83,8 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr .launchIn((context as ReaderActivity).lifecycleScope) // Makes so that landscape zoom gets hidden away when image scale type is not fit screen binding.pagerPrefsGroup.scaleType.bindToPreference(readerPreferences.imageScaleType(), 1) - readerPreferences.imageScaleType() - .asHotFlow { binding.pagerPrefsGroup.landscapeZoom.isVisible = it == 1 } + readerPreferences.imageScaleType().changes() + .onEach { binding.pagerPrefsGroup.landscapeZoom.isVisible = it == 1 } .launchIn((context as ReaderActivity).lifecycleScope) binding.pagerPrefsGroup.landscapeZoom.bindToPreference(readerPreferences.landscapeZoom()) @@ -92,8 +92,8 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr binding.pagerPrefsGroup.cropBorders.bindToPreference(readerPreferences.cropBorders()) binding.pagerPrefsGroup.dualPageSplit.bindToPreference(readerPreferences.dualPageSplitPaged()) - readerPreferences.dualPageSplitPaged() - .asHotFlow { + readerPreferences.dualPageSplitPaged().changes() + .onEach { binding.pagerPrefsGroup.dualPageInvert.isVisible = it if (it) { binding.pagerPrefsGroup.dualPageRotateToFit.isChecked = false @@ -103,8 +103,8 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr binding.pagerPrefsGroup.dualPageInvert.bindToPreference(readerPreferences.dualPageInvertPaged()) binding.pagerPrefsGroup.dualPageRotateToFit.bindToPreference(readerPreferences.dualPageRotateToFit()) - readerPreferences.dualPageRotateToFit() - .asHotFlow { + readerPreferences.dualPageRotateToFit().changes() + .onEach { binding.pagerPrefsGroup.dualPageRotateToFitInvert.isVisible = it if (it) { binding.pagerPrefsGroup.dualPageSplit.isChecked = false @@ -124,16 +124,16 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr binding.webtoonPrefsGroup.tappingInverted.bindToPreference(readerPreferences.webtoonNavInverted(), ReaderPreferences.TappingInvertMode::class.java) binding.webtoonPrefsGroup.webtoonNav.bindToPreference(readerPreferences.navigationModeWebtoon()) - readerPreferences.navigationModeWebtoon() - .asHotFlow { binding.webtoonPrefsGroup.tappingInverted.isVisible = it != 5 } + readerPreferences.navigationModeWebtoon().changes() + .onEach { binding.webtoonPrefsGroup.tappingInverted.isVisible = it != 5 } .launchIn((context as ReaderActivity).lifecycleScope) binding.webtoonPrefsGroup.cropBordersWebtoon.bindToPreference(readerPreferences.cropBordersWebtoon()) binding.webtoonPrefsGroup.webtoonSidePadding.bindToIntPreference(readerPreferences.webtoonSidePadding(), R.array.webtoon_side_padding_values) binding.webtoonPrefsGroup.dualPageSplit.bindToPreference(readerPreferences.dualPageSplitWebtoon()) // Makes it so that dual page invert gets hidden away when dual page split is turned off - readerPreferences.dualPageSplitWebtoon() - .asHotFlow { binding.webtoonPrefsGroup.dualPageInvert.isVisible = it } + readerPreferences.dualPageSplitWebtoon().changes() + .onEach { binding.webtoonPrefsGroup.dualPageInvert.isVisible = it } .launchIn((context as ReaderActivity).lifecycleScope) binding.webtoonPrefsGroup.dualPageInvert.bindToPreference(readerPreferences.dualPageInvertWebtoon()) binding.webtoonPrefsGroup.longStripSplit.bindToPreference(readerPreferences.longStripSplitWebtoon()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/preference/PreferenceExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/preference/PreferenceExtensions.kt index d8cf1a61f0..7009635c6a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/preference/PreferenceExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/preference/PreferenceExtensions.kt @@ -1,8 +1,6 @@ package eu.kanade.tachiyomi.util.preference import android.widget.CompoundButton -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.onEach import tachiyomi.core.preference.Preference /** @@ -13,12 +11,6 @@ fun CompoundButton.bindToPreference(pref: Preference) { setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) } } -fun Preference.asHotFlow(block: (T) -> Unit): Flow { - block(get()) - return changes() - .onEach { block(it) } -} - operator fun Preference>.plusAssign(item: T) { set(get() + item) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/TachiyomiTextInputEditText.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/TachiyomiTextInputEditText.kt index bf77d38fdf..a571b68fa9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/TachiyomiTextInputEditText.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/TachiyomiTextInputEditText.kt @@ -7,13 +7,13 @@ import androidx.core.view.inputmethod.EditorInfoCompat import com.google.android.material.textfield.TextInputEditText import eu.kanade.domain.base.BasePreferences import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.util.preference.asHotFlow import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -49,8 +49,8 @@ class TachiyomiTextInputEditText @JvmOverloads constructor( * if [BasePreferences.incognitoMode] is true. Some IMEs may not respect this flag. */ fun EditText.setIncognito(viewScope: CoroutineScope) { - Injekt.get().incognitoMode() - .asHotFlow { + Injekt.get().incognitoMode().changes() + .onEach { imeOptions = if (it) { imeOptions or EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING } else {