Kaynağa Gözat

Migrate ReaderColorFilterSettings to Compose

It'll eventually be a tab with the other settings again once the other tabs are also
migrated over so it's just a single Compose sheet.
arkon 1 yıl önce
ebeveyn
işleme
fe82cdb9c8

+ 0 - 1
app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt

@@ -199,7 +199,6 @@ private fun ColumnScope.DisplayPage(
         val columns by columnPreference.collectAsState()
         SliderItem(
             label = stringResource(R.string.pref_library_columns),
-            min = 0,
             max = 10,
             value = columns,
             valueText = if (columns > 0) {

+ 18 - 0
app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt

@@ -11,6 +11,7 @@ import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.structuralEqualityPolicy
+import androidx.compose.ui.unit.dp
 import eu.kanade.domain.track.service.TrackPreferences
 import eu.kanade.domain.ui.UiPreferences
 import eu.kanade.presentation.more.settings.widget.AppThemePreferenceWidget
@@ -24,10 +25,12 @@ import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
 import eu.kanade.presentation.util.collectAsState
 import kotlinx.coroutines.launch
 import tachiyomi.core.preference.PreferenceStore
+import tachiyomi.presentation.core.components.SliderItem
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 
 val LocalPreferenceHighlighted = compositionLocalOf(structuralEqualityPolicy()) { false }
+val LocalPreferenceMinHeight = compositionLocalOf(structuralEqualityPolicy()) { 56.dp }
 
 @Composable
 fun StatusWrapper(
@@ -77,6 +80,21 @@ internal fun PreferenceItem(
                     },
                 )
             }
+            is Preference.PreferenceItem.SliderPreference -> {
+                // TODO: use different composable?
+                SliderItem(
+                    label = item.title,
+                    min = item.min,
+                    max = item.max,
+                    value = item.value,
+                    valueText = item.value.toString(),
+                    onChange = {
+                        scope.launch {
+                            item.onValueChanged(it)
+                        }
+                    },
+                )
+            }
             is Preference.PreferenceItem.ListPreference<*> -> {
                 val value by item.pref.collectAsState()
                 ListPreferenceWidget(

+ 15 - 0
app/src/main/java/eu/kanade/presentation/more/settings/PreferenceModel.kt

@@ -5,6 +5,7 @@ import androidx.compose.runtime.remember
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.res.stringResource
 import eu.kanade.domain.ui.model.AppTheme
+import eu.kanade.presentation.more.settings.Preference.PreferenceItem
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.track.TrackService
 import tachiyomi.core.preference.Preference as PreferenceData
@@ -43,6 +44,20 @@ sealed class Preference {
             override val onValueChanged: suspend (newValue: Boolean) -> Boolean = { true },
         ) : PreferenceItem<Boolean>()
 
+        /**
+         * A [PreferenceItem] that provides a slider to select an integer number.
+         */
+        data class SliderPreference(
+            val value: Int,
+            val min: Int = 0,
+            val max: Int,
+            override val title: String = "",
+            override val subtitle: String? = null,
+            override val icon: ImageVector? = null,
+            override val enabled: Boolean = true,
+            override val onValueChanged: suspend (newValue: Int) -> Boolean = { true },
+        ) : PreferenceItem<Int>()
+
         /**
          * A [PreferenceItem] that displays a list of entries as a dialog.
          */

+ 3 - 1
app/src/main/java/eu/kanade/presentation/more/settings/widget/BasePreferenceWidget.kt

@@ -31,6 +31,7 @@ import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import eu.kanade.presentation.more.settings.LocalPreferenceHighlighted
+import eu.kanade.presentation.more.settings.LocalPreferenceMinHeight
 import kotlinx.coroutines.delay
 import kotlin.time.Duration.Companion.seconds
 
@@ -44,10 +45,11 @@ internal fun BasePreferenceWidget(
     widget: @Composable (() -> Unit)? = null,
 ) {
     val highlighted = LocalPreferenceHighlighted.current
+    val minHeight = LocalPreferenceMinHeight.current
     Row(
         modifier = modifier
             .highlightBackground(highlighted)
-            .sizeIn(minHeight = 56.dp)
+            .sizeIn(minHeight = minHeight)
             .clickable(enabled = onClick != null, onClick = { onClick?.invoke() })
             .fillMaxWidth(),
         verticalAlignment = Alignment.CenterVertically,

+ 20 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -58,6 +58,7 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
 import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
 import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
 import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
+import eu.kanade.tachiyomi.ui.reader.setting.ReaderColorFilterDialog
 import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
 import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsSheet
 import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
@@ -409,10 +410,20 @@ class ReaderActivity : BaseActivity() {
 
         binding.dialogRoot.setComposeContent {
             val state by viewModel.state.collectAsState()
-
+            val onDismissRequest = viewModel::closeDialog
             when (state.dialog) {
+                is ReaderViewModel.Dialog.ColorFilter -> {
+                    setMenuVisibility(false)
+                    ReaderColorFilterDialog(
+                        onDismissRequest = {
+                            onDismissRequest()
+                            setMenuVisibility(true)
+                        },
+                        readerPreferences = viewModel.readerPreferences,
+                    )
+                }
                 is ReaderViewModel.Dialog.Page -> ReaderPageDialog(
-                    onDismissRequest = viewModel::closeDialog,
+                    onDismissRequest = onDismissRequest,
                     onSetAsCover = viewModel::setAsCover,
                     onShare = viewModel::shareImage,
                     onSave = viewModel::saveImage,
@@ -548,11 +559,14 @@ class ReaderActivity : BaseActivity() {
                 if (readerSettingSheet?.isShowing == true) return@setOnClickListener
                 readerSettingSheet = ReaderSettingsSheet(this@ReaderActivity).apply { show() }
             }
+        }
+
+        // Color filter sheet
+        with(binding.actionColorSettings) {
+            setTooltip(R.string.custom_filter)
 
-            setOnLongClickListener {
-                if (readerSettingSheet?.isShowing == true) return@setOnLongClickListener false
-                readerSettingSheet = ReaderSettingsSheet(this@ReaderActivity, showColorFilterSettings = true).apply { show() }
-                true
+            setOnClickListener {
+                viewModel.openColorFilterDialog()
             }
         }
     }

+ 6 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt

@@ -92,9 +92,9 @@ class ReaderViewModel(
     private val downloadProvider: DownloadProvider = Injekt.get(),
     private val imageSaver: ImageSaver = Injekt.get(),
     preferences: BasePreferences = Injekt.get(),
+    val readerPreferences: ReaderPreferences = Injekt.get(),
     private val basePreferences: BasePreferences = Injekt.get(),
     private val downloadPreferences: DownloadPreferences = Injekt.get(),
-    private val readerPreferences: ReaderPreferences = Injekt.get(),
     private val trackPreferences: TrackPreferences = Injekt.get(),
     private val delayedTrackingStore: DelayedTrackingStore = Injekt.get(),
     private val getManga: GetManga = Injekt.get(),
@@ -723,6 +723,10 @@ class ReaderViewModel(
         mutableState.update { it.copy(dialog = Dialog.Page(page)) }
     }
 
+    fun openColorFilterDialog() {
+        mutableState.update { it.copy(dialog = Dialog.ColorFilter) }
+    }
+
     fun closeDialog() {
         mutableState.update { it.copy(dialog = null) }
     }
@@ -925,6 +929,7 @@ class ReaderViewModel(
     }
 
     sealed class Dialog {
+        object ColorFilter : Dialog()
         data class Page(val page: ReaderPage) : Dialog()
     }
 

+ 164 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderColorFilterDialog.kt

@@ -0,0 +1,164 @@
+package eu.kanade.tachiyomi.ui.reader.setting
+
+import android.os.Build
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.window.DialogWindowProvider
+import androidx.core.graphics.alpha
+import androidx.core.graphics.blue
+import androidx.core.graphics.green
+import androidx.core.graphics.red
+import eu.kanade.presentation.components.AdaptiveSheet
+import eu.kanade.presentation.more.settings.LocalPreferenceMinHeight
+import eu.kanade.presentation.more.settings.Preference
+import eu.kanade.presentation.more.settings.PreferenceScreen
+import eu.kanade.presentation.util.collectAsState
+import eu.kanade.tachiyomi.R
+import tachiyomi.core.preference.getAndSet
+
+@Composable
+fun ReaderColorFilterDialog(
+    onDismissRequest: () -> Unit,
+    readerPreferences: ReaderPreferences,
+) {
+    val colorFilterModes = buildList {
+        addAll(
+            listOf(
+                R.string.label_default,
+                R.string.filter_mode_multiply,
+                R.string.filter_mode_screen,
+            ),
+        )
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            addAll(
+                listOf(
+                    R.string.filter_mode_overlay,
+                    R.string.filter_mode_lighten,
+                    R.string.filter_mode_darken,
+                ),
+            )
+        }
+    }.map { stringResource(it) }
+
+    val customBrightness by readerPreferences.customBrightness().collectAsState()
+    val customBrightnessValue by readerPreferences.customBrightnessValue().collectAsState()
+    val colorFilter by readerPreferences.colorFilter().collectAsState()
+    val colorFilterValue by readerPreferences.colorFilterValue().collectAsState()
+    val colorFilterMode by readerPreferences.colorFilterMode().collectAsState()
+
+    AdaptiveSheet(
+        onDismissRequest = onDismissRequest,
+    ) {
+        (LocalView.current.parent as? DialogWindowProvider)?.window?.setDimAmount(0f)
+
+        CompositionLocalProvider(
+            LocalPreferenceMinHeight provides 48.dp,
+        ) {
+            PreferenceScreen(
+                items = listOfNotNull(
+                    Preference.PreferenceItem.SwitchPreference(
+                        pref = readerPreferences.customBrightness(),
+                        title = stringResource(R.string.pref_custom_brightness),
+                    ),
+                    /**
+                     * Sets the brightness of the screen. Range is [-75, 100].
+                     * From -75 to -1 a semi-transparent black view is shown at the top with the minimum brightness.
+                     * From 1 to 100 it sets that value as brightness.
+                     * 0 sets system brightness and hides the overlay.
+                     */
+                    Preference.PreferenceItem.SliderPreference(
+                        value = customBrightnessValue,
+                        title = stringResource(R.string.pref_custom_brightness),
+                        min = -75,
+                        max = 100,
+                        onValueChanged = {
+                            readerPreferences.customBrightnessValue().set(it)
+                            true
+                        },
+                    ).takeIf { customBrightness },
+
+                    Preference.PreferenceItem.SwitchPreference(
+                        pref = readerPreferences.colorFilter(),
+                        title = stringResource(R.string.pref_custom_color_filter),
+                    ),
+                    Preference.PreferenceItem.SliderPreference(
+                        value = colorFilterValue.red,
+                        title = stringResource(R.string.color_filter_r_value),
+                        max = 255,
+                        onValueChanged = { newRValue ->
+                            readerPreferences.colorFilterValue().getAndSet {
+                                getColorValue(it, newRValue, RED_MASK, 16)
+                            }
+                            true
+                        },
+                    ).takeIf { colorFilter },
+                    Preference.PreferenceItem.SliderPreference(
+                        value = colorFilterValue.green,
+                        title = stringResource(R.string.color_filter_g_value),
+                        max = 255,
+                        onValueChanged = { newRValue ->
+                            readerPreferences.colorFilterValue().getAndSet {
+                                getColorValue(it, newRValue, GREEN_MASK, 8)
+                            }
+                            true
+                        },
+                    ).takeIf { colorFilter },
+                    Preference.PreferenceItem.SliderPreference(
+                        value = colorFilterValue.blue,
+                        title = stringResource(R.string.color_filter_b_value),
+                        max = 255,
+                        onValueChanged = { newRValue ->
+                            readerPreferences.colorFilterValue().getAndSet {
+                                getColorValue(it, newRValue, BLUE_MASK, 0)
+                            }
+                            true
+                        },
+                    ).takeIf { colorFilter },
+                    Preference.PreferenceItem.SliderPreference(
+                        value = colorFilterValue.alpha,
+                        title = stringResource(R.string.color_filter_a_value),
+                        max = 255,
+                        onValueChanged = { newRValue ->
+                            readerPreferences.colorFilterValue().getAndSet {
+                                getColorValue(it, newRValue, ALPHA_MASK, 24)
+                            }
+                            true
+                        },
+                    ).takeIf { colorFilter },
+                    Preference.PreferenceItem.BasicListPreference(
+                        value = colorFilterMode.toString(),
+                        title = stringResource(R.string.pref_color_filter_mode),
+                        entries = colorFilterModes
+                            .mapIndexed { index, mode -> index.toString() to mode }
+                            .toMap(),
+                        onValueChanged = { newValue ->
+                            readerPreferences.colorFilterMode().set(newValue.toInt())
+                            true
+                        },
+                    ).takeIf { colorFilter },
+
+                    Preference.PreferenceItem.SwitchPreference(
+                        pref = readerPreferences.grayscale(),
+                        title = stringResource(R.string.pref_grayscale),
+                    ),
+                    Preference.PreferenceItem.SwitchPreference(
+                        pref = readerPreferences.invertedColors(),
+                        title = stringResource(R.string.pref_inverted_colors),
+                    ),
+                ),
+            )
+        }
+    }
+}
+
+private fun getColorValue(currentColor: Int, color: Int, mask: Long, bitShift: Int): Int {
+    return (color shl bitShift) or (currentColor and mask.inv().toInt())
+}
+private const val ALPHA_MASK: Long = 0xFF000000
+private const val RED_MASK: Long = 0x00FF0000
+private const val GREEN_MASK: Long = 0x0000FF00
+private const val BLUE_MASK: Long = 0x000000FF

+ 0 - 202
app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderColorFilterSettings.kt

@@ -1,202 +0,0 @@
-package eu.kanade.tachiyomi.ui.reader.setting
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.LayoutInflater
-import androidx.annotation.ColorInt
-import androidx.core.graphics.alpha
-import androidx.core.graphics.blue
-import androidx.core.graphics.green
-import androidx.core.graphics.red
-import androidx.core.widget.NestedScrollView
-import androidx.lifecycle.lifecycleScope
-import eu.kanade.tachiyomi.databinding.ReaderColorFilterSettingsBinding
-import eu.kanade.tachiyomi.ui.reader.ReaderActivity
-import eu.kanade.tachiyomi.util.preference.bindToPreference
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.flow.sample
-import tachiyomi.core.preference.getAndSet
-import uy.kohesive.injekt.injectLazy
-
-/**
- * Color filter sheet to toggle custom filter and brightness overlay.
- */
-class ReaderColorFilterSettings @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
-    NestedScrollView(context, attrs) {
-
-    private val readerPreferences: ReaderPreferences by injectLazy()
-
-    private val binding = ReaderColorFilterSettingsBinding.inflate(LayoutInflater.from(context), this, false)
-
-    init {
-        addView(binding.root)
-
-        readerPreferences.colorFilter().changes()
-            .onEach(::setColorFilter)
-            .launchIn((context as ReaderActivity).lifecycleScope)
-
-        readerPreferences.colorFilterMode().changes()
-            .onEach { setColorFilter(readerPreferences.colorFilter().get()) }
-            .launchIn(context.lifecycleScope)
-
-        readerPreferences.customBrightness().changes()
-            .onEach(::setCustomBrightness)
-            .launchIn(context.lifecycleScope)
-
-        // Get color and update values
-        val color = readerPreferences.colorFilterValue().get()
-        val brightness = readerPreferences.customBrightnessValue().get()
-
-        val argb = setValues(color)
-
-        // Set brightness value
-        binding.txtBrightnessSeekbarValue.text = brightness.toString()
-        binding.sliderBrightness.value = brightness.toFloat()
-
-        // Initialize seekBar progress
-        binding.sliderColorFilterAlpha.value = argb[0].toFloat()
-        binding.sliderColorFilterRed.value = argb[1].toFloat()
-        binding.sliderColorFilterGreen.value = argb[2].toFloat()
-        binding.sliderColorFilterBlue.value = argb[3].toFloat()
-
-        // Set listeners
-        binding.switchColorFilter.bindToPreference(readerPreferences.colorFilter())
-        binding.customBrightness.bindToPreference(readerPreferences.customBrightness())
-        binding.colorFilterMode.bindToPreference(readerPreferences.colorFilterMode())
-        binding.grayscale.bindToPreference(readerPreferences.grayscale())
-        binding.invertedColors.bindToPreference(readerPreferences.invertedColors())
-
-        binding.sliderColorFilterAlpha.addOnChangeListener { _, value, fromUser ->
-            if (fromUser) {
-                setColorValue(value.toInt(), ALPHA_MASK, 24)
-            }
-        }
-        binding.sliderColorFilterRed.addOnChangeListener { _, value, fromUser ->
-            if (fromUser) {
-                setColorValue(value.toInt(), RED_MASK, 16)
-            }
-        }
-        binding.sliderColorFilterGreen.addOnChangeListener { _, value, fromUser ->
-            if (fromUser) {
-                setColorValue(value.toInt(), GREEN_MASK, 8)
-            }
-        }
-        binding.sliderColorFilterBlue.addOnChangeListener { _, value, fromUser ->
-            if (fromUser) {
-                setColorValue(value.toInt(), BLUE_MASK, 0)
-            }
-        }
-
-        binding.sliderBrightness.addOnChangeListener { _, value, fromUser ->
-            if (fromUser) {
-                readerPreferences.customBrightnessValue().set(value.toInt())
-            }
-        }
-    }
-
-    /**
-     * Set enabled status of seekBars belonging to color filter
-     * @param enabled determines if seekBar gets enabled
-     */
-    private fun setColorFilterSeekBar(enabled: Boolean) {
-        binding.sliderColorFilterRed.isEnabled = enabled
-        binding.sliderColorFilterGreen.isEnabled = enabled
-        binding.sliderColorFilterBlue.isEnabled = enabled
-        binding.sliderColorFilterAlpha.isEnabled = enabled
-    }
-
-    /**
-     * Set enabled status of seekBars belonging to custom brightness
-     * @param enabled value which determines if seekBar gets enabled
-     */
-    private fun setCustomBrightnessSeekBar(enabled: Boolean) {
-        binding.sliderBrightness.isEnabled = enabled
-    }
-
-    /**
-     * Set the text value's of color filter
-     * @param color integer containing color information
-     */
-    private fun setValues(color: Int): Array<Int> {
-        val alpha = color.alpha
-        val red = color.red
-        val green = color.green
-        val blue = color.blue
-
-        // Initialize values
-        binding.txtColorFilterAlphaValue.text = "$alpha"
-        binding.txtColorFilterRedValue.text = "$red"
-        binding.txtColorFilterGreenValue.text = "$green"
-        binding.txtColorFilterBlueValue.text = "$blue"
-
-        return arrayOf(alpha, red, green, blue)
-    }
-
-    /**
-     * Manages the custom brightness value subscription
-     * @param enabled determines if the subscription get (un)subscribed
-     */
-    private fun setCustomBrightness(enabled: Boolean) {
-        if (enabled) {
-            readerPreferences.customBrightnessValue().changes()
-                .sample(100)
-                .onEach(::setCustomBrightnessValue)
-                .launchIn((context as ReaderActivity).lifecycleScope)
-        } else {
-            setCustomBrightnessValue(0, true)
-        }
-        setCustomBrightnessSeekBar(enabled)
-    }
-
-    /**
-     * Sets the brightness of the screen. Range is [-75, 100].
-     * From -75 to -1 a semi-transparent black view is shown at the top with the minimum brightness.
-     * From 1 to 100 it sets that value as brightness.
-     * 0 sets system brightness and hides the overlay.
-     */
-    private fun setCustomBrightnessValue(value: Int, isDisabled: Boolean = false) {
-        if (!isDisabled) {
-            binding.txtBrightnessSeekbarValue.text = value.toString()
-        }
-    }
-
-    /**
-     * Manages the color filter value subscription
-     * @param enabled determines if the subscription get (un)subscribed
-     */
-    private fun setColorFilter(enabled: Boolean) {
-        if (enabled) {
-            readerPreferences.colorFilterValue().changes()
-                .sample(100)
-                .onEach(::setColorFilterValue)
-                .launchIn((context as ReaderActivity).lifecycleScope)
-        }
-        setColorFilterSeekBar(enabled)
-    }
-
-    /**
-     * Sets the color filter overlay of the screen. Determined by HEX of integer
-     * @param color hex of color.
-     */
-    private fun setColorFilterValue(@ColorInt color: Int) {
-        setValues(color)
-    }
-
-    /**
-     * Updates the color value in preference
-     * @param color value of color range [0,255]
-     * @param mask contains hex mask of chosen color
-     * @param bitShift amounts of bits that gets shifted to receive value
-     */
-    private fun setColorValue(color: Int, mask: Long, bitShift: Int) {
-        readerPreferences.colorFilterValue().getAndSet { currentColor ->
-            (color shl bitShift) or (currentColor and mask.inv().toInt())
-        }
-    }
-}
-
-private const val ALPHA_MASK: Long = 0xFF000000
-private const val RED_MASK: Long = 0x00FF0000
-private const val GREEN_MASK: Long = 0x0000FF00
-private const val BLUE_MASK: Long = 0x000000FF

+ 0 - 45
app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderSettingsSheet.kt

@@ -1,46 +1,30 @@
 package eu.kanade.tachiyomi.ui.reader.setting
 
-import android.animation.ValueAnimator
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import com.google.android.material.tabs.TabLayout
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.databinding.CommonTabbedSheetBinding
 import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 import eu.kanade.tachiyomi.widget.ViewPagerAdapter
-import eu.kanade.tachiyomi.widget.listener.SimpleTabSelectedListener
 import eu.kanade.tachiyomi.widget.sheet.BaseBottomSheetDialog
 
 class ReaderSettingsSheet(
     private val activity: ReaderActivity,
-    private val showColorFilterSettings: Boolean = false,
 ) : BaseBottomSheetDialog(activity) {
 
     private val tabs = listOf(
         ReaderReadingModeSettings(activity) to R.string.pref_category_reading_mode,
         ReaderGeneralSettings(activity) to R.string.pref_category_general,
-        ReaderColorFilterSettings(activity) to R.string.custom_filter,
     )
 
-    private val backgroundDimAnimator by lazy {
-        val sheetBackgroundDim = window?.attributes?.dimAmount ?: 0.25f
-        ValueAnimator.ofFloat(sheetBackgroundDim, 0f).also { valueAnimator ->
-            valueAnimator.duration = 250
-            valueAnimator.addUpdateListener {
-                window?.setDimAmount(it.animatedValue as Float)
-            }
-        }
-    }
-
     private lateinit var binding: CommonTabbedSheetBinding
 
     override fun createView(inflater: LayoutInflater): View {
         binding = CommonTabbedSheetBinding.inflate(activity.layoutInflater)
 
         val adapter = Adapter()
-        binding.pager.offscreenPageLimit = 2
         binding.pager.adapter = adapter
         binding.tabs.setupWithViewPager(binding.pager)
 
@@ -52,35 +36,6 @@ class ReaderSettingsSheet(
 
         behavior.isFitToContents = false
         behavior.halfExpandedRatio = 0.25f
-
-        val filterTabIndex = tabs.indexOfFirst { it.first is ReaderColorFilterSettings }
-        binding.tabs.addOnTabSelectedListener(
-            object : SimpleTabSelectedListener() {
-                override fun onTabSelected(tab: TabLayout.Tab?) {
-                    val isFilterTab = tab?.position == filterTabIndex
-
-                    // Remove dimmed backdrop so color filter changes can be previewed
-                    backgroundDimAnimator.run {
-                        if (isFilterTab) {
-                            if (animatedFraction < 1f) {
-                                start()
-                            }
-                        } else if (animatedFraction > 0f) {
-                            reverse()
-                        }
-                    }
-
-                    // Hide toolbars
-                    if (activity.menuVisible != !isFilterTab) {
-                        activity.setMenuVisibility(!isFilterTab)
-                    }
-                }
-            },
-        )
-
-        if (showColorFilterSettings) {
-            binding.tabs.getTabAt(filterTabIndex)?.select()
-        }
     }
 
     private inner class Adapter : ViewPagerAdapter() {

+ 0 - 14
app/src/main/java/eu/kanade/tachiyomi/widget/listener/SimpleTabSelectedListener.kt

@@ -1,14 +0,0 @@
-package eu.kanade.tachiyomi.widget.listener
-
-import com.google.android.material.tabs.TabLayout
-
-open class SimpleTabSelectedListener : TabLayout.OnTabSelectedListener {
-    override fun onTabSelected(tab: TabLayout.Tab?) {
-    }
-
-    override fun onTabUnselected(tab: TabLayout.Tab?) {
-    }
-
-    override fun onTabReselected(tab: TabLayout.Tab?) {
-    }
-}

+ 14 - 1
app/src/main/res/layout/reader_activity.xml

@@ -119,12 +119,25 @@
                     android:background="?attr/selectableItemBackgroundBorderless"
                     android:contentDescription="@string/action_settings"
                     android:padding="@dimen/screen_edge_margin"
-                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintEnd_toStartOf="@+id/action_color_settings"
                     app:layout_constraintStart_toEndOf="@id/action_rotation"
                     app:layout_constraintTop_toTopOf="parent"
                     app:srcCompat="@drawable/ic_settings_24dp"
                     app:tint="?attr/colorOnSurface" />
 
+                <ImageButton
+                    android:id="@+id/action_color_settings"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:background="?attr/selectableItemBackgroundBorderless"
+                    android:contentDescription="@string/custom_filter"
+                    android:padding="@dimen/screen_edge_margin"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toEndOf="@id/action_settings"
+                    app:layout_constraintTop_toTopOf="parent"
+                    app:srcCompat="@drawable/ic_brightness_5_24dp"
+                    app:tint="?attr/colorOnSurface" />
+
             </androidx.constraintlayout.widget.ConstraintLayout>
 
         </LinearLayout>

+ 0 - 269
app/src/main/res/layout/reader_color_filter_settings.xml

@@ -1,269 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <!-- Brightness -->
-
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/custom_brightness"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingHorizontal="16dp"
-            android:paddingVertical="16dp"
-            android:text="@string/pref_custom_brightness"
-            app:layout_constraintTop_toTopOf="parent" />
-
-        <!-- Brightness value -->
-
-        <androidx.appcompat.widget.AppCompatImageView
-            android:id="@+id/txt_brightness_seekbar_icon"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:paddingStart="16dp"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            android:tint="?attr/colorOnBackground"
-            app:layout_constraintBottom_toBottomOf="@id/slider_brightness"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_brightness"
-            app:srcCompat="@drawable/ic_brightness_5_24dp" />
-
-        <com.google.android.material.slider.Slider
-            android:id="@+id/slider_brightness"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="8dp"
-            android:layout_marginEnd="8dp"
-            android:padding="8dp"
-            android:valueFrom="-75.0"
-            android:valueTo="100.0"
-            android:stepSize="1.0"
-            app:layout_constraintEnd_toStartOf="@id/txt_brightness_seekbar_value"
-            app:layout_constraintStart_toEndOf="@id/txt_brightness_seekbar_icon"
-            app:layout_constraintTop_toBottomOf="@id/custom_brightness" />
-
-        <TextView
-            android:id="@+id/txt_brightness_seekbar_value"
-            android:layout_width="30dp"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="16dp"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_brightness"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_brightness"
-            tools:text="50" />
-
-        <!-- Color filter -->
-
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/switch_color_filter"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:paddingHorizontal="16dp"
-            android:paddingVertical="16dp"
-            android:text="@string/pref_custom_color_filter"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/slider_brightness" />
-
-        <!-- Red filter -->
-
-        <TextView
-            android:id="@+id/txt_color_filter_red_symbol"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:paddingStart="16dp"
-            android:text="@string/color_filter_r_value"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_red"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_red" />
-
-        <com.google.android.material.slider.Slider
-            android:id="@+id/slider_color_filter_red"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="8dp"
-            android:layout_marginEnd="8dp"
-            android:stepSize="1.0"
-            android:valueTo="255.0"
-            android:padding="8dp"
-            app:layout_constraintEnd_toStartOf="@id/txt_color_filter_red_value"
-            app:layout_constraintStart_toEndOf="@id/color_filter_symbols_barrier"
-            app:layout_constraintTop_toBottomOf="@id/switch_color_filter" />
-
-        <TextView
-            android:id="@+id/txt_color_filter_red_value"
-            android:layout_width="30dp"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_marginEnd="16dp"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_red"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_red"
-            tools:text="255" />
-
-        <!-- Green filter -->
-
-        <TextView
-            android:id="@+id/txt_color_filter_green_symbol"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:paddingStart="16dp"
-            android:text="@string/color_filter_g_value"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_green"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_green" />
-
-        <com.google.android.material.slider.Slider
-            android:id="@+id/slider_color_filter_green"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="8dp"
-            android:layout_marginEnd="8dp"
-            android:stepSize="1.0"
-            android:valueTo="255.0"
-            android:padding="8dp"
-            app:layout_constraintEnd_toStartOf="@id/txt_color_filter_green_value"
-            app:layout_constraintStart_toEndOf="@id/color_filter_symbols_barrier"
-            app:layout_constraintTop_toBottomOf="@id/slider_color_filter_red" />
-
-        <TextView
-            android:id="@+id/txt_color_filter_green_value"
-            android:layout_width="30dp"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_marginEnd="16dp"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_green"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_green"
-            tools:text="255" />
-
-        <!-- Blue filter -->
-
-        <TextView
-            android:id="@+id/txt_color_filter_blue_symbol"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:paddingStart="16dp"
-            android:text="@string/color_filter_b_value"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_blue"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_blue" />
-
-        <com.google.android.material.slider.Slider
-            android:id="@+id/slider_color_filter_blue"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="8dp"
-            android:layout_marginEnd="8dp"
-            android:stepSize="1.0"
-            android:valueTo="255.0"
-            android:padding="8dp"
-            app:layout_constraintEnd_toStartOf="@id/txt_color_filter_blue_value"
-            app:layout_constraintStart_toEndOf="@id/color_filter_symbols_barrier"
-            app:layout_constraintTop_toBottomOf="@id/slider_color_filter_green" />
-
-        <TextView
-            android:id="@+id/txt_color_filter_blue_value"
-            android:layout_width="30dp"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_marginEnd="16dp"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_blue"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_blue"
-            tools:text="255" />
-
-        <!-- Alpha filter -->
-
-        <TextView
-            android:id="@+id/txt_color_filter_alpha_symbol"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:paddingStart="16dp"
-            android:text="@string/color_filter_a_value"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_alpha"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_alpha" />
-
-        <com.google.android.material.slider.Slider
-            android:id="@+id/slider_color_filter_alpha"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="8dp"
-            android:layout_marginEnd="8dp"
-            android:stepSize="1.0"
-            android:valueTo="255.0"
-            android:padding="8dp"
-            app:layout_constraintEnd_toStartOf="@id/txt_color_filter_alpha_value"
-            app:layout_constraintStart_toEndOf="@id/color_filter_symbols_barrier"
-            app:layout_constraintTop_toBottomOf="@id/slider_color_filter_blue" />
-
-        <TextView
-            android:id="@+id/txt_color_filter_alpha_value"
-            android:layout_width="30dp"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_marginEnd="16dp"
-            android:textAppearance="?attr/textAppearanceTitleSmall"
-            app:layout_constraintBottom_toBottomOf="@id/slider_color_filter_alpha"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="@id/slider_color_filter_alpha"
-            tools:text="255" />
-
-        <!-- Filter mode -->
-
-        <eu.kanade.tachiyomi.widget.MaterialSpinnerView
-            android:id="@+id/color_filter_mode"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:entries="@array/color_filter_modes"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/slider_color_filter_alpha"
-            app:title="@string/pref_color_filter_mode" />
-
-        <!-- Grayscale -->
-
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/grayscale"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingHorizontal="16dp"
-            android:paddingVertical="16dp"
-            android:text="@string/pref_grayscale"
-            android:textColor="?android:attr/textColorSecondary"
-            app:layout_constraintTop_toBottomOf="@id/color_filter_mode" />
-
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/inverted_colors"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingHorizontal="16dp"
-            android:paddingVertical="16dp"
-            android:text="@string/pref_inverted_colors"
-            android:textColor="?android:attr/textColorSecondary"
-            app:layout_constraintTop_toBottomOf="@id/grayscale" />
-
-        <androidx.constraintlayout.widget.Barrier
-            android:id="@+id/color_filter_symbols_barrier"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:barrierDirection="end"
-            app:constraint_referenced_ids="txt_color_filter_alpha_symbol,txt_color_filter_blue_symbol,txt_color_filter_red_symbol,txt_color_filter_green_symbol" />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.core.widget.NestedScrollView>

+ 0 - 15
app/src/main/res/values-v28/arrays.xml

@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string-array name="color_filter_modes">
-        <item>@string/label_default</item>
-        <item>@string/filter_mode_multiply</item>
-        <item>@string/filter_mode_screen</item>
-
-        <!-- Attributes specific for SDK 28 and up  -->
-        <item>@string/filter_mode_overlay</item>
-        <item>@string/filter_mode_lighten</item>
-        <item>@string/filter_mode_darken</item>
-    </string-array>
-
-</resources>

+ 0 - 6
app/src/main/res/values/arrays.xml

@@ -67,12 +67,6 @@
         <item>@string/rotation_reverse_portrait</item>
     </string-array>
 
-    <string-array name="color_filter_modes">
-        <item>@string/label_default</item>
-        <item>@string/filter_mode_multiply</item>
-        <item>@string/filter_mode_screen</item>
-    </string-array>
-
     <string-array name="invert_tapping_mode">
         <item>@string/tapping_inverted_none</item>
         <item>@string/tapping_inverted_horizontal</item>

+ 1 - 1
presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt

@@ -140,7 +140,7 @@ fun RadioItem(
 @Composable
 fun SliderItem(
     label: String,
-    min: Int,
+    min: Int = 0,
     max: Int,
     value: Int,
     valueText: String,