mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-09 20:15:05 +01:00
Using flow prefs on reader
This commit is contained in:
parent
afcbe3b5a2
commit
8b09548099
@ -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")
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
||||
subscriptions += Observable.merge(initialRotation, rotationUpdates)
|
||||
.subscribe { setOrientation(it) }
|
||||
|
||||
subscriptions += preferences.showPageNumber().asObservable()
|
||||
.subscribe { setPageNumberVisibility(it) }
|
||||
|
||||
subscriptions += preferences.trueColor().asObservable()
|
||||
.subscribe { setTrueColor(it) }
|
||||
|
||||
subscriptions += preferences.fullscreen().asObservable()
|
||||
.subscribe { setFullscreen(it) }
|
||||
|
||||
subscriptions += preferences.keepScreenOn().asObservable()
|
||||
.subscribe { setKeepScreenOn(it) }
|
||||
|
||||
subscriptions += preferences.customBrightness().asObservable()
|
||||
.subscribe { setCustomBrightness(it) }
|
||||
|
||||
subscriptions += preferences.colorFilter().asObservable()
|
||||
.subscribe { setColorFilter(it) }
|
||||
|
||||
subscriptions += preferences.colorFilterMode().asObservable()
|
||||
.subscribe { setColorFilter(preferences.colorFilter().getOrDefault()) }
|
||||
|
||||
subscriptions += preferences.alwaysShowChapterTransition().asObservable()
|
||||
.subscribe { showNewChapter = it }
|
||||
setOrientation(preferences.rotation().get())
|
||||
preferences.rotation().asFlow()
|
||||
.drop(1)
|
||||
.onEach {
|
||||
delay(250)
|
||||
setOrientation(it)
|
||||
}
|
||||
.launchIn(scope)
|
||||
|
||||
/**
|
||||
* Called when the reader is being destroyed. It cleans up all the subscriptions.
|
||||
*/
|
||||
fun destroy() {
|
||||
subscriptions.unsubscribe()
|
||||
customBrightnessSubscription = null
|
||||
customFilterColorSubscription = null
|
||||
preferences.showPageNumber().asFlow()
|
||||
.onEach { setPageNumberVisibility(it) }
|
||||
.launchIn(scope)
|
||||
|
||||
preferences.trueColor().asFlow()
|
||||
.onEach { setTrueColor(it) }
|
||||
.launchIn(scope)
|
||||
|
||||
preferences.fullscreen().asFlow()
|
||||
.onEach { setFullscreen(it) }
|
||||
.launchIn(scope)
|
||||
|
||||
preferences.keepScreenOn().asFlow()
|
||||
.onEach { setKeepScreenOn(it) }
|
||||
.launchIn(scope)
|
||||
|
||||
preferences.customBrightness().asFlow()
|
||||
.onEach { setCustomBrightness(it) }
|
||||
.launchIn(scope)
|
||||
|
||||
preferences.colorFilter().asFlow()
|
||||
.onEach { setColorFilter(it) }
|
||||
.launchIn(scope)
|
||||
|
||||
preferences.colorFilterMode().asFlow()
|
||||
.onEach { setColorFilter(preferences.colorFilter().get()) }
|
||||
.launchIn(scope)
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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_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,16 +209,17 @@ 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()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the color filter value subscription
|
||||
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
private fun zoomTypeFromPreference(value: Int) {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user