Make reader edge-to-edge (mihonapp/mihon#1908)

(cherry picked from commit 5f0c4606681cd59b38ae0855c7827e149fa5488c)
This commit is contained in:
AntsyLich 2025-11-02 19:41:33 +06:00 committed by Cuong-Tran
parent 5aa67ebf34
commit 77ecb97535
12 changed files with 568 additions and 592 deletions

View file

@ -280,7 +280,6 @@ dependencies {
implementation(libs.directionalviewpager) { implementation(libs.directionalviewpager) {
exclude(group = "androidx.viewpager", module = "viewpager") exclude(group = "androidx.viewpager", module = "viewpager")
} }
implementation(libs.insetter)
implementation(libs.richeditor.compose) implementation(libs.richeditor.compose)
implementation(libs.aboutLibraries.compose) implementation(libs.aboutLibraries.compose)
implementation(libs.bundles.voyager) implementation(libs.bundles.voyager)

View file

@ -1,6 +1,5 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import android.os.Build
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -14,6 +13,7 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences.Companion.zoomWid
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences.WebtoonScaleType import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences.WebtoonScaleType
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableMap import kotlinx.collections.immutable.toImmutableMap
@ -148,9 +148,7 @@ object SettingsReaderScreen : SearchableSettings {
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
preference = readerPreferences.cutoutShort(), preference = readerPreferences.cutoutShort(),
title = stringResource(MR.strings.pref_cutout_short), title = stringResource(MR.strings.pref_cutout_short),
enabled = fullscreen && enabled = LocalView.current.hasDisplayCutout() && fullscreen,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P &&
LocalView.current.rootWindowInsets?.displayCutout != null, // has cutout
), ),
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
preference = readerPreferences.keepScreenOn(), preference = readerPreferences.keepScreenOn(),

View file

@ -6,6 +6,7 @@ import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
@ -15,11 +16,12 @@ import androidx.compose.ui.unit.sp
import eu.kanade.presentation.theme.TachiyomiPreviewTheme import eu.kanade.presentation.theme.TachiyomiPreviewTheme
@Composable @Composable
fun PageIndicatorText( fun ReaderPageIndicator(
// SY --> // SY -->
currentPage: String, currentPage: String,
// SY <-- // SY <--
totalPages: Int, totalPages: Int,
modifier: Modifier = Modifier,
) { ) {
if (currentPage.isEmpty() || totalPages <= 0) return if (currentPage.isEmpty() || totalPages <= 0) return
@ -40,6 +42,7 @@ fun PageIndicatorText(
Box( Box(
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
modifier = modifier,
) { ) {
Text( Text(
text = text, text = text,
@ -54,10 +57,10 @@ fun PageIndicatorText(
@PreviewLightDark @PreviewLightDark
@Composable @Composable
private fun PageIndicatorTextPreview() { private fun ReaderPageIndicatorPreview() {
TachiyomiPreviewTheme { TachiyomiPreviewTheme {
Surface { Surface {
PageIndicatorText(currentPage = "10", totalPages = 69) ReaderPageIndicator(currentPage = "10", totalPages = 69)
} }
} }
} }

View file

@ -2,10 +2,13 @@ package eu.kanade.presentation.reader.appbars
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -13,13 +16,12 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Bookmark
import androidx.compose.material.icons.outlined.BookmarkBorder
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -30,20 +32,16 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.reader.components.ChapterNavigator import eu.kanade.presentation.reader.components.ChapterNavigator
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import eu.kanade.tachiyomi.ui.reader.viewer.Viewer import eu.kanade.tachiyomi.ui.reader.viewer.Viewer
import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.pager.R2LPagerViewer
import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
private val animationSpec = tween<IntOffset>(200) private val readerBarsSlideAnimationSpec = tween<IntOffset>(200)
private val readerBarsFadeAnimationSpec = tween<Float>(150)
// SY --> // SY -->
enum class NavBarType { enum class NavBarType {
@ -72,7 +70,6 @@ fun BoxIgnoreLayoutDirection(modifier: Modifier, content: @Composable BoxScope.(
@Composable @Composable
fun ReaderAppBars( fun ReaderAppBars(
visible: Boolean, visible: Boolean,
fullscreen: Boolean,
mangaTitle: String?, mangaTitle: String?,
chapterTitle: String?, chapterTitle: String?,
@ -129,28 +126,18 @@ fun ReaderAppBars(
.surfaceColorAtElevation(3.dp) .surfaceColorAtElevation(3.dp)
.copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f) .copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f)
val modifierWithInsetsPadding = if (fullscreen) {
Modifier.systemBarsPadding()
} else {
Modifier
}
// SY --> // SY -->
BoxIgnoreLayoutDirection( BoxIgnoreLayoutDirection(
Modifier.fillMaxWidth(), Modifier.fillMaxWidth(),
) { ) {
AnimatedVisibility( AnimatedVisibility(
visible = visible && navBarType == NavBarType.VerticalLeft, visible = visible && navBarType == NavBarType.VerticalLeft,
enter = slideInHorizontally( enter = slideInHorizontally(initialOffsetX = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
initialOffsetX = { -it }, fadeIn(animationSpec = readerBarsFadeAnimationSpec),
animationSpec = animationSpec, exit = slideOutHorizontally(targetOffsetX = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
), fadeOut(animationSpec = readerBarsFadeAnimationSpec),
exit = slideOutHorizontally( modifier = Modifier
targetOffsetX = { -it }, .padding(top = 164.dp, bottom = 70.dp)
animationSpec = animationSpec,
),
modifier = modifierWithInsetsPadding
.padding(bottom = 64.dp, top = 112.dp)
.align(Alignment.TopStart), .align(Alignment.TopStart),
) { ) {
ChapterNavigator( ChapterNavigator(
@ -162,23 +149,21 @@ fun ReaderAppBars(
currentPage = currentPage, currentPage = currentPage,
totalPages = totalPages, totalPages = totalPages,
onPageIndexChange = onPageIndexChange, onPageIndexChange = onPageIndexChange,
// SY -->
isVerticalSlider = true, isVerticalSlider = true,
currentPageText = currentPageText, currentPageText = currentPageText,
// SY <--
) )
} }
AnimatedVisibility( AnimatedVisibility(
visible = visible && navBarType == NavBarType.VerticalRight, visible = visible && navBarType == NavBarType.VerticalRight,
enter = slideInHorizontally( enter = slideInHorizontally(initialOffsetX = { it }, animationSpec = readerBarsSlideAnimationSpec) +
initialOffsetX = { it }, fadeIn(animationSpec = readerBarsFadeAnimationSpec),
animationSpec = animationSpec, exit = slideOutHorizontally(targetOffsetX = { it }, animationSpec = readerBarsSlideAnimationSpec) +
), fadeOut(animationSpec = readerBarsFadeAnimationSpec),
exit = slideOutHorizontally( modifier = Modifier
targetOffsetX = { it }, .padding(top = 164.dp, bottom = 70.dp)
animationSpec = animationSpec,
),
modifier = modifierWithInsetsPadding
.padding(bottom = 64.dp, top = 112.dp)
.align(Alignment.TopEnd), .align(Alignment.TopEnd),
) { ) {
ChapterNavigator( ChapterNavigator(
@ -190,87 +175,38 @@ fun ReaderAppBars(
currentPage = currentPage, currentPage = currentPage,
totalPages = totalPages, totalPages = totalPages,
onPageIndexChange = onPageIndexChange, onPageIndexChange = onPageIndexChange,
// SY -->
isVerticalSlider = true, isVerticalSlider = true,
currentPageText = currentPageText, currentPageText = currentPageText,
// SY <--
) )
} }
// SY <-- // SY <--
Column( Column(modifier = Modifier.fillMaxHeight()) {
modifier = Modifier.fillMaxHeight(),
verticalArrangement = Arrangement.SpaceBetween,
) {
AnimatedVisibility( AnimatedVisibility(
visible = visible, visible = visible,
enter = slideInVertically( enter = slideInVertically(initialOffsetY = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
initialOffsetY = { -it }, fadeIn(animationSpec = readerBarsFadeAnimationSpec),
animationSpec = animationSpec, exit = slideOutVertically(targetOffsetY = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
), fadeOut(animationSpec = readerBarsFadeAnimationSpec),
exit = slideOutVertically(
targetOffsetY = { -it },
animationSpec = animationSpec,
),
) { ) {
// SY --> // SY -->
Column(modifierWithInsetsPadding) { Column {
// SY <-- // SY <--
AppBar( ReaderTopBar(
modifier = /*SY --> */ Modifier /*SY <-- */ modifier = Modifier
.background(backgroundColor)
.clickable(onClick = onClickTopAppBar), .clickable(onClick = onClickTopAppBar),
backgroundColor = backgroundColor, mangaTitle = mangaTitle,
title = mangaTitle, chapterTitle = chapterTitle,
subtitle = chapterTitle,
navigateUp = navigateUp, navigateUp = navigateUp,
actions = { bookmarked = bookmarked,
AppBarActions( onToggleBookmarked = onToggleBookmarked,
actions = persistentListOf<AppBar.AppBarAction>().builder() // SY -->
.apply { onOpenInWebView = null, // onOpenInWebView,
add( onOpenInBrowser = null, // onOpenInBrowser,
AppBar.Action( onShare = null, // onShare,
title = stringResource( // SY <--
if (bookmarked) {
MR.strings.action_remove_bookmark
} else {
MR.strings.action_bookmark
},
),
icon = if (bookmarked) {
Icons.Outlined.Bookmark
} else {
Icons.Outlined.BookmarkBorder
},
onClick = onToggleBookmarked,
),
)
/* SY -->
onOpenInWebView?.let {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_open_in_web_view),
onClick = it,
),
)
}
onOpenInBrowser?.let {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_open_in_browser),
onClick = it,
),
)
}
onShare?.let {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_share),
onClick = it,
),
)
}
SY <-- */
}
.build(),
)
},
) )
// SY --> // SY -->
ExhUtils( ExhUtils(
@ -288,28 +224,23 @@ fun ReaderAppBars(
onClickBoostPage = onClickBoostPage, onClickBoostPage = onClickBoostPage,
onClickBoostPageHelp = onClickBoostPageHelp, onClickBoostPageHelp = onClickBoostPageHelp,
) )
// SY <--
} }
// SY <--
} }
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
AnimatedVisibility( AnimatedVisibility(
visible = visible, visible = visible,
enter = slideInVertically( enter = slideInVertically(initialOffsetY = { it }, animationSpec = readerBarsSlideAnimationSpec) +
initialOffsetY = { it }, fadeIn(animationSpec = readerBarsFadeAnimationSpec),
animationSpec = animationSpec, exit = slideOutVertically(targetOffsetY = { it }, animationSpec = readerBarsSlideAnimationSpec) +
), fadeOut(animationSpec = readerBarsFadeAnimationSpec),
exit = slideOutVertically(
targetOffsetY = { it },
animationSpec = animationSpec,
),
) { ) {
Column( Column(verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small)) {
modifier = modifierWithInsetsPadding, // SY -->
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) {
if (navBarType == NavBarType.Bottom) { if (navBarType == NavBarType.Bottom) {
// SY <--
ChapterNavigator( ChapterNavigator(
isRtl = isRtl, isRtl = isRtl,
onNextChapter = onNextChapter, onNextChapter = onNextChapter,
@ -319,15 +250,18 @@ fun ReaderAppBars(
currentPage = currentPage, currentPage = currentPage,
totalPages = totalPages, totalPages = totalPages,
onPageIndexChange = onPageIndexChange, onPageIndexChange = onPageIndexChange,
// SY -->
isVerticalSlider = false, isVerticalSlider = false,
currentPageText = currentPageText, currentPageText = currentPageText,
// SY <--
) )
} }
BottomReaderBar( ReaderBottomBar(
// SY --> modifier = Modifier
enabledButtons = enabledButtons, .fillMaxWidth()
// SY <-- .background(backgroundColor)
backgroundColor = backgroundColor, .padding(horizontal = MaterialTheme.padding.small)
.windowInsetsPadding(WindowInsets.navigationBars),
readingMode = readingMode, readingMode = readingMode,
onClickReadingMode = onClickReadingMode, onClickReadingMode = onClickReadingMode,
orientation = orientation, orientation = orientation,
@ -336,6 +270,7 @@ fun ReaderAppBars(
onClickCropBorder = onClickCropBorder, onClickCropBorder = onClickCropBorder,
onClickSettings = onClickSettings, onClickSettings = onClickSettings,
// SY --> // SY -->
enabledButtons = enabledButtons,
currentReadingMode = currentReadingMode, currentReadingMode = currentReadingMode,
dualPageSplitEnabled = dualPageSplitEnabled, dualPageSplitEnabled = dualPageSplitEnabled,
doublePages = doublePages, doublePages = doublePages,

View file

@ -1,10 +1,7 @@
package eu.kanade.presentation.reader.appbars package eu.kanade.presentation.reader.appbars
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Explore import androidx.compose.material.icons.outlined.Explore
import androidx.compose.material.icons.outlined.FormatListNumbered import androidx.compose.material.icons.outlined.FormatListNumbered
@ -17,9 +14,8 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
@ -30,11 +26,10 @@ import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
fun BottomReaderBar( fun ReaderBottomBar(
// SY --> // SY -->
enabledButtons: ImmutableSet<String>, enabledButtons: ImmutableSet<String>,
// SY <-- // SY <--
backgroundColor: Color,
readingMode: ReadingMode, readingMode: ReadingMode,
onClickReadingMode: () -> Unit, onClickReadingMode: () -> Unit,
orientation: ReaderOrientation, orientation: ReaderOrientation,
@ -53,15 +48,14 @@ fun BottomReaderBar(
onClickPageLayout: () -> Unit, onClickPageLayout: () -> Unit,
onClickShiftPage: () -> Unit, onClickShiftPage: () -> Unit,
// SY <-- // SY <--
modifier: Modifier = Modifier,
) { ) {
// KMK --> // KMK -->
val iconColor = MaterialTheme.colorScheme.primary val iconColor = MaterialTheme.colorScheme.primary
// KMK <-- // KMK <--
Row( Row(
modifier = Modifier modifier = modifier
.fillMaxWidth() .pointerInput(Unit) {},
.background(backgroundColor)
.padding(8.dp),
horizontalArrangement = Arrangement.SpaceEvenly, horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {

View file

@ -0,0 +1,83 @@
package eu.kanade.presentation.reader.appbars
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Bookmark
import androidx.compose.material.icons.outlined.BookmarkBorder
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@Composable
fun ReaderTopBar(
mangaTitle: String?,
chapterTitle: String?,
navigateUp: () -> Unit,
bookmarked: Boolean,
onToggleBookmarked: () -> Unit,
onOpenInWebView: (() -> Unit)?,
onOpenInBrowser: (() -> Unit)?,
onShare: (() -> Unit)?,
modifier: Modifier = Modifier,
) {
AppBar(
modifier = modifier,
backgroundColor = Color.Transparent,
title = mangaTitle,
subtitle = chapterTitle,
navigateUp = navigateUp,
actions = {
AppBarActions(
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
add(
AppBar.Action(
title = stringResource(
if (bookmarked) {
MR.strings.action_remove_bookmark
} else {
MR.strings.action_bookmark
},
),
icon = if (bookmarked) {
Icons.Outlined.Bookmark
} else {
Icons.Outlined.BookmarkBorder
},
onClick = onToggleBookmarked,
),
)
onOpenInWebView?.let {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_open_in_web_view),
onClick = it,
),
)
}
onOpenInBrowser?.let {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_open_in_browser),
onClick = it,
),
)
}
onShare?.let {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_share),
onClick = it,
),
)
}
}
.build(),
)
},
)
}

View file

@ -5,8 +5,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalView
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import eu.kanade.tachiyomi.util.system.hasDisplayCutout
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.CheckboxItem
@ -84,7 +86,8 @@ internal fun GeneralPage(screenModel: ReaderSettingsScreenModel) {
pref = screenModel.preferences.fullscreen(), pref = screenModel.preferences.fullscreen(),
) )
if (screenModel.hasDisplayCutout && screenModel.preferences.fullscreen().get()) { val isFullscreen by screenModel.preferences.fullscreen().collectAsState()
if (LocalView.current.hasDisplayCutout() && isFullscreen) {
CheckboxItem( CheckboxItem(
label = stringResource(MR.strings.pref_cutout_short), label = stringResource(MR.strings.pref_cutout_short),
pref = screenModel.preferences.cutoutShort(), pref = screenModel.preferences.cutoutShort(),

View file

@ -13,7 +13,6 @@ import uy.kohesive.injekt.api.get
class ReaderSettingsScreenModel( class ReaderSettingsScreenModel(
readerState: StateFlow<ReaderViewModel.State>, readerState: StateFlow<ReaderViewModel.State>,
val hasDisplayCutout: Boolean,
val onChangeReadingMode: (ReadingMode) -> Unit, val onChangeReadingMode: (ReadingMode) -> Unit,
val onChangeOrientation: (ReaderOrientation) -> Unit, val onChangeOrientation: (ReaderOrientation) -> Unit,
val preferences: ReaderPreferences = Injekt.get(), val preferences: ReaderPreferences = Injekt.get(),

View file

@ -1,9 +1,9 @@
package eu.kanade.tachiyomi.util.system package eu.kanade.tachiyomi.util.system
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Build import android.os.Build
import android.view.View
import eu.kanade.domain.ui.UiPreferences import eu.kanade.domain.ui.UiPreferences
import eu.kanade.domain.ui.model.TabletUiMode import eu.kanade.domain.ui.model.TabletUiMode
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -57,11 +57,11 @@ fun Context.isNightMode(): Boolean {
/** /**
* Checks whether if the device has a display cutout (i.e. notch, camera cutout, etc.). * Checks whether if the device has a display cutout (i.e. notch, camera cutout, etc.).
* *
* Only works in Android 9+. * Only relevant from Android 9 to Android 14.
*/ */
fun Activity.hasDisplayCutout(): Boolean { fun View.hasDisplayCutout(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && return Build.VERSION.SDK_INT in Build.VERSION_CODES.P..Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
window.decorView.rootWindowInsets?.displayCutout != null rootWindowInsets?.displayCutout != null
} }
/** /**

View file

@ -13,12 +13,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants" /> android:descendantFocusability="blocksDescendants" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/page_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal" />
</FrameLayout> </FrameLayout>
<eu.kanade.tachiyomi.ui.reader.ReaderNavigationOverlayView <eu.kanade.tachiyomi.ui.reader.ReaderNavigationOverlayView
@ -30,7 +24,7 @@
android:visibility="gone" /> android:visibility="gone" />
<androidx.compose.ui.platform.ComposeView <androidx.compose.ui.platform.ComposeView
android:id="@+id/dialog_root" android:id="@+id/compose_overlay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />

View file

@ -60,7 +60,6 @@ material = "com.google.android.material:material:1.13.0"
flexible-adapter-core = "com.github.arkon.FlexibleAdapter:flexible-adapter:c8013533" flexible-adapter-core = "com.github.arkon.FlexibleAdapter:flexible-adapter:c8013533"
photoview = "com.github.chrisbanes:PhotoView:2.3.0" photoview = "com.github.chrisbanes:PhotoView:2.3.0"
directionalviewpager = "com.github.tachiyomiorg:DirectionalViewPager:1.0.0" directionalviewpager = "com.github.tachiyomiorg:DirectionalViewPager:1.0.0"
insetter = "dev.chrisbanes.insetter:insetter:0.6.1"
compose-materialmotion = "io.github.fornewid:material-motion-compose-core:2.0.1" compose-materialmotion = "io.github.fornewid:material-motion-compose-core:2.0.1"
compose-webview = "io.github.kevinnzou:compose-webview:0.33.6" compose-webview = "io.github.kevinnzou:compose-webview:0.33.6"
compose-grid = "io.woong.compose.grid:grid:1.2.2" compose-grid = "io.woong.compose.grid:grid:1.2.2"