feat: Re-added tachi's cutout support

Closes GH-9
This commit is contained in:
ziro 2024-02-05 16:02:58 +07:00
parent e97cb08bd2
commit 80191827c2
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
9 changed files with 70 additions and 29 deletions

View file

@ -7,5 +7,8 @@
## Other ## Other
--> -->
## Additions
- Ported Tachi's cutout option
## Fixes ## Fixes
- Fixed splash icon hardcoded to white - Fixed splash icon hardcoded to white

View file

@ -7,9 +7,11 @@ import eu.kanade.tachiyomi.core.preference.getEnum
import eu.kanade.tachiyomi.data.preference.PreferenceKeys import eu.kanade.tachiyomi.data.preference.PreferenceKeys
class ReaderPreferences(private val preferenceStore: PreferenceStore) { class ReaderPreferences(private val preferenceStore: PreferenceStore) {
fun pagerCutoutBehavior() = preferenceStore.getEnum(PreferenceKeys.pagerCutoutBehavior, CutoutBehaviour.SHOW) fun cutoutShort() = preferenceStore.getBoolean("cutout_short", true)
fun landscapeCutoutBehavior() = preferenceStore.getEnum("landscape_cutout_behavior", LandscapeCutoutBehaviour.DEFAULT) fun pagerCutoutBehavior() = preferenceStore.getEnum(PreferenceKeys.pagerCutoutBehavior, CutoutBehaviour.HIDE)
fun landscapeCutoutBehavior() = preferenceStore.getEnum("landscape_cutout_behavior", LandscapeCutoutBehaviour.HIDE)
enum class CutoutBehaviour(@StringRes val titleResId: Int) { enum class CutoutBehaviour(@StringRes val titleResId: Int) {
HIDE(R.string.pad_cutout_areas), // Similar to CUTOUT_MODE_NEVER / J2K's pad HIDE(R.string.pad_cutout_areas), // Similar to CUTOUT_MODE_NEVER / J2K's pad

View file

@ -1822,22 +1822,30 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
* Sets notch cutout mode to "NEVER", if mobile is in a landscape view * Sets notch cutout mode to "NEVER", if mobile is in a landscape view
*/ */
private fun setCutoutMode() { private fun setCutoutMode() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return
val currentOrientation = resources.configuration.orientation
val params = window.attributes val currentOrientation = resources.configuration.orientation
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
params.layoutInDisplayCutoutMode = val attributes = window.attributes
attributes.layoutInDisplayCutoutMode =
when (currentOrientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
if (readerPreferences.landscapeCutoutBehavior().get() == LandscapeCutoutBehaviour.HIDE) { if (readerPreferences.landscapeCutoutBehavior().get() == LandscapeCutoutBehaviour.HIDE) {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
} else { } else {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
} }
} else { }
params.layoutInDisplayCutoutMode = else -> {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES if (readerPreferences.cutoutShort().get()) {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
} else {
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
}
}
} }
}
window.attributes = attributes
} }
private fun setDoublePageMode(viewer: PagerViewer) { private fun setDoublePageMode(viewer: PagerViewer) {
@ -1913,6 +1921,8 @@ class ReaderActivity : BaseActivity<ReaderActivityBinding>() {
preferences.showPageNumber().changesIn(scope) { setPageNumberVisibility(it) } preferences.showPageNumber().changesIn(scope) { setPageNumberVisibility(it) }
readerPreferences.cutoutShort().changesIn(scope) { setCutoutMode() }
readerPreferences.landscapeCutoutBehavior().changes() readerPreferences.landscapeCutoutBehavior().changes()
.drop(1) .drop(1)
.onEach { setCutoutMode() } .onEach { setCutoutMode() }

View file

@ -2,9 +2,11 @@ package eu.kanade.tachiyomi.ui.reader.settings
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import androidx.core.view.isVisible
import eu.kanade.tachiyomi.databinding.ReaderGeneralLayoutBinding import eu.kanade.tachiyomi.databinding.ReaderGeneralLayoutBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
@ -50,9 +52,14 @@ class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: Attri
preferences.readerTheme().set(backgroundColor.prefValue) preferences.readerTheme().set(backgroundColor.prefValue)
} }
binding.showPageNumber.bindToPreference(preferences.showPageNumber()) binding.showPageNumber.bindToPreference(preferences.showPageNumber())
binding.fullscreen.bindToPreference(preferences.fullscreen()) binding.fullscreen.bindToPreference(preferences.fullscreen()) {
updatePrefs()
}
binding.cutoutShort.bindToPreference(readerPreferences.cutoutShort())
binding.keepscreen.bindToPreference(preferences.keepScreenOn()) binding.keepscreen.bindToPreference(preferences.keepScreenOn())
binding.alwaysShowChapterTransition.bindToPreference(preferences.alwaysShowChapterTransition()) binding.alwaysShowChapterTransition.bindToPreference(preferences.alwaysShowChapterTransition())
updatePrefs()
} }
/** /**
@ -65,4 +72,8 @@ class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: Attri
private fun initPagerPreferences() { private fun initPagerPreferences() {
sheet.updateTabs(false) sheet.updateTabs(false)
} }
private fun updatePrefs() {
binding.cutoutShort.isVisible = DeviceUtil.hasCutout(context) && preferences.fullscreen().get()
}
} }

View file

@ -16,14 +16,13 @@ import eu.kanade.tachiyomi.databinding.ReaderPagedLayoutBinding
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.lang.addBetaTag import eu.kanade.tachiyomi.util.lang.addBetaTag
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseReaderSettingsView<ReaderPagedLayoutBinding>(context, attrs) { BaseReaderSettingsView<ReaderPagedLayoutBinding>(context, attrs) {
private val readerPreferences: ReaderPreferences by injectLazy()
var needsActivityRecreate = false var needsActivityRecreate = false
override fun inflateBinding() = ReaderPagedLayoutBinding.bind(this) override fun inflateBinding() = ReaderPagedLayoutBinding.bind(this)
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
@ -115,15 +114,9 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
} else { } else {
false false
} }
val hasAnyCutout = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
context.getSystemService<DisplayManager>()
?.getDisplay(Display.DEFAULT_DISPLAY)?.cutout != null
} else {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
}
binding.landscapeZoom.isVisible = show && preferences.imageScaleType().get() == SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE binding.landscapeZoom.isVisible = show && preferences.imageScaleType().get() == SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
binding.extendPastCutout.isVisible = show && isFullFit && hasCutout && preferences.fullscreen().get() binding.extendPastCutout.isVisible = show && isFullFit && hasCutout && preferences.fullscreen().get()
binding.extendPastCutoutLandscape.isVisible = hasAnyCutout && preferences.fullscreen().get() && binding.extendPastCutoutLandscape.isVisible = DeviceUtil.hasCutout(context) && preferences.fullscreen().get() &&
ogView?.resources?.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE ogView?.resources?.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE
if (binding.extendPastCutoutLandscape.isVisible) { if (binding.extendPastCutoutLandscape.isVisible) {
binding.filterLinearLayout.removeView(binding.extendPastCutoutLandscape) binding.filterLinearLayout.removeView(binding.extendPastCutoutLandscape)

View file

@ -126,13 +126,22 @@ class SettingsReaderController : SettingsController() {
titleRes = R.string.show_page_number titleRes = R.string.show_page_number
defaultValue = true defaultValue = true
} }
switchPreference {
bindTo(readerPreferences.cutoutShort())
// FIXME: Transition from reader to homepage is broken when cutout short is disabled
title = context.getString(R.string.pref_cutout_short).addBetaTag(context)
preferences.fullscreen().changesIn(viewScope) { isVisible = DeviceUtil.hasCutout(activity) && it}
}
listPreference(activity) { listPreference(activity) {
bindTo(readerPreferences.landscapeCutoutBehavior()) bindTo(readerPreferences.landscapeCutoutBehavior())
title = "${context.getString(R.string.cutout_area_behavior)} (${context.getString(R.string.landscape)})" title = "${context.getString(R.string.cutout_area_behavior)} (${context.getString(R.string.landscape)})"
val values = LandscapeCutoutBehaviour.entries val values = LandscapeCutoutBehaviour.entries
entriesRes = values.map { it.titleResId }.toTypedArray() entriesRes = values.map { it.titleResId }.toTypedArray()
entryValues = values.map { it.name }.toTypedArray().toList() entryValues = values.map { it.name }
isVisible = DeviceUtil.hasCutout(activity) && preferences.fullscreen().get() defaultValue = LandscapeCutoutBehaviour.HIDE.name
preferences.fullscreen().changesIn(viewScope) { isVisible = DeviceUtil.hasCutout(activity) && it}
} }
} }
@ -210,14 +219,16 @@ class SettingsReaderController : SettingsController() {
titleRes = R.string.cutout_area_behavior titleRes = R.string.cutout_area_behavior
val values = CutoutBehaviour.entries val values = CutoutBehaviour.entries
entriesRes = values.map { it.titleResId }.toTypedArray() entriesRes = values.map { it.titleResId }.toTypedArray()
entryValues = values.map { it.name }.toTypedArray().toList() entryValues = values.map { it.name }
defaultValue = CutoutBehaviour.HIDE.name
// Calling this once to show only on cutout // Calling this once to show only on cutout
isVisible = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { isVisible = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
activityBinding?.root?.rootWindowInsets?.displayCutout?.safeInsetTop != null || activityBinding?.root?.rootWindowInsets?.displayCutout?.safeInsetTop != null ||
activityBinding?.root?.rootWindowInsets?.displayCutout?.safeInsetBottom != null activityBinding?.root?.rootWindowInsets?.displayCutout?.safeInsetBottom != null
} else { } else {
false false
} && preferences.fullscreen().get() }
// Calling this a second time in case activity is recreated while on this page // Calling this a second time in case activity is recreated while on this page
// Keep the first so it shouldn't animate hiding the preference for phones without // Keep the first so it shouldn't animate hiding the preference for phones without
// cutouts // cutouts
@ -227,7 +238,7 @@ class SettingsReaderController : SettingsController() {
activityBinding?.root?.rootWindowInsets?.displayCutout?.safeInsetBottom != null activityBinding?.root?.rootWindowInsets?.displayCutout?.safeInsetBottom != null
} else { } else {
false false
} && preferences.fullscreen().get() }
} }
} }

View file

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.util.system package eu.kanade.tachiyomi.util.system
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.content.Context
import android.hardware.display.DisplayManager import android.hardware.display.DisplayManager
import android.os.Build import android.os.Build
import android.view.Display import android.view.Display
@ -80,8 +80,8 @@ object DeviceUtil {
} }
} }
fun hasCutout(activity: Activity? = null) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { fun hasCutout(context: Context? = null) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
activity?.getSystemService<DisplayManager>() context?.getSystemService<DisplayManager>()
?.getDisplay(Display.DEFAULT_DISPLAY)?.cutout != null ?.getDisplay(Display.DEFAULT_DISPLAY)?.cutout != null
} else { } else {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P Build.VERSION.SDK_INT >= Build.VERSION_CODES.P

View file

@ -6,6 +6,7 @@ import androidx.core.widget.NestedScrollView
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import dev.yokai.domain.recents.RecentsPreferences import dev.yokai.domain.recents.RecentsPreferences
import dev.yokai.domain.ui.UiPreferences import dev.yokai.domain.ui.UiPreferences
import dev.yokai.domain.ui.settings.ReaderPreferences
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
@ -50,4 +51,6 @@ abstract class BaseLibraryDisplayView<VB : ViewBinding> @JvmOverloads constructo
abstract class BaseReaderSettingsView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : abstract class BaseReaderSettingsView<VB : ViewBinding> @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseTabbedScrollView<VB>(context, attrs) { BaseTabbedScrollView<VB>(context, attrs) {
lateinit var activity: ReaderActivity lateinit var activity: ReaderActivity
internal val readerPreferences: ReaderPreferences by injectLazy()
} }

View file

@ -78,6 +78,14 @@
android:text="@string/fullscreen" android:text="@string/fullscreen"
android:textColor="?attr/colorOnBackground" /> android:textColor="?attr/colorOnBackground" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/cutout_short"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/pref_cutout_short"
android:textColor="?attr/colorOnBackground" />
<com.google.android.material.materialswitch.MaterialSwitch <com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/keepscreen" android:id="@+id/keepscreen"
android:layout_width="match_parent" android:layout_width="match_parent"