Using flow prefs on reader

This commit is contained in:
arkon 2020-05-09 16:52:58 -04:00 committed by Jay
parent afcbe3b5a2
commit 8b09548099
12 changed files with 195 additions and 316 deletions

View File

@ -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")

View File

@ -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)

View File

@ -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<P : BasePresenter<*>> : NucleusAppCompatActivity<P>() {
val scope = lifecycleScope
init {
@Suppress("LeakingThis")
LocaleHelper.updateConfiguration(this)

View File

@ -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<ReaderPresenter>(),
viewer?.destroy()
chapters_bottom_sheet.adapter = null
viewer = null
config?.destroy()
config = null
bottomSheet?.dismiss()
bottomSheet = null
@ -724,67 +720,52 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
*/
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<ReaderPresenter>(),
*/
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<ReaderPresenter>(),
*/
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<ReaderPresenter>(),
// 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<ReaderPresenter>(),
* 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())
}
}
}

View File

@ -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<PreferencesHelper>()
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)
}

View File

@ -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<PreferencesHelper>().readerTheme().getOrDefault() == 0 &&
!context.isInNightMode() &&
!activity.window.decorView.rootWindowInsets.hasSideNavBar())
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR

View File

@ -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<Boolean>) {
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<Int>, @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)
}
}

View File

@ -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)

View File

@ -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 <T> Preference<T>.register(
valueAssignment: (T) -> Unit,
onChanged: (T) -> Unit = {}
) {
asFlow()
.onEach {
valueAssignment(it)
onChanged(it)
}
.launchIn(scope)
}
}

View File

@ -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 <T> Preference<T>.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) {

View File

@ -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<PreferencesHelper>()
ImageUtil.autoSetBackground(BitmapFactory.decodeByteArray(
bytesArray, 0, bytesArray.size
), preferences.readerTheme().getOrDefault() == 2, context)
), preferences.readerTheme().get() == 2, context)
}
}

View File

@ -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 <T> Preference<T>.register(
valueAssignment: (T) -> Unit,
onChanged: (T) -> Unit = {}
) {
asObservable()
.doOnNext(valueAssignment)
.skip(1)
.distinctUntilChanged()
.doOnNext(onChanged)
.subscribe()
.addTo(subscriptions)
}
}