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.
This commit is contained in:
Two-Ai 2023-03-26 11:52:54 -04:00 committed by GitHub
parent 0bcc22822d
commit 35d381144d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 27 deletions

View file

@ -9,9 +9,9 @@ import androidx.lifecycle.lifecycleScope
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.ReaderGeneralSettingsBinding import eu.kanade.tachiyomi.databinding.ReaderGeneralSettingsBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.util.preference.bindToPreference import eu.kanade.tachiyomi.util.preference.bindToPreference
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.injectLazy 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.backgroundColor.bindToIntPreference(readerPreferences.readerTheme(), R.array.reader_themes_values)
binding.showPageNumber.bindToPreference(readerPreferences.showPageNumber()) binding.showPageNumber.bindToPreference(readerPreferences.showPageNumber())
binding.fullscreen.bindToPreference(readerPreferences.fullscreen()) binding.fullscreen.bindToPreference(readerPreferences.fullscreen())
readerPreferences.fullscreen() readerPreferences.fullscreen().changes()
.asHotFlow { .onEach {
// If the preference is explicitly disabled, that means the setting was configured since there is a cutout // 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.isVisible = it && ((context as ReaderActivity).hasCutout || !readerPreferences.cutoutShort().get())
binding.cutoutShort.bindToPreference(readerPreferences.cutoutShort()) binding.cutoutShort.bindToPreference(readerPreferences.cutoutShort())

View file

@ -13,9 +13,9 @@ import eu.kanade.tachiyomi.databinding.ReaderReadingModeSettingsBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.util.preference.bindToPreference import eu.kanade.tachiyomi.util.preference.bindToPreference
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
/** /**
@ -74,8 +74,8 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr
binding.pagerPrefsGroup.navigatePan.bindToPreference(readerPreferences.navigateToPan()) binding.pagerPrefsGroup.navigatePan.bindToPreference(readerPreferences.navigateToPan())
binding.pagerPrefsGroup.pagerNav.bindToPreference(readerPreferences.navigationModePager()) binding.pagerPrefsGroup.pagerNav.bindToPreference(readerPreferences.navigationModePager())
readerPreferences.navigationModePager() readerPreferences.navigationModePager().changes()
.asHotFlow { .onEach {
val isTappingEnabled = it != 5 val isTappingEnabled = it != 5
binding.pagerPrefsGroup.tappingInverted.isVisible = isTappingEnabled binding.pagerPrefsGroup.tappingInverted.isVisible = isTappingEnabled
binding.pagerPrefsGroup.navigatePan.isVisible = isTappingEnabled binding.pagerPrefsGroup.navigatePan.isVisible = isTappingEnabled
@ -83,8 +83,8 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr
.launchIn((context as ReaderActivity).lifecycleScope) .launchIn((context as ReaderActivity).lifecycleScope)
// Makes so that landscape zoom gets hidden away when image scale type is not fit screen // Makes so that landscape zoom gets hidden away when image scale type is not fit screen
binding.pagerPrefsGroup.scaleType.bindToPreference(readerPreferences.imageScaleType(), 1) binding.pagerPrefsGroup.scaleType.bindToPreference(readerPreferences.imageScaleType(), 1)
readerPreferences.imageScaleType() readerPreferences.imageScaleType().changes()
.asHotFlow { binding.pagerPrefsGroup.landscapeZoom.isVisible = it == 1 } .onEach { binding.pagerPrefsGroup.landscapeZoom.isVisible = it == 1 }
.launchIn((context as ReaderActivity).lifecycleScope) .launchIn((context as ReaderActivity).lifecycleScope)
binding.pagerPrefsGroup.landscapeZoom.bindToPreference(readerPreferences.landscapeZoom()) 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.cropBorders.bindToPreference(readerPreferences.cropBorders())
binding.pagerPrefsGroup.dualPageSplit.bindToPreference(readerPreferences.dualPageSplitPaged()) binding.pagerPrefsGroup.dualPageSplit.bindToPreference(readerPreferences.dualPageSplitPaged())
readerPreferences.dualPageSplitPaged() readerPreferences.dualPageSplitPaged().changes()
.asHotFlow { .onEach {
binding.pagerPrefsGroup.dualPageInvert.isVisible = it binding.pagerPrefsGroup.dualPageInvert.isVisible = it
if (it) { if (it) {
binding.pagerPrefsGroup.dualPageRotateToFit.isChecked = false binding.pagerPrefsGroup.dualPageRotateToFit.isChecked = false
@ -103,8 +103,8 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr
binding.pagerPrefsGroup.dualPageInvert.bindToPreference(readerPreferences.dualPageInvertPaged()) binding.pagerPrefsGroup.dualPageInvert.bindToPreference(readerPreferences.dualPageInvertPaged())
binding.pagerPrefsGroup.dualPageRotateToFit.bindToPreference(readerPreferences.dualPageRotateToFit()) binding.pagerPrefsGroup.dualPageRotateToFit.bindToPreference(readerPreferences.dualPageRotateToFit())
readerPreferences.dualPageRotateToFit() readerPreferences.dualPageRotateToFit().changes()
.asHotFlow { .onEach {
binding.pagerPrefsGroup.dualPageRotateToFitInvert.isVisible = it binding.pagerPrefsGroup.dualPageRotateToFitInvert.isVisible = it
if (it) { if (it) {
binding.pagerPrefsGroup.dualPageSplit.isChecked = false 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.tappingInverted.bindToPreference(readerPreferences.webtoonNavInverted(), ReaderPreferences.TappingInvertMode::class.java)
binding.webtoonPrefsGroup.webtoonNav.bindToPreference(readerPreferences.navigationModeWebtoon()) binding.webtoonPrefsGroup.webtoonNav.bindToPreference(readerPreferences.navigationModeWebtoon())
readerPreferences.navigationModeWebtoon() readerPreferences.navigationModeWebtoon().changes()
.asHotFlow { binding.webtoonPrefsGroup.tappingInverted.isVisible = it != 5 } .onEach { binding.webtoonPrefsGroup.tappingInverted.isVisible = it != 5 }
.launchIn((context as ReaderActivity).lifecycleScope) .launchIn((context as ReaderActivity).lifecycleScope)
binding.webtoonPrefsGroup.cropBordersWebtoon.bindToPreference(readerPreferences.cropBordersWebtoon()) binding.webtoonPrefsGroup.cropBordersWebtoon.bindToPreference(readerPreferences.cropBordersWebtoon())
binding.webtoonPrefsGroup.webtoonSidePadding.bindToIntPreference(readerPreferences.webtoonSidePadding(), R.array.webtoon_side_padding_values) binding.webtoonPrefsGroup.webtoonSidePadding.bindToIntPreference(readerPreferences.webtoonSidePadding(), R.array.webtoon_side_padding_values)
binding.webtoonPrefsGroup.dualPageSplit.bindToPreference(readerPreferences.dualPageSplitWebtoon()) binding.webtoonPrefsGroup.dualPageSplit.bindToPreference(readerPreferences.dualPageSplitWebtoon())
// Makes it so that dual page invert gets hidden away when dual page split is turned off // Makes it so that dual page invert gets hidden away when dual page split is turned off
readerPreferences.dualPageSplitWebtoon() readerPreferences.dualPageSplitWebtoon().changes()
.asHotFlow { binding.webtoonPrefsGroup.dualPageInvert.isVisible = it } .onEach { binding.webtoonPrefsGroup.dualPageInvert.isVisible = it }
.launchIn((context as ReaderActivity).lifecycleScope) .launchIn((context as ReaderActivity).lifecycleScope)
binding.webtoonPrefsGroup.dualPageInvert.bindToPreference(readerPreferences.dualPageInvertWebtoon()) binding.webtoonPrefsGroup.dualPageInvert.bindToPreference(readerPreferences.dualPageInvertWebtoon())
binding.webtoonPrefsGroup.longStripSplit.bindToPreference(readerPreferences.longStripSplitWebtoon()) binding.webtoonPrefsGroup.longStripSplit.bindToPreference(readerPreferences.longStripSplitWebtoon())

View file

@ -1,8 +1,6 @@
package eu.kanade.tachiyomi.util.preference package eu.kanade.tachiyomi.util.preference
import android.widget.CompoundButton import android.widget.CompoundButton
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onEach
import tachiyomi.core.preference.Preference import tachiyomi.core.preference.Preference
/** /**
@ -13,12 +11,6 @@ fun CompoundButton.bindToPreference(pref: Preference<Boolean>) {
setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) } setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
} }
fun <T> Preference<T>.asHotFlow(block: (T) -> Unit): Flow<T> {
block(get())
return changes()
.onEach { block(it) }
}
operator fun <T> Preference<Set<T>>.plusAssign(item: T) { operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
set(get() + item) set(get() + item)
} }

View file

@ -7,13 +7,13 @@ import androidx.core.view.inputmethod.EditorInfoCompat
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import eu.kanade.domain.base.BasePreferences import eu.kanade.domain.base.BasePreferences
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get 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. * if [BasePreferences.incognitoMode] is true. Some IMEs may not respect this flag.
*/ */
fun EditText.setIncognito(viewScope: CoroutineScope) { fun EditText.setIncognito(viewScope: CoroutineScope) {
Injekt.get<BasePreferences>().incognitoMode() Injekt.get<BasePreferences>().incognitoMode().changes()
.asHotFlow { .onEach {
imeOptions = if (it) { imeOptions = if (it) {
imeOptions or EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING imeOptions or EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING
} else { } else {