Move to Compose Reader Settings Now (#871)

* Move to Compose Reader Settings Now

* Cleanup res

* Cleanup

* Fix trans

* Fix

---------

Co-authored-by: GG Bond <whatever@tagkong.com>
This commit is contained in:
renovate[bot]andGG Bond authored and GitHub committed 2024-03-07 17:43:41 +08:00
1 parent e47d7378ec
commit 9b9f25d405
36 files changed
+18 -1866

No files matched your search

@@ -18,10 +18,7 @@
package com.hippo.ehviewer.image
import android.graphics.Bitmap
import android.graphics.ColorSpace
import android.graphics.drawable.Animatable
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.ui.unit.IntRect
import arrow.core.Either
import arrow.core.left
@@ -33,7 +30,6 @@ import coil3.imageLoader
import coil3.request.CachePolicy
import coil3.request.ErrorResult
import coil3.request.SuccessResult
import coil3.request.colorSpace
import coil3.size.Precision
import coil3.size.Scale
import com.hippo.ehviewer.Settings
@@ -44,7 +40,6 @@ import com.hippo.ehviewer.jni.mmap
import com.hippo.ehviewer.jni.munmap
import com.hippo.ehviewer.jni.rewriteGifSource
import com.hippo.ehviewer.ktbuilder.imageRequest
import com.hippo.ehviewer.util.isAtLeastO
import com.hippo.ehviewer.util.isAtLeastP
import com.hippo.ehviewer.util.isAtLeastU
import com.hippo.unifile.UniFile
@@ -81,12 +76,6 @@ class Image private constructor(image: CoilImage, private val src: AutoCloseable
private val targetWidth = appCtx.resources.displayMetrics.widthPixels * 2
private val targetHeight = appCtx.resources.displayMetrics.heightPixels * 2
@delegate:RequiresApi(Build.VERSION_CODES.O)
val isWideColorGamut by lazy { appCtx.resources.configuration.isScreenWideColorGamut }
@RequiresApi(Build.VERSION_CODES.O)
lateinit var colorSpace: ColorSpace
private suspend fun Either<ByteBufferSource, UniFileSource>.decodeCoil(): CoilImage {
val req = appCtx.imageRequest {
onLeft { data(it.source) }
@@ -94,9 +83,6 @@ class Image private constructor(image: CoilImage, private val src: AutoCloseable
size(targetWidth, targetHeight)
scale(Scale.FILL)
precision(Precision.INEXACT)
if (isAtLeastO && !Settings.newReader) {
colorSpace(colorSpace)
}
maybeCropBorder(Settings.cropBorder.value)
memoryCachePolicy(CachePolicy.DISABLED)
}
@@ -22,7 +22,6 @@ import android.app.assist.AssistContent
import android.content.ClipData
import android.content.ContentValues
import android.content.Intent
import android.content.pm.ActivityInfo
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Paint
@@ -44,6 +43,7 @@ import androidx.annotation.RequiresApi
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
@@ -78,8 +78,8 @@ import com.hippo.ehviewer.download.archiveFile
import com.hippo.ehviewer.gallery.ArchivePageLoader
import com.hippo.ehviewer.gallery.EhPageLoader
import com.hippo.ehviewer.gallery.PageLoader2
import com.hippo.ehviewer.image.Image
import com.hippo.ehviewer.ui.EhActivity
import com.hippo.ehviewer.ui.reader.SettingsPager
import com.hippo.ehviewer.ui.setMD3Content
import com.hippo.ehviewer.ui.tools.DialogState
import com.hippo.ehviewer.util.AppConfig
@@ -88,7 +88,6 @@ import com.hippo.ehviewer.util.awaitActivityResult
import com.hippo.ehviewer.util.getParcelableCompat
import com.hippo.ehviewer.util.getParcelableExtraCompat
import com.hippo.ehviewer.util.getValue
import com.hippo.ehviewer.util.isAtLeastO
import com.hippo.ehviewer.util.isAtLeastP
import com.hippo.ehviewer.util.isAtLeastQ
import com.hippo.ehviewer.util.lazyMut
@@ -100,7 +99,6 @@ import dev.chrisbanes.insetter.applyInsetter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsSheet
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
@@ -109,6 +107,7 @@ import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.isNightMode
import eu.kanade.tachiyomi.util.system.logcat
import java.io.File
import kotlin.coroutines.resume
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.debounce
@@ -252,13 +251,6 @@ class ReaderActivity : EhActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (isAtLeastO) {
window.colorMode = if (Image.isWideColorGamut && ReaderPreferences.wideColorGamut().get()) {
ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT
} else {
ActivityInfo.COLOR_MODE_DEFAULT
}
}
if (savedInstanceState == null) {
onInit()
} else {
@@ -300,7 +292,21 @@ class ReaderActivity : EhActivity() {
sliderValueFlow.value = it
currentPage = it + 1
},
onClickSettings = { readerSettingSheetDialog?.show() },
onClickSettings = {
lifecycleScope.launch {
dialogState.dialog { cont ->
fun dispose() = cont.resume(Unit)
ModalBottomSheet(
onDismissRequest = { dispose() },
dragHandle = null,
windowInsets = WindowInsets(0),
) {
SettingsPager(modifier = Modifier.fillMaxSize())
Spacer(modifier = Modifier.navigationBarsPadding())
}
}
}
},
)
ReaderContentOverlay(
@@ -358,8 +364,6 @@ class ReaderActivity : EhActivity() {
config = null
viewer?.destroy()
viewer = null
readerSettingSheetDialog?.dismiss()
readerSettingSheetDialog = null
}
private suspend fun makeToast(text: String) = withUIContext {
@@ -521,8 +525,6 @@ class ReaderActivity : EhActivity() {
)
}
private var readerSettingSheetDialog: ReaderSettingsSheet? = null
/**
* Sets the visibility of the menu according to [visible] and with an optional parameter to
* [animate] the views.
@@ -574,8 +576,6 @@ class ReaderActivity : EhActivity() {
}
}
readerSettingSheetDialog = ReaderSettingsSheet(this@ReaderActivity)
val toolbarBackground = MaterialShapeDrawable.createWithElevationOverlay(this).apply {
elevation = resources.getDimension(com.google.android.material.R.dimen.m3_sys_elevation_level2)
alpha = if (isNightMode()) 230 else 242 // 90% dark 95% light
@@ -758,7 +758,6 @@ class ReaderActivity : EhActivity() {
ReaderPreferences.cutoutShort().changes()
.drop(1)
.onEach {
readerSettingSheetDialog?.hide()
setCutoutShort(it)
recreate()
}
@@ -1,230 +0,0 @@
package eu.kanade.tachiyomi.ui.reader.setting
import android.content.Context
import android.content.pm.ActivityInfo
import android.graphics.ColorSpace
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.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.lifecycleScope
import com.hippo.ehviewer.databinding.ReaderColorFilterSettingsBinding
import com.hippo.ehviewer.image.Image
import com.hippo.ehviewer.util.isAtLeastO
import eu.kanade.tachiyomi.core.preference.getAndSet
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.util.preference.bindToPreference
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.sample
/**
* 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 = ReaderPreferences
private val binding = ReaderColorFilterSettingsBinding.inflate(LayoutInflater.from(context), this, false)
init {
addView(binding.root)
context as ReaderActivity
if (isAtLeastO) {
binding.wideColorGamut.isEnabled = Image.isWideColorGamut
if (!Image.isWideColorGamut) {
readerPreferences.wideColorGamut().set(false)
}
binding.wideColorGamut.bindToPreference(readerPreferences.wideColorGamut())
readerPreferences.wideColorGamut().asHotFlow {
Image.colorSpace = ColorSpace.get(if (Image.isWideColorGamut && it) ColorSpace.Named.DISPLAY_P3 else ColorSpace.Named.SRGB)
val colorMode = if (Image.isWideColorGamut && it) ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT else ActivityInfo.COLOR_MODE_DEFAULT
with(context) {
if (window.colorMode != colorMode) {
window.colorMode = colorMode
restartGalleryProvider()
}
}
}.launchIn(context.lifecycleScope)
} else {
binding.wideColorGamut.isVisible = false
}
readerPreferences.colorFilter().changes()
.onEach { setColorFilter(it) }
.launchIn(context.lifecycleScope)
readerPreferences.colorFilterMode().changes()
.onEach { setColorFilter(readerPreferences.colorFilter().get()) }
.launchIn(context.lifecycleScope)
readerPreferences.customBrightness().changes()
.onEach { setCustomBrightness(it) }
.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(it) }
.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(it) }
.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
@@ -1,67 +0,0 @@
package eu.kanade.tachiyomi.ui.reader.setting
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.lifecycleScope
import com.hippo.ehviewer.R
import com.hippo.ehviewer.databinding.ReaderGeneralSettingsBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.util.preference.bindToPreference
import kotlinx.coroutines.flow.launchIn
/**
* Sheet to show reader and viewer preferences.
*/
class ReaderGeneralSettings @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
NestedScrollView(context, attrs) {
private val readerPreferences: ReaderPreferences = ReaderPreferences
private val binding = ReaderGeneralSettingsBinding.inflate(LayoutInflater.from(context), this, false)
init {
addView(binding.root)
initGeneralPreferences()
}
/**
* Init general reader preferences.
*/
private fun initGeneralPreferences() {
binding.backgroundColor.bindToIntPreference(readerPreferences.readerTheme(), R.array.reader_themes_values)
binding.showPageNumber.bindToPreference(readerPreferences.showPageNumber())
binding.showReaderSeekbar.bindToPreference(readerPreferences.showReaderSeekbar())
binding.doubleTapToZoom.bindToPreference(readerPreferences.doubleTapToZoom())
binding.fullscreen.bindToPreference(readerPreferences.fullscreen())
readerPreferences.fullscreen()
.asHotFlow {
// If the preference is explicitly disabled, that means the setting was configured since there is a cutout
binding.cutoutShort.isVisible = it && ((context as ReaderActivity).hasCutout || !readerPreferences.cutoutShort().get())
binding.cutoutShort.bindToPreference(readerPreferences.cutoutShort())
}
.launchIn((context as ReaderActivity).lifecycleScope)
binding.keepscreen.bindToPreference(readerPreferences.keepScreenOn())
binding.longTap.bindToPreference(readerPreferences.readWithLongTap())
binding.pageTransitions.bindToPreference(readerPreferences.pageTransitions())
binding.volumePage.bindToPreference(readerPreferences.readWithVolumeKeys())
binding.reserveVolumePage.bindToPreference(readerPreferences.readWithVolumeKeysInverted())
readerPreferences.readWithVolumeKeys().asHotFlow {
binding.volumePageSpeed.isVisible = it
binding.reserveVolumePage.isVisible = it
}.launchIn((context as ReaderActivity).lifecycleScope)
val volumePageInterval = readerPreferences.readWithVolumeKeysInterval().get()
binding.sliderVolumePageInterval.value = volumePageInterval.toFloat()
binding.sliderVolumePageInterval.addOnChangeListener { _, value, fromUser ->
if (fromUser) {
readerPreferences.readWithVolumeKeysInterval().set(value.toInt())
}
}
}
}
@@ -1,136 +0,0 @@
package eu.kanade.tachiyomi.ui.reader.setting
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.lifecycleScope
import com.hippo.ehviewer.R
import com.hippo.ehviewer.databinding.ReaderReadingModeSettingsBinding
import eu.kanade.tachiyomi.data.preference.PreferenceValues
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerViewer
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer
import eu.kanade.tachiyomi.util.preference.asHotFlow
import eu.kanade.tachiyomi.util.preference.bindToPreference
import kotlinx.coroutines.flow.launchIn
/**
* Sheet to show reader and viewer preferences.
*/
class ReaderReadingModeSettings @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
) :
NestedScrollView(context, attrs) {
private val readerPreferences: ReaderPreferences = ReaderPreferences
private val binding =
ReaderReadingModeSettingsBinding.inflate(LayoutInflater.from(context), this, false)
init {
addView(binding.root)
initGeneralPreferences()
when ((context as ReaderActivity).viewer) {
is PagerViewer -> initPagerPreferences()
is WebtoonViewer -> initWebtoonPreferences()
}
}
/**
* Init general reader preferences.
*/
private fun initGeneralPreferences() {
binding.viewer.onItemSelectedListener = { position ->
val readingModeType = ReadingModeType.fromSpinner(position)
ReaderPreferences.defaultReadingMode().set(readingModeType.flagValue)
if (readingModeType == ReadingModeType.WEBTOON || readingModeType == ReadingModeType.CONTINUOUS_VERTICAL) {
initWebtoonPreferences()
} else {
initPagerPreferences()
}
}
binding.viewer.setSelection(
ReaderPreferences.defaultReadingMode().get()
.let { ReadingModeType.fromPreference(it).prefValue },
)
binding.rotationMode.onItemSelectedListener = { position ->
val rotationType = OrientationType.fromSpinner(position)
readerPreferences.defaultOrientationType().set(rotationType.flagValue)
}
binding.rotationMode.setSelection(
ReaderPreferences.defaultOrientationType().get()
.let { OrientationType.fromPreference(it).prefValue },
)
}
/**
* Init the preferences for the pager reader.
*/
private fun initPagerPreferences() {
binding.webtoonPrefsGroup.root.isVisible = false
binding.pagerPrefsGroup.root.isVisible = true
binding.pagerPrefsGroup.tappingInverted.bindToPreference(
readerPreferences.pagerNavInverted(),
PreferenceValues.TappingInvertMode::class.java,
)
binding.pagerPrefsGroup.navigatePan.bindToPreference(readerPreferences.navigateToPan())
binding.pagerPrefsGroup.pagerNav.bindToPreference(readerPreferences.navigationModePager())
readerPreferences.navigationModePager()
.asHotFlow {
val isTappingEnabled = it != 5
binding.pagerPrefsGroup.tappingInverted.isVisible = isTappingEnabled
binding.pagerPrefsGroup.navigatePan.isVisible = isTappingEnabled
}
.launchIn((context as ReaderActivity).lifecycleScope)
// Makes so that landscape zoom gets hidden away when image scale type is not fit screen
binding.pagerPrefsGroup.scaleType.bindToPreference(readerPreferences.imageScaleType(), 1)
readerPreferences.imageScaleType()
.asHotFlow { binding.pagerPrefsGroup.landscapeZoom.isVisible = it == 1 }
.launchIn((context as ReaderActivity).lifecycleScope)
binding.pagerPrefsGroup.landscapeZoom.bindToPreference(readerPreferences.landscapeZoom())
binding.pagerPrefsGroup.zoomStart.bindToPreference(readerPreferences.zoomStart(), 1)
binding.pagerPrefsGroup.cropBorders.bindToPreference(readerPreferences.cropBorders())
}
/**
* Init the preferences for the webtoon reader.
*/
private fun initWebtoonPreferences() {
binding.pagerPrefsGroup.root.isVisible = false
binding.webtoonPrefsGroup.root.isVisible = true
binding.webtoonPrefsGroup.tappingInverted.bindToPreference(
readerPreferences.webtoonNavInverted(),
PreferenceValues.TappingInvertMode::class.java,
)
binding.webtoonPrefsGroup.webtoonNav.bindToPreference(readerPreferences.navigationModeWebtoon())
readerPreferences.navigationModeWebtoon()
.asHotFlow { binding.webtoonPrefsGroup.tappingInverted.isVisible = it != 5 }
.launchIn((context as ReaderActivity).lifecycleScope)
binding.webtoonPrefsGroup.cropBordersWebtoon.bindToPreference(readerPreferences.cropBorders())
binding.webtoonPrefsGroup.webtoonSidePadding.bindToIntPreference(
readerPreferences.webtoonSidePadding(),
R.array.webtoon_side_padding_values,
)
}
fun init() {
initGeneralPreferences()
when ((context as ReaderActivity).viewer) {
is PagerViewer -> initPagerPreferences()
is WebtoonViewer -> initWebtoonPreferences()
}
}
}
@@ -1,98 +0,0 @@
package eu.kanade.tachiyomi.ui.reader.setting
import android.animation.ValueAnimator
import android.os.Build
import android.os.Bundle
import com.google.android.material.tabs.TabLayout
import com.hippo.ehviewer.R
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.widget.listener.SimpleTabSelectedListener
import eu.kanade.tachiyomi.widget.sheet.TabbedBottomSheetDialog
class ReaderSettingsSheet(
private val activity: ReaderActivity,
private val showColorFilterSettings: Boolean = false,
) : TabbedBottomSheetDialog(activity) {
private lateinit var readingModeSettings: ReaderReadingModeSettings
private lateinit var generalSettings: ReaderGeneralSettings
private lateinit var colorFilterSettings: ReaderColorFilterSettings
init {
initSettings()
}
private fun initSettings() {
readingModeSettings = ReaderReadingModeSettings(activity)
generalSettings = ReaderGeneralSettings(activity)
colorFilterSettings = ReaderColorFilterSettings(activity)
}
private val backgroundDimAnimator by lazy {
val sheetBackgroundDim = window?.attributes?.dimAmount ?: 0.25f
ValueAnimator.ofFloat(sheetBackgroundDim, 0f).also { valueAnimator ->
valueAnimator.duration = 250
valueAnimator.addUpdateListener {
window?.run {
setDimAmount(it.animatedValue as Float)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
attributes.blurBehindRadius = (it.animatedValue as Float * 50).toInt()
}
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
behavior.isFitToContents = false
behavior.halfExpandedRatio = 0.25f
val filterTabIndex = getTabViews().indexOf(colorFilterSettings)
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()
}
}
override fun getTabViews() = listOf(
readingModeSettings,
generalSettings,
colorFilterSettings,
)
override fun getTabTitles() = listOf(
R.string.pref_category_reading_mode,
R.string.pref_category_general,
R.string.custom_filter,
)
override fun show() {
readingModeSettings.init()
super.show()
}
}
@@ -1,28 +0,0 @@
package eu.kanade.tachiyomi.util.preference
import android.widget.CompoundButton
import eu.kanade.tachiyomi.core.preference.Preference
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onEach
/**
* Binds a checkbox or switch view with a boolean preference.
*/
fun CompoundButton.bindToPreference(pref: Preference<Boolean>) {
isChecked = pref.get()
setOnCheckedChangeListener { _, isChecked -> pref.set(isChecked) }
}
fun <T> Preference<T>.asHotFlow(block: (T) -> Unit): Flow<T> {
block(get())
return changes()
.onEach { block(it) }
}
operator fun <T> Preference<Set<T>>.plusAssign(item: T) {
set(get() + item)
}
operator fun <T> Preference<Set<T>>.minusAssign(item: T) {
set(get() - item)
}
@@ -3,41 +3,10 @@ package eu.kanade.tachiyomi.util.system
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.Color
import android.os.Build
import android.provider.Settings
import android.view.Display
import android.view.View
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.graphics.alpha
import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
import com.hippo.ehviewer.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import kotlin.math.roundToInt
import splitties.systemservices.windowManager
/**
* Returns the color for the given attribute.
*
* @param resource the attribute.
* @param alphaFactor the alpha number [0,1].
*/
@ColorInt fun Context.getResourceColor(@AttrRes resource: Int, alphaFactor: Float = 1f): Int {
val typedArray = obtainStyledAttributes(intArrayOf(resource))
val color = typedArray.getColor(0, 0)
typedArray.recycle()
if (alphaFactor < 1f) {
val alpha = (color.alpha * alphaFactor).roundToInt()
return Color.argb(alpha, color.red, color.green, color.blue)
}
return color
}
/**
* Converts to px.
@@ -45,20 +14,6 @@ import splitties.systemservices.windowManager
val Int.dpToPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.pxToDp: Float
get() = (this / Resources.getSystem().displayMetrics.density)
val Resources.isLTR
get() = configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR
val Context.displayCompat: Display?
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
display
} else {
@Suppress("DEPRECATION")
windowManager.defaultDisplay
}
/** Gets the duration multiplier for general animations on the device
* @see Settings.Global.ANIMATOR_DURATION_SCALE
*/
@@ -67,24 +22,10 @@ val Context.animatorDurationScale: Float
private const val TABLET_UI_REQUIRED_SCREEN_WIDTH_DP = 720
// some tablets have screen width like 711dp = 1600px / 2.25
private const val TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP = 700
// make sure icons on the nav rail fit
private const val TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP = 600
fun Context.isTabletUi(): Boolean {
return resources.configuration.isTabletUi()
}
fun Configuration.isTabletUi(): Boolean {
return smallestScreenWidthDp >= TABLET_UI_REQUIRED_SCREEN_WIDTH_DP
}
fun Configuration.isAutoTabletUiAvailable(): Boolean {
return smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
}
/**
* Returns true if current context is in night mode
*/
@@ -92,14 +33,6 @@ fun Context.isNightMode(): Boolean {
return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
}
/**
* Gets system's config_navBarNeedsScrim boolean flag added in Android 10, defaults to true.
*/
fun Context.isNavigationBarNeedsScrim(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ||
InternalResourceHelper.getBoolean(this, "config_navBarNeedsScrim", true)
}
/**
* Creates night mode Context depending on reader theme/background
*
@@ -1,28 +0,0 @@
package eu.kanade.tachiyomi.util.system
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
object InternalResourceHelper {
fun getBoolean(context: Context, resName: String, defaultValue: Boolean): Boolean {
val id = getResourceId(resName, "bool")
return if (id != 0) {
context.createPackageContext("android", 0).resources.getBoolean(id)
} else {
defaultValue
}
}
/**
* Get resource id from system resources
* @param resName resource name to get
* @param type resource type of [resName] to get
* @return 0 if not available
*/
@SuppressLint("DiscouragedApi")
private fun getResourceId(resName: String, type: String): Int {
return Resources.getSystem().getIdentifier(resName, type, "android")
}
}
@@ -1,22 +1,8 @@
package eu.kanade.tachiyomi.util.view
import android.content.Context
import android.content.res.Resources
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.view.View
import com.google.android.material.shape.MaterialShapeDrawable
/**
* Returns a deep copy of the provided [Drawable]
*/
inline fun <reified T : Drawable> T.copy(context: Context): T? {
return (constantState?.newDrawable()?.mutate() as? T).apply {
if (this is MaterialShapeDrawable) {
initializeElevationOverlay(context)
}
}
}
fun View?.isVisibleOnScreen(): Boolean {
if (this == null) {
@@ -1,30 +1,7 @@
package eu.kanade.tachiyomi.util.view
import android.content.Context
import android.graphics.Color
import android.view.Window
import android.view.WindowManager
import com.google.android.material.elevation.ElevationOverlayProvider
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.isNavigationBarNeedsScrim
/**
* Sets navigation bar color to transparent if system's config_navBarNeedsScrim is false,
* otherwise it will use the theme navigationBarColor with 70% opacity.
*
* @see isNavigationBarNeedsScrim
*/
fun Window.setNavigationBarTransparentCompat(context: Context, elevation: Float = 0F) {
navigationBarColor = if (context.isNavigationBarNeedsScrim()) {
// Set navbar scrim 70% of navigationBarColor
ElevationOverlayProvider(context).compositeOverlayIfNeeded(
context.getResourceColor(android.R.attr.navigationBarColor, 0.7F),
elevation,
)
} else {
Color.TRANSPARENT
}
}
fun Window.setSecureScreen(enabled: Boolean) {
if (enabled) {
@@ -1,169 +0,0 @@
package eu.kanade.tachiyomi.widget
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MenuItem
import android.widget.FrameLayout
import androidx.annotation.ArrayRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.withStyledAttributes
import androidx.core.view.forEach
import androidx.core.view.get
import androidx.core.view.size
import com.hippo.ehviewer.R
import com.hippo.ehviewer.databinding.PrefSpinnerBinding
import eu.kanade.tachiyomi.core.preference.Preference
import eu.kanade.tachiyomi.util.system.getResourceColor
class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
FrameLayout(context, attrs) {
private var entries = emptyList<String>()
private var selectedPosition = 0
private var popup: PopupMenu? = null
var onItemSelectedListener: ((Int) -> Unit)? = null
set(value) {
field = value
if (value != null) {
popup = makeSettingsPopup()
setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener {
popup?.show()
}
}
}
private val emptyIcon by lazy {
AppCompatResources.getDrawable(context, R.drawable.ic_blank_24dp)
}
private val checkmarkIcon by lazy {
AppCompatResources.getDrawable(context, R.drawable.ic_check_24dp)?.mutate()?.apply {
setTint(context.getResourceColor(android.R.attr.textColorPrimary))
}
}
private val binding = PrefSpinnerBinding.inflate(LayoutInflater.from(context), this, false)
init {
addView(binding.root)
context.withStyledAttributes(set = attrs, attrs = R.styleable.MaterialSpinnerView) {
val title = getString(R.styleable.MaterialSpinnerView_title).orEmpty()
binding.title.text = title
val viewEntries = (
getTextArray(R.styleable.MaterialSpinnerView_android_entries)
?: emptyArray()
).map { it.toString() }
entries = viewEntries
binding.details.text = viewEntries.firstOrNull().orEmpty()
}
}
fun setSelection(selection: Int) {
if (selectedPosition < (popup?.menu?.size ?: 0)) {
popup?.menu?.getItem(selectedPosition)?.let {
it.icon = emptyIcon
}
}
selectedPosition = selection
if (selectedPosition < (popup?.menu?.size ?: 0)) {
popup?.menu?.getItem(selectedPosition)?.let {
it.icon = checkmarkIcon
}
}
binding.details.text = entries.getOrNull(selection).orEmpty()
}
fun bindToPreference(pref: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null) {
setSelection(pref.get() - offset)
popup = makeSettingsPopup(pref, offset, block)
setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener {
popup?.show()
}
}
fun <T : Enum<T>> bindToPreference(pref: Preference<T>, clazz: Class<T>) {
val enumConstants = clazz.enumConstants
enumConstants?.indexOf(pref.get())?.let { setSelection(it) }
popup = makeSettingsPopup(pref, clazz)
setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener {
popup?.show()
}
}
fun bindToIntPreference(pref: Preference<Int>, @ArrayRes intValuesResource: Int, block: ((Int) -> Unit)? = null) {
val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
setSelection(intValues.indexOf(pref.get()))
popup = makeSettingsPopup(pref, intValues, block)
setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener {
popup?.show()
}
}
private fun <T : Enum<T>> makeSettingsPopup(preference: Preference<T>, clazz: Class<T>): PopupMenu {
return createPopupMenu { pos ->
onItemSelectedListener?.invoke(pos)
val enumConstants = clazz.enumConstants
enumConstants?.get(pos)?.let { enumValue -> preference.set(enumValue) }
}
}
private fun makeSettingsPopup(preference: Preference<Int>, intValues: List<Int?>, block: ((Int) -> Unit)? = null): PopupMenu {
return createPopupMenu { pos ->
preference.set(intValues[pos] ?: 0)
block?.invoke(pos)
}
}
private fun makeSettingsPopup(preference: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null): PopupMenu {
return createPopupMenu { pos ->
preference.set(pos + offset)
block?.invoke(pos)
}
}
private fun makeSettingsPopup(): PopupMenu {
return createPopupMenu { pos ->
onItemSelectedListener?.invoke(pos)
}
}
private fun menuClicked(menuItem: MenuItem): Int {
val pos = menuItem.itemId
setSelection(pos)
return pos
}
@SuppressLint("RestrictedApi")
fun createPopupMenu(onItemClick: (Int) -> Unit): PopupMenu {
val popup = PopupMenu(context, this, Gravity.END, androidx.appcompat.R.attr.actionOverflowMenuStyle, 0)
entries.forEachIndexed { index, entry ->
popup.menu.add(0, index, 0, entry)
}
(popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
popup.menu.forEach {
it.icon = emptyIcon
}
popup.menu[selectedPosition].icon = checkmarkIcon
popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem)
onItemClick(pos)
true
}
return popup
}
}
@@ -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?) {
}
}
@@ -1,55 +0,0 @@
package eu.kanade.tachiyomi.widget.sheet
import android.content.Context
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.hippo.ehviewer.R
import com.hippo.ehviewer.util.isAtLeastO
import eu.kanade.tachiyomi.util.system.displayCompat
import eu.kanade.tachiyomi.util.system.isNightMode
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
abstract class BaseBottomSheetDialog(context: Context) : BottomSheetDialog(context) {
abstract fun createView(inflater: LayoutInflater): View
@Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val rootView = createView(layoutInflater)
setContentView(rootView)
// Enforce max width for tablets
val width = context.resources.getDimensionPixelSize(R.dimen.bottom_sheet_width)
if (width > 0) {
behavior.maxWidth = width
}
// Set peek height to 50% display height
context.displayCompat?.let {
val metrics = DisplayMetrics()
it.getRealMetrics(metrics)
behavior.peekHeight = metrics.heightPixels / 2
}
// Set navbar color to transparent for edge-to-edge bottom sheet if we can use light navigation bar
// TODO Replace deprecated systemUiVisibility when material-components uses new API to modify status bar icons
// window?.setNavigationBarTransparentCompat(context, behavior.getElevation())
if (isAtLeastO) {
window?.setNavigationBarTransparentCompat(context, 0f)
val bottomSheet = rootView.parent as ViewGroup
var flags = bottomSheet.systemUiVisibility
flags = if (context.isNightMode()) {
flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
} else {
flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
}
bottomSheet.systemUiVisibility = flags
}
}
}
@@ -1,56 +0,0 @@
package eu.kanade.tachiyomi.widget.sheet
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.viewpager.widget.ViewPager
import java.lang.reflect.Field
/**
* From https://github.com/kafumi/android-bottomsheet-viewpager
*/
class BottomSheetViewPager @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
) : ViewPager(context, attrs) {
private val positionField: Field = LayoutParams::class.java.getDeclaredField("position").also {
it.isAccessible = true
}
override fun getChildAt(index: Int): View {
val currentView = getCurrentView() ?: return super.getChildAt(index)
return if (index == 0) {
currentView
} else {
var view = super.getChildAt(index)
if (view == currentView) {
view = super.getChildAt(0)
}
return view
}
}
private fun getCurrentView(): View? {
for (i in 0 until childCount) {
val child = super.getChildAt(i)
val lp = child.layoutParams as? LayoutParams
if (lp != null) {
val position = positionField.getInt(lp)
if (!lp.isDecor && currentItem == position) {
return child
}
}
}
return null
}
init {
addOnPageChangeListener(
object : SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
requestLayout()
}
},
)
}
}
@@ -1,43 +0,0 @@
package eu.kanade.tachiyomi.widget.sheet
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.hippo.ehviewer.databinding.CommonTabbedSheetBinding
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
abstract class TabbedBottomSheetDialog(private val activity: Activity) : BaseBottomSheetDialog(activity) {
lateinit var binding: CommonTabbedSheetBinding
override fun createView(inflater: LayoutInflater): View {
binding = CommonTabbedSheetBinding.inflate(activity.layoutInflater)
val adapter = LibrarySettingsSheetAdapter()
binding.pager.offscreenPageLimit = 2
binding.pager.adapter = adapter
binding.tabs.setupWithViewPager(binding.pager)
return binding.root
}
abstract fun getTabViews(): List<View>
abstract fun getTabTitles(): List<Int>
private inner class LibrarySettingsSheetAdapter : ViewPagerAdapter() {
override fun createView(container: ViewGroup, position: Int): View {
return getTabViews()[position]
}
override fun getCount(): Int {
return getTabViews().size
}
override fun getPageTitle(position: Int): CharSequence {
return activity.resources!!.getString(getTabTitles()[position])
}
}
}
@@ -1,7 +0,0 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="24dp"
android:height="24dp" />
<solid android:color="@android:color/transparent" />
</shape>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:pathData="M20,15.31L23.31,12 20,8.69V4h-4.69L12,0.69 8.69,4H4v4.69L0.69,12 4,15.31V20h4.69L12,23.31 15.31,20H20v-4.69zM12,18c-3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6 6,2.69 6,6 -2.69,6 -6,6z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@android:color/black"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z" />
</vector>
@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>
@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
</shape>
</item>
<item
android:gravity="bottom">
<shape>
<size android:height="1dp" />
<solid android:color="?attr/colorSurfaceVariant" />
</shape>
</item>
</layer-list>
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/transparent_tabs_background">
<!-- Remove background color so rounded sheet corners work -->
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/menu"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabGravity="fill"
app:tabMode="fixed" />
<ImageButton
android:id="@+id/menu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/action_menu"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_overflow_24dp"
app:tint="?attr/colorOnSurface"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
<eu.kanade.tachiyomi.widget.sheet.BottomSheetViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
-58
View File
@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="?attr/listPreferredItemHeightSmall"
android:background="?attr/selectableItemBackground"
android:paddingStart="16dp"
android:paddingEnd="16dp">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingEnd="8dp"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/center_guideline"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/details"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/dropdown_caret"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/center_guideline"
app:layout_constraintTop_toTopOf="parent"
tools:text="Details" />
<ImageView
android:id="@+id/dropdown_caret"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="1dp"
android:src="@drawable/ic_expand_more_24dp"
app:layout_constraintBottom_toBottomOf="@id/details"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/details"
app:tint="?android:attr/colorControlNormal"
tools:ignore="ContentDescription" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/center_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -1,279 +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">
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/wide_color_gamut"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/wide_color_gamut"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintTop_toTopOf="parent" />
<!-- 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_toBottomOf="@id/wide_color_gamut" />
<!-- 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:stepSize="1.0"
android:valueFrom="-75.0"
android:valueTo="100.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:padding="8dp"
android:stepSize="1.0"
android:valueTo="255.0"
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:padding="8dp"
android:stepSize="1.0"
android:valueTo="255.0"
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:padding="8dp"
android:stepSize="1.0"
android:valueTo="255.0"
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:padding="8dp"
android:stepSize="1.0"
android:valueTo="255.0"
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>
@@ -1,154 +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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/background_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/reader_themes"
app:title="@string/pref_reader_theme" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/show_page_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_show_page_number"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/show_reader_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_show_reader_seekbar"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/double_tap_to_zoom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_double_tap_to_zoom"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/fullscreen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_fullscreen"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/cutout_short"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_cutout_short"
android:textColor="?android:attr/textColorSecondary"
android:visibility="gone"
tools:visibility="visible" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/keepscreen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_keep_screen_on"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/long_tap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_read_with_long_tap"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/page_transitions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_page_transitions"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/volume_page"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/settings_read_volume_page"
android:textColor="?android:attr/textColorSecondary" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/volume_page_speed"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txt_volume_page_fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="@string/settings_read_volume_page_fast"
app:layout_constraintBottom_toBottomOf="@id/slider_volume_page_interval"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/slider_volume_page_interval" />
<com.google.android.material.slider.Slider
android:id="@+id/slider_volume_page_interval"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:padding="8dp"
android:stepSize="1.0"
android:valueFrom="0.0"
android:valueTo="9.0"
app:layout_constraintEnd_toStartOf="@id/txt_volume_page_slow"
app:layout_constraintStart_toEndOf="@id/txt_volume_page_fast"
app:layout_constraintTop_toTopOf="@id/volume_page_speed" />
<TextView
android:id="@+id/txt_volume_page_slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/settings_read_volume_page_slow"
app:layout_constraintBottom_toBottomOf="@id/slider_volume_page_interval"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/slider_volume_page_interval" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/reserve_volume_page"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/settings_read_reverse_volume"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/pager_prefs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@string/pager_viewer"
android:textAppearance="@style/TextAppearance.Tachiyomi.SectionHeader" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/pager_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/pager_nav"
app:title="@string/pref_viewer_nav" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/tapping_inverted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/invert_tapping_mode"
app:title="@string/pref_read_with_tapping_inverted" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/navigate_pan"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_navigate_pan"
android:textColor="?android:attr/textColorSecondary" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/scale_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/image_scale_type"
app:title="@string/pref_image_scale_type" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/landscape_zoom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_landscape_zoom"
android:textColor="?android:attr/textColorSecondary" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/zoom_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/zoom_start"
app:title="@string/pref_zoom_start" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/crop_borders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_crop_borders"
android:textColor="?android:attr/textColorSecondary" />
<androidx.constraintlayout.widget.Group
android:id="@+id/tapping_prefs_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="pager_nav,tapping_inverted" />
</LinearLayout>
@@ -1,47 +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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/viewer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/viewers_selector"
app:title="@string/pref_category_reading_mode" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/rotation_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:entries="@array/rotation_type"
app:title="@string/rotation_type" />
<!-- Pager preferences -->
<include
android:id="@+id/pager_prefs_group"
layout="@layout/reader_pager_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible" />
<!-- Webtoon preferences -->
<include
android:id="@+id/webtoon_prefs_group"
layout="@layout/reader_webtoon_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/webtoon_prefs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:layout_marginBottom="8dp"
android:text="@string/webtoon_viewer"
android:textAppearance="@style/TextAppearance.Tachiyomi.SectionHeader" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/webtoon_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/webtoon_nav"
app:title="@string/pref_viewer_nav" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/tapping_inverted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/invert_tapping_mode"
app:title="@string/pref_read_with_tapping_inverted" />
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/webtoon_side_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/webtoon_side_padding"
app:title="@string/pref_webtoon_side_padding" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/crop_borders_webtoon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_crop_borders"
android:textColor="?android:attr/textColorSecondary" />
<androidx.constraintlayout.widget.Group
android:id="@+id/tapping_prefs_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="webtoon_nav,tapping_inverted" />
</LinearLayout>
@@ -1,3 +0,0 @@
<resources>
<dimen name="bottom_sheet_width">480dp</dimen>
</resources>
@@ -563,10 +563,6 @@
<string name="rotation_free">跟随系统</string>
<string name="rotation_force_portrait">锁定竖屏</string>
<string name="rotation_force_landscape">锁定横屏</string>
<string name="color_filter_r_value">R</string>
<string name="color_filter_g_value">G</string>
<string name="color_filter_b_value">B</string>
<string name="color_filter_a_value">A</string>
<string name="custom_filter">滤镜</string>
<string name="decode_image_error">无法加载该图片</string>
<string name="pref_read_with_long_tap">长按显示操作菜单</string>
@@ -455,10 +455,6 @@
<string name="rotation_free">自動</string>
<string name="rotation_force_portrait">鎖定直向</string>
<string name="rotation_force_landscape">鎖定橫向</string>
<string name="color_filter_r_value">R</string>
<string name="color_filter_g_value">G</string>
<string name="color_filter_b_value">B</string>
<string name="color_filter_a_value">A</string>
<string name="pref_page_transitions">翻頁轉場動畫</string>
<string name="pref_color_filter_mode">濾鏡融合機制</string>
<string name="filter_mode_multiply">色彩增值</string>
@@ -563,10 +563,6 @@
<string name="rotation_free">自動</string>
<string name="rotation_force_portrait">鎖定直向</string>
<string name="rotation_force_landscape">鎖定橫向</string>
<string name="color_filter_r_value">R</string>
<string name="color_filter_g_value">G</string>
<string name="color_filter_b_value">B</string>
<string name="color_filter_a_value">A</string>
<string name="custom_filter">濾鏡</string>
<string name="decode_image_error">無法載入該圖片</string>
<string name="pref_read_with_long_tap">長按顯示</string>
-2
View File
@@ -51,6 +51,4 @@
<dimen name="gallery_detail_thumb_width">128dp</dimen>
<dimen name="gallery_detail_thumb_height">192dp</dimen>
<dimen name="bottom_sheet_width">0dp</dimen>
</resources>
-4
View File
@@ -661,10 +661,6 @@
<string name="zoom_start_right">Right</string>
<string name="zoom_start_center">Center</string>
<string name="rotation_type">Rotation type</string>
<string name="color_filter_r_value">R</string>
<string name="color_filter_g_value">G</string>
<string name="color_filter_b_value">B</string>
<string name="color_filter_a_value">A</string>
<string name="pref_category_reading_mode">Reading mode</string>
<string name="pref_webtoon_side_padding">Side padding</string>
<string name="webtoon_side_padding_0">None</string>
-4
View File
@@ -23,8 +23,4 @@
<item name="postSplashScreenTheme">@style/AppTheme</item>
</style>
<!-- Tachiyomi -->
<style name="TextAppearance.Tachiyomi.SectionHeader" parent="TextAppearance.Material3.LabelLarge">
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
</resources>