diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 5ae9d45ecb..3b4003d72d 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -114,9 +114,11 @@ dependencies {
implementation("com.google.firebase:firebase-core:17.3.0")
- val lifecycleVersion = "2.1.0"
+ val lifecycleVersion = "2.2.0"
implementation("androidx.lifecycle:lifecycle-extensions:$lifecycleVersion")
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
+ implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
+
// ReactiveX
implementation("io.reactivex:rxandroid:1.2.1")
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 9c84e839e4..bcd8c68624 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
@@ -61,51 +61,51 @@ class PreferencesHelper(val context: Context) {
fun theme() = prefs.getInt(Keys.theme, 5)
- fun rotation() = rxPrefs.getInteger(Keys.rotation, 1)
+ fun rotation() = flowPrefs.getInt(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 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, 2)
+ fun readerTheme() = flowPrefs.getInt(Keys.readerTheme, 2)
- fun cropBorders() = rxPrefs.getBoolean(Keys.cropBorders, false)
+ fun cropBorders() = flowPrefs.getBoolean(Keys.cropBorders, false)
- fun cropBordersWebtoon() = rxPrefs.getBoolean(Keys.cropBordersWebtoon, false)
+ fun cropBordersWebtoon() = flowPrefs.getBoolean(Keys.cropBordersWebtoon, false)
- fun webtoonSidePadding() = rxPrefs.getInteger(Keys.webtoonSidePadding, 0)
+ fun webtoonSidePadding() = flowPrefs.getInt(Keys.webtoonSidePadding, 0)
- fun readWithTapping() = rxPrefs.getBoolean(Keys.readWithTapping, true)
+ fun readWithTapping() = flowPrefs.getBoolean(Keys.readWithTapping, true)
- fun readWithLongTap() = rxPrefs.getBoolean(Keys.readWithLongTap, true)
+ fun readWithLongTap() = flowPrefs.getBoolean(Keys.readWithLongTap, true)
- fun readWithVolumeKeys() = rxPrefs.getBoolean(Keys.readWithVolumeKeys, false)
+ fun readWithVolumeKeys() = flowPrefs.getBoolean(Keys.readWithVolumeKeys, false)
- fun readWithVolumeKeysInverted() = rxPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
+ fun readWithVolumeKeysInverted() = flowPrefs.getBoolean(Keys.readWithVolumeKeysInverted, false)
fun updateOnlyNonCompleted() = prefs.getBoolean(Keys.updateOnlyNonCompleted, false)
@@ -257,7 +257,7 @@ class PreferencesHelper(val context: Context) {
fun hideFiltersAtStart() = rxPrefs.getBoolean("hide_filters_at_start", false)
- fun alwaysShowChapterTransition() = rxPrefs.getBoolean(Keys.alwaysShowChapterTransition, true)
+ fun alwaysShowChapterTransition() = flowPrefs.getBoolean(Keys.alwaysShowChapterTransition, true)
fun deleteRemovedChapters() = flowPrefs.getInt(Keys.deleteRemovedChapters, 0)
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 d38ecabcc9..8a5e979ac7 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 eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.LocaleHelper
@@ -8,6 +9,8 @@ import nucleus.view.NucleusAppCompatActivity
abstract class BaseRxActivity
> : NucleusAppCompatActivity
() {
+ val scope = lifecycleScope
+
init {
@Suppress("LeakingThis")
LocaleHelper.updateConfiguration(this)
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 8928c0e175..7ff2f4a8eb 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
@@ -33,7 +33,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.ui.base.activity.BaseRxActivity
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Error
@@ -46,7 +45,6 @@ import eu.kanade.tachiyomi.ui.reader.viewer.pager.L2RPagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.VerticalPagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
-import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.GLUtil
import eu.kanade.tachiyomi.util.system.ThemeUtil
@@ -72,17 +70,16 @@ import kotlinx.android.synthetic.main.reader_activity.*
import kotlinx.android.synthetic.main.reader_chapters_sheet.*
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.drop
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.sample
import me.zhanghai.android.systemuihelper.SystemUiHelper
import nucleus.factory.RequiresPresenter
-import rx.Observable
-import rx.Subscription
-import rx.android.schedulers.AndroidSchedulers
-import rx.subscriptions.CompositeSubscription
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
import java.io.File
import java.util.Locale
-import java.util.concurrent.TimeUnit
import kotlin.math.abs
/**
@@ -222,7 +219,6 @@ class ReaderActivity : BaseRxActivity(),
viewer?.destroy()
chapters_bottom_sheet.adapter = null
viewer = null
- config?.destroy()
config = null
bottomSheet?.dismiss()
bottomSheet = null
@@ -724,67 +720,52 @@ class ReaderActivity : BaseRxActivity(),
*/
private inner class ReaderConfig {
- /**
- * List of subscriptions to keep while the reader is alive.
- */
- private val subscriptions = CompositeSubscription()
-
- /**
- * Custom brightness subscription.
- */
- private var customBrightnessSubscription: Subscription? = null
-
- /**
- * Custom color filter subscription.
- */
- private var customFilterColorSubscription: Subscription? = null
-
var showNewChapter = false
/**
* Initializes the reader subscriptions.
*/
init {
- val sharedRotation = preferences.rotation().asObservable().share()
- val initialRotation = sharedRotation.take(1)
- val rotationUpdates = sharedRotation.skip(1)
- .delay(250, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
+ setOrientation(preferences.rotation().get())
+ preferences.rotation().asFlow()
+ .drop(1)
+ .onEach {
+ delay(250)
+ setOrientation(it)
+ }
+ .launchIn(scope)
- subscriptions += Observable.merge(initialRotation, rotationUpdates)
- .subscribe { setOrientation(it) }
+ preferences.showPageNumber().asFlow()
+ .onEach { setPageNumberVisibility(it) }
+ .launchIn(scope)
- subscriptions += preferences.showPageNumber().asObservable()
- .subscribe { setPageNumberVisibility(it) }
+ preferences.trueColor().asFlow()
+ .onEach { setTrueColor(it) }
+ .launchIn(scope)
- subscriptions += preferences.trueColor().asObservable()
- .subscribe { setTrueColor(it) }
+ preferences.fullscreen().asFlow()
+ .onEach { setFullscreen(it) }
+ .launchIn(scope)
- subscriptions += preferences.fullscreen().asObservable()
- .subscribe { setFullscreen(it) }
+ preferences.keepScreenOn().asFlow()
+ .onEach { setKeepScreenOn(it) }
+ .launchIn(scope)
- subscriptions += preferences.keepScreenOn().asObservable()
- .subscribe { setKeepScreenOn(it) }
+ preferences.customBrightness().asFlow()
+ .onEach { setCustomBrightness(it) }
+ .launchIn(scope)
- subscriptions += preferences.customBrightness().asObservable()
- .subscribe { setCustomBrightness(it) }
+ preferences.colorFilter().asFlow()
+ .onEach { setColorFilter(it) }
+ .launchIn(scope)
- subscriptions += preferences.colorFilter().asObservable()
- .subscribe { setColorFilter(it) }
+ preferences.colorFilterMode().asFlow()
+ .onEach { setColorFilter(preferences.colorFilter().get()) }
+ .launchIn(scope)
- subscriptions += preferences.colorFilterMode().asObservable()
- .subscribe { setColorFilter(preferences.colorFilter().getOrDefault()) }
-
- subscriptions += preferences.alwaysShowChapterTransition().asObservable()
- .subscribe { showNewChapter = it }
- }
-
- /**
- * Called when the reader is being destroyed. It cleans up all the subscriptions.
- */
- fun destroy() {
- subscriptions.unsubscribe()
- customBrightnessSubscription = null
- customFilterColorSubscription = null
+ preferences.alwaysShowChapterTransition().asFlow()
+ .onEach { showNewChapter = it }
+ .launchIn(scope)
}
/**
@@ -861,13 +842,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)
}
}
@@ -877,14 +856,12 @@ 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) }
- color_overlay.visibility = View.GONE
+ color_overlay.gone()
}
}
@@ -910,11 +887,11 @@ class ReaderActivity : BaseRxActivity(),
// Set black overlay visibility.
if (value < 0) {
- brightness_overlay.visibility = View.VISIBLE
+ brightness_overlay.visible()
val alpha = (abs(value) * 2.56).toInt()
brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0))
} else {
- brightness_overlay.visibility = View.GONE
+ brightness_overlay.gone()
}
}
@@ -922,8 +899,8 @@ class ReaderActivity : BaseRxActivity(),
* Sets the color filter [value].
*/
private fun setColorFilterValue(value: Int) {
- color_overlay.visibility = View.VISIBLE
- color_overlay.setFilterColor(value, preferences.colorFilterMode().getOrDefault())
+ color_overlay.visible()
+ color_overlay.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 4590db11c2..32b924a4a7 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
@@ -10,48 +10,33 @@ 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.system.hasSideNavBar
+import eu.kanade.tachiyomi.util.system.isInNightMode
import eu.kanade.tachiyomi.util.view.expand
+import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.setBottomEdge
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
+import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
import kotlinx.android.synthetic.main.reader_color_filter.*
import kotlinx.android.synthetic.main.reader_color_filter_sheet.*
-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
-import java.util.concurrent.TimeUnit
import kotlin.math.abs
/**
* Color filter sheet to toggle custom filter and brightness overlay.
*/
-class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
+class ReaderColorFilterSheet(private val activity: ReaderActivity) : BottomSheetDialog
(activity, R.style.BottomSheetDialogTheme) {
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)
@@ -59,26 +44,28 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
setEdgeToEdge(activity, view, 0)
window?.navigationBarColor = Color.TRANSPARENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
- preferences.readerTheme().getOrDefault() == 0 &&
+ !context.isInNightMode() &&
!activity.window.decorView.rootWindowInsets.hasSideNavBar())
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
setBottomEdge(brightness_seekbar, activity)
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)
@@ -93,26 +80,20 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
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)
}
- /*color_filter_mode.setOnClickListener {
- val popupMenu = PopupMenu(context, color_filter_mode)
-
- popupMenu.menuInflater.inflate(R.menu.download_single, popupMenu.menu)
- popupMenu.show()
- }*/
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) {
@@ -161,13 +142,6 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
sheetBehavior?.expand()
}
- 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
@@ -201,15 +175,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
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)
}
@@ -220,13 +190,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
*/
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)
@@ -241,15 +209,16 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
private fun setCustomBrightnessValue(value: Int, view: View, isDisabled: Boolean = false) = with(view) {
// Set black overlay visibility.
if (value < 0) {
- brightness_overlay.visibility = View.VISIBLE
+ brightness_overlay.visible()
val alpha = (abs(value) * 2.56).toInt()
brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0))
} else {
- brightness_overlay.visibility = View.GONE
+ brightness_overlay.gone()
}
- if (!isDisabled)
+ if (!isDisabled) {
txt_brightness_seekbar_value.text = value.toString()
+ }
}
/**
@@ -259,14 +228,12 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
*/
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.visibility = View.GONE
+ color_overlay.gone()
}
setColorFilterSeekBar(enabled, view)
}
@@ -277,8 +244,8 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
* @param view view of the dialog
*/
private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) {
- color_overlay.visibility = View.VISIBLE
- color_overlay.setFilterColor(color, preferences.colorFilterMode().getOrDefault())
+ color_overlay.visible()
+ color_overlay.setFilterColor(color, preferences.colorFilterMode().get())
setValues(color, view)
}
@@ -289,7 +256,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog
* @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/ReaderPageSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPageSheet.kt
index f855502170..5c8ebd4423 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPageSheet.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPageSheet.kt
@@ -8,16 +8,13 @@ import android.view.ViewGroup
import com.afollestad.materialdialogs.MaterialDialog
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.source.model.Page
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.util.system.hasSideNavBar
+import eu.kanade.tachiyomi.util.system.isInNightMode
import eu.kanade.tachiyomi.util.view.setBottomEdge
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
import kotlinx.android.synthetic.main.reader_page_sheet.*
-import uy.kohesive.injekt.Injekt
-import uy.kohesive.injekt.api.get
/**
* Sheet to show when a page is long clicked.
@@ -37,7 +34,7 @@ class ReaderPageSheet(
setEdgeToEdge(activity, view)
window?.navigationBarColor = Color.TRANSPARENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
- Injekt.get().readerTheme().getOrDefault() == 0 &&
+ !context.isInNightMode() &&
!activity.window.decorView.rootWindowInsets.hasSideNavBar())
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
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 4a3851a6e3..17a800443a 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
@@ -9,16 +9,16 @@ import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.Spinner
import androidx.annotation.ArrayRes
-import com.f2prateek.rx.preferences.Preference
import com.google.android.material.bottomsheet.BottomSheetBehavior
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
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.hasSideNavBar
+import eu.kanade.tachiyomi.util.system.isInNightMode
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.setBottomEdge
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
@@ -54,7 +54,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) :
)
window?.navigationBarColor = Color.TRANSPARENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
- preferences.readerTheme().getOrDefault() == 0 &&
+ !context.isInNightMode() &&
!activity.window.decorView.rootWindowInsets.hasSideNavBar()
) {
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
@@ -156,7 +156,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) :
* 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) }
}
@@ -170,7 +170,7 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) :
onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
pref.set(position + offset)
}
- setSelection(pref.getOrDefault() - offset, false)
+ setSelection(pref.get() - offset, false)
}
/**
@@ -181,8 +181,8 @@ class ReaderSettingsSheet(private val activity: ReaderActivity) :
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] ?: 0)
}
- setSelection(intValues.indexOf(pref.getOrDefault()), false)
+ setSelection(intValues.indexOf(pref.get()), false)
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
index 535fae9a71..c5e7d32c68 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
@@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.reader.loader
import android.graphics.BitmapFactory
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
-import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
@@ -221,7 +220,7 @@ class HttpPageLoader(
Observable.just(page)
}
}.doOnNext {
- val readerTheme = preferences.readerTheme().getOrDefault()
+ val readerTheme = preferences.readerTheme().get()
if (readerTheme >= 2) {
val stream = chapterCache.getImageFile(imageUrl).inputStream()
val image = BitmapFactory.decodeStream(stream)
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
new file mode 100644
index 0000000000..fab2958314
--- /dev/null
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt
@@ -0,0 +1,58 @@
+package eu.kanade.tachiyomi.ui.reader.viewer
+
+import com.tfcporciuncula.flow.Preference
+import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+
+/**
+ * Common configuration for all viewers.
+ */
+abstract class ViewerConfig(preferences: PreferencesHelper) {
+
+ 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
+
+ init {
+ preferences.readWithTapping()
+ .register({ tappingEnabled = it })
+
+ preferences.readWithLongTap()
+ .register({ longTapEnabled = it })
+
+ preferences.doubleTapAnimSpeed()
+ .register({ doubleTapAnimDuration = it })
+
+ preferences.readWithVolumeKeys()
+ .register({ volumeKeysEnabled = it })
+
+ preferences.readWithVolumeKeysInverted()
+ .register({ volumeKeysInverted = it })
+
+ preferences.alwaysShowChapterTransition()
+ .register({ alwaysShowChapterTransition = it })
+ }
+
+ fun Preference.register(
+ valueAssignment: (T) -> Unit,
+ onChanged: (T) -> Unit = {}
+ ) {
+ asFlow()
+ .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 2f303e15e8..c6ac8ad7ce 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
@@ -1,32 +1,15 @@
package eu.kanade.tachiyomi.ui.reader.viewer.pager
-import com.f2prateek.rx.preferences.Preference
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
-import eu.kanade.tachiyomi.util.lang.addTo
-import rx.subscriptions.CompositeSubscription
+import eu.kanade.tachiyomi.ui.reader.viewer.ViewerConfig
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
/**
* Configuration used by pager viewers.
*/
-class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelper = Injekt.get()) {
-
- private val subscriptions = CompositeSubscription()
-
- var imagePropertyChangedListener: (() -> Unit)? = null
-
- var tappingEnabled = true
- private set
-
- var longTapEnabled = true
- private set
-
- var volumeKeysEnabled = false
- private set
-
- var volumeKeysInverted = false
- private set
+class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelper = Injekt.get()) :
+ ViewerConfig(preferences) {
var usePageTransitions = false
private set
@@ -40,22 +23,10 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
var imageCropBorders = false
private set
- var doubleTapAnimDuration = 500
- private set
-
var readerTheme = 0
private set
- var alwaysShowChapterTransition = true
- private set
-
init {
- preferences.readWithTapping()
- .register({ tappingEnabled = it })
-
- preferences.readWithLongTap()
- .register({ longTapEnabled = it })
-
preferences.pageTransitions()
.register({ usePageTransitions = it })
@@ -68,37 +39,8 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
preferences.cropBorders()
.register({ imageCropBorders = it }, { imagePropertyChangedListener?.invoke() })
- preferences.doubleTapAnimSpeed()
- .register({ doubleTapAnimDuration = it })
-
- preferences.readWithVolumeKeys()
- .register({ volumeKeysEnabled = it })
-
- preferences.readWithVolumeKeysInverted()
- .register({ volumeKeysInverted = it })
-
preferences.readerTheme()
- .register({ readerTheme = it }, { imagePropertyChangedListener?.invoke() })
-
- preferences.alwaysShowChapterTransition()
- .register({ alwaysShowChapterTransition = it })
- }
-
- fun unsubscribe() {
- subscriptions.unsubscribe()
- }
-
- private fun Preference.register(
- valueAssignment: (T) -> Unit,
- onChanged: (T) -> Unit = {}
- ) {
- asObservable()
- .doOnNext(valueAssignment)
- .skip(1)
- .distinctUntilChanged()
- .doOnNext(onChanged)
- .subscribe()
- .addTo(subscriptions)
+ .register({ readerTheme = it }, { imagePropertyChangedListener?.invoke() })
}
private fun zoomTypeFromPreference(value: Int) {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
index a026fc80cd..651e6dd42e 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
@@ -32,7 +32,6 @@ import com.github.chrisbanes.photoview.PhotoView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
-import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressBar
@@ -304,7 +303,7 @@ class PagerPageHolder(
val preferences by injectLazy()
ImageUtil.autoSetBackground(BitmapFactory.decodeByteArray(
bytesArray, 0, bytesArray.size
- ), preferences.readerTheme().getOrDefault() == 2, context)
+ ), preferences.readerTheme().get() == 2, context)
}
}
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 f4b822958a..6f108b892c 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
@@ -1,91 +1,26 @@
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
-import com.f2prateek.rx.preferences.Preference
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
-import eu.kanade.tachiyomi.util.lang.addTo
-import rx.subscriptions.CompositeSubscription
+import eu.kanade.tachiyomi.ui.reader.viewer.ViewerConfig
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
/**
* Configuration used by webtoon viewers.
*/
-class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) {
-
- private val subscriptions = CompositeSubscription()
-
- var imagePropertyChangedListener: (() -> Unit)? = null
-
- var tappingEnabled = true
- private set
-
- var longTapEnabled = true
- private set
-
- var volumeKeysEnabled = false
- private set
-
- var volumeKeysInverted = false
- private set
+class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfig(preferences) {
var imageCropBorders = false
private set
- var doubleTapAnimDuration = 500
- private set
-
- var alwaysShowChapterTransition = true
- private set
-
var sidePadding = 0
private set
- var readerTheme = 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() })
-
- preferences.readerTheme()
- .register({ readerTheme = it }, { imagePropertyChangedListener?.invoke() })
- }
-
- fun unsubscribe() {
- subscriptions.unsubscribe()
- }
-
- private fun Preference.register(
- valueAssignment: (T) -> Unit,
- onChanged: (T) -> Unit = {}
- ) {
- asObservable()
- .doOnNext(valueAssignment)
- .skip(1)
- .distinctUntilChanged()
- .doOnNext(onChanged)
- .subscribe()
- .addTo(subscriptions)
}
}