From 2815068a002743bd854613b4c1064d6594ce46f3 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. (cherry picked from commit 35d381144d010be47566ee480c311c3d13952822) --- .../ui/library/LibraryScreenModel.kt | 11 ++++---- .../reader/setting/ReaderGeneralSettings.kt | 10 +++---- .../setting/ReaderReadingModeSettings.kt | 26 +++++++++---------- .../util/preference/PreferenceExtensions.kt | 8 ------ .../widget/TachiyomiTextInputEditText.kt | 6 ++--- 5 files changed, 27 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt index 3e30f8f0f..cc2c76f82 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt @@ -36,7 +36,6 @@ import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.util.chapter.getNextUnread -import eu.kanade.tachiyomi.util.preference.asHotFlow import eu.kanade.tachiyomi.util.removeCovers import exh.favorites.FavoritesSyncHelper import exh.md.utils.FollowStatus @@ -259,11 +258,13 @@ class LibraryScreenModel( } .launchIn(coroutineScope) - libraryPreferences.groupLibraryBy().asHotFlow { - mutableState.update { state -> - state.copy(groupType = it) + libraryPreferences.groupLibraryBy().changes() + .onEach { + mutableState.update { state -> + state.copy(groupType = it) + } } - }.launchIn(coroutineScope) + .launchIn(coroutineScope) // SY <-- } 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 f525e866a..e76a704bc 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 @@ -10,9 +10,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 /** @@ -38,8 +38,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()) @@ -60,8 +60,8 @@ class ReaderGeneralSettings @JvmOverloads constructor(context: Context, attrs: A // Hides landscapeVerticalSeekbar & leftVerticalSeekbar option when forceHorizontalSeekbar is enabled binding.forceHorzSeekbar.bindToPreference(readerPreferences.forceHorizontalSeekbar()) - readerPreferences.forceHorizontalSeekbar() - .asHotFlow { + readerPreferences.forceHorizontalSeekbar().changes() + .onEach { binding.landscapeVerticalSeekbar.isGone = it binding.leftVerticalSeekbar.isGone = it } 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 7b74947f5..4693fa9ab 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 @@ -131,16 +131,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 d8cf1a61f..7009635c6 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 bf77d38fd..a571b68fa 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 {