refactor(ReaderAppBars): simplify reader app bar layout and vertical navigator (#1386)

- Removes `BoxIgnoreLayoutDirection` wrapper and related `CompositionLocalProvider` logic.
- Integrates vertical `ChapterNavigator` directly into the main `Column` layout using `Modifier.weight(1f)`.
- Replaces separate `AnimatedVisibility` blocks for vertical navigation with a single `when` branch inside the main UI structure.
- Refines positioning for `NavBarType.VerticalLeft` and `NavBarType.VerticalRight`.
This commit is contained in:
Cuong-Tran 2025-11-02 22:28:25 +06:00
parent 77ecb97535
commit 26b1331750

View file

@ -12,8 +12,6 @@ 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
import androidx.compose.foundation.layout.Box
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.WindowInsets
@ -25,12 +23,9 @@ import androidx.compose.foundation.layout.windowInsetsPadding
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
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
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.dp import androidx.compose.ui.unit.dp
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
@ -49,22 +44,6 @@ enum class NavBarType {
VerticalLeft, VerticalLeft,
Bottom, Bottom,
} }
@Composable
fun BoxIgnoreLayoutDirection(modifier: Modifier, content: @Composable BoxScope.() -> Unit) {
val layoutDirection = LocalLayoutDirection.current
CompositionLocalProvider(
LocalLayoutDirection provides LayoutDirection.Ltr,
) {
Box(modifier) {
CompositionLocalProvider(
LocalLayoutDirection provides layoutDirection,
) {
content()
}
}
}
}
// SY <-- // SY <--
@Composable @Composable
@ -126,164 +105,178 @@ 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)
// SY --> Column(modifier = Modifier.fillMaxHeight()) {
BoxIgnoreLayoutDirection(
Modifier.fillMaxWidth(),
) {
AnimatedVisibility( AnimatedVisibility(
visible = visible && navBarType == NavBarType.VerticalLeft, visible = visible,
enter = slideInHorizontally(initialOffsetX = { -it }, animationSpec = readerBarsSlideAnimationSpec) + enter = slideInVertically(initialOffsetY = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
fadeIn(animationSpec = readerBarsFadeAnimationSpec), fadeIn(animationSpec = readerBarsFadeAnimationSpec),
exit = slideOutHorizontally(targetOffsetX = { -it }, animationSpec = readerBarsSlideAnimationSpec) + exit = slideOutVertically(targetOffsetY = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
fadeOut(animationSpec = readerBarsFadeAnimationSpec), fadeOut(animationSpec = readerBarsFadeAnimationSpec),
modifier = Modifier
.padding(top = 164.dp, bottom = 70.dp)
.align(Alignment.TopStart),
) { ) {
ChapterNavigator( // SY -->
isRtl = isRtl, Column {
onNextChapter = onNextChapter,
enabledNext = enabledNext,
onPreviousChapter = onPreviousChapter,
enabledPrevious = enabledPrevious,
currentPage = currentPage,
totalPages = totalPages,
onPageIndexChange = onPageIndexChange,
// SY -->
isVerticalSlider = true,
currentPageText = currentPageText,
// SY <-- // SY <--
) ReaderTopBar(
modifier = Modifier
.background(backgroundColor)
.clickable(onClick = onClickTopAppBar),
mangaTitle = mangaTitle,
chapterTitle = chapterTitle,
navigateUp = navigateUp,
bookmarked = bookmarked,
onToggleBookmarked = onToggleBookmarked,
// SY -->
onOpenInWebView = null, // onOpenInWebView,
onOpenInBrowser = null, // onOpenInBrowser,
onShare = null, // onShare,
// SY <--
)
// SY -->
ExhUtils(
isVisible = isExhToolsVisible,
onSetExhUtilsVisibility = onSetExhUtilsVisibility,
backgroundColor = backgroundColor,
isAutoScroll = isAutoScroll,
isAutoScrollEnabled = isAutoScrollEnabled,
onToggleAutoscroll = onToggleAutoscroll,
autoScrollFrequency = autoScrollFrequency,
onSetAutoScrollFrequency = onSetAutoScrollFrequency,
onClickAutoScrollHelp = onClickAutoScrollHelp,
onClickRetryAll = onClickRetryAll,
onClickRetryAllHelp = onClickRetryAllHelp,
onClickBoostPage = onClickBoostPage,
onClickBoostPageHelp = onClickBoostPageHelp,
)
}
// SY <--
} }
AnimatedVisibility( // KMK -->
visible = visible && navBarType == NavBarType.VerticalRight, when (navBarType) {
enter = slideInHorizontally(initialOffsetX = { it }, animationSpec = readerBarsSlideAnimationSpec) + NavBarType.VerticalLeft -> {
fadeIn(animationSpec = readerBarsFadeAnimationSpec), AnimatedVisibility(
exit = slideOutHorizontally(targetOffsetX = { it }, animationSpec = readerBarsSlideAnimationSpec) + visible = visible,
fadeOut(animationSpec = readerBarsFadeAnimationSpec), enter = slideInHorizontally(
modifier = Modifier initialOffsetX = { -it },
.padding(top = 164.dp, bottom = 70.dp) animationSpec = readerBarsSlideAnimationSpec,
.align(Alignment.TopEnd), ) +
) { fadeIn(animationSpec = readerBarsFadeAnimationSpec),
ChapterNavigator( exit = slideOutHorizontally(
isRtl = isRtl, targetOffsetX = { -it },
onNextChapter = onNextChapter, animationSpec = readerBarsSlideAnimationSpec,
enabledNext = enabledNext, ) +
onPreviousChapter = onPreviousChapter, fadeOut(animationSpec = readerBarsFadeAnimationSpec),
enabledPrevious = enabledPrevious, modifier = Modifier
currentPage = currentPage, .weight(1f)
totalPages = totalPages, .align(Alignment.Start),
onPageIndexChange = onPageIndexChange, ) {
// SY --> ChapterNavigator(
isVerticalSlider = true, isRtl = isRtl,
currentPageText = currentPageText, onNextChapter = onNextChapter,
// SY <-- enabledNext = enabledNext,
) onPreviousChapter = onPreviousChapter,
} enabledPrevious = enabledPrevious,
// SY <-- currentPage = currentPage,
Column(modifier = Modifier.fillMaxHeight()) { totalPages = totalPages,
AnimatedVisibility( onPageIndexChange = onPageIndexChange,
visible = visible,
enter = slideInVertically(initialOffsetY = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
fadeIn(animationSpec = readerBarsFadeAnimationSpec),
exit = slideOutVertically(targetOffsetY = { -it }, animationSpec = readerBarsSlideAnimationSpec) +
fadeOut(animationSpec = readerBarsFadeAnimationSpec),
) {
// SY -->
Column {
// SY <--
ReaderTopBar(
modifier = Modifier
.background(backgroundColor)
.clickable(onClick = onClickTopAppBar),
mangaTitle = mangaTitle,
chapterTitle = chapterTitle,
navigateUp = navigateUp,
bookmarked = bookmarked,
onToggleBookmarked = onToggleBookmarked,
// SY --> // SY -->
onOpenInWebView = null, // onOpenInWebView, isVerticalSlider = true,
onOpenInBrowser = null, // onOpenInBrowser, currentPageText = currentPageText,
onShare = null, // onShare,
// SY <-- // SY <--
) )
// SY -->
ExhUtils(
isVisible = isExhToolsVisible,
onSetExhUtilsVisibility = onSetExhUtilsVisibility,
backgroundColor = backgroundColor,
isAutoScroll = isAutoScroll,
isAutoScrollEnabled = isAutoScrollEnabled,
onToggleAutoscroll = onToggleAutoscroll,
autoScrollFrequency = autoScrollFrequency,
onSetAutoScrollFrequency = onSetAutoScrollFrequency,
onClickAutoScrollHelp = onClickAutoScrollHelp,
onClickRetryAll = onClickRetryAll,
onClickRetryAllHelp = onClickRetryAllHelp,
onClickBoostPage = onClickBoostPage,
onClickBoostPageHelp = onClickBoostPageHelp,
)
} }
// SY <--
} }
Spacer(modifier = Modifier.weight(1f)) NavBarType.VerticalRight -> {
AnimatedVisibility(
AnimatedVisibility( visible = visible,
visible = visible, enter = slideInHorizontally(
enter = slideInVertically(initialOffsetY = { it }, animationSpec = readerBarsSlideAnimationSpec) + initialOffsetX = { it },
fadeIn(animationSpec = readerBarsFadeAnimationSpec), animationSpec = readerBarsSlideAnimationSpec,
exit = slideOutVertically(targetOffsetY = { it }, animationSpec = readerBarsSlideAnimationSpec) + ) +
fadeOut(animationSpec = readerBarsFadeAnimationSpec), fadeIn(animationSpec = readerBarsFadeAnimationSpec),
) { exit = slideOutHorizontally(
Column(verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small)) { targetOffsetX = { it },
// SY --> animationSpec = readerBarsSlideAnimationSpec,
if (navBarType == NavBarType.Bottom) { ) +
// SY <-- fadeOut(animationSpec = readerBarsFadeAnimationSpec),
ChapterNavigator( modifier = Modifier
isRtl = isRtl, .weight(1f)
onNextChapter = onNextChapter, .align(Alignment.End),
enabledNext = enabledNext, ) {
onPreviousChapter = onPreviousChapter, ChapterNavigator(
enabledPrevious = enabledPrevious, isRtl = isRtl,
currentPage = currentPage, onNextChapter = onNextChapter,
totalPages = totalPages, enabledNext = enabledNext,
onPageIndexChange = onPageIndexChange, onPreviousChapter = onPreviousChapter,
// SY --> enabledPrevious = enabledPrevious,
isVerticalSlider = false, currentPage = currentPage,
currentPageText = currentPageText, totalPages = totalPages,
// SY <-- onPageIndexChange = onPageIndexChange,
)
}
ReaderBottomBar(
modifier = Modifier
.fillMaxWidth()
.background(backgroundColor)
.padding(horizontal = MaterialTheme.padding.small)
.windowInsetsPadding(WindowInsets.navigationBars),
readingMode = readingMode,
onClickReadingMode = onClickReadingMode,
orientation = orientation,
onClickOrientation = onClickOrientation,
cropEnabled = cropEnabled,
onClickCropBorder = onClickCropBorder,
onClickSettings = onClickSettings,
// SY --> // SY -->
enabledButtons = enabledButtons, isVerticalSlider = true,
currentReadingMode = currentReadingMode, currentPageText = currentPageText,
dualPageSplitEnabled = dualPageSplitEnabled,
doublePages = doublePages,
onClickChapterList = onClickChapterList,
onClickWebView = onOpenInWebView,
onClickBrowser = onOpenInBrowser,
onClickShare = onShare,
onClickPageLayout = onClickPageLayout,
onClickShiftPage = onClickShiftPage,
// SY <-- // SY <--
) )
} }
} }
// KMK <--
else -> Spacer(modifier = Modifier.weight(1f))
}
AnimatedVisibility(
visible = visible,
enter = slideInVertically(initialOffsetY = { it }, animationSpec = readerBarsSlideAnimationSpec) +
fadeIn(animationSpec = readerBarsFadeAnimationSpec),
exit = slideOutVertically(targetOffsetY = { it }, animationSpec = readerBarsSlideAnimationSpec) +
fadeOut(animationSpec = readerBarsFadeAnimationSpec),
) {
Column(verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small)) {
// SY -->
if (navBarType == NavBarType.Bottom) {
// SY <--
ChapterNavigator(
isRtl = isRtl,
onNextChapter = onNextChapter,
enabledNext = enabledNext,
onPreviousChapter = onPreviousChapter,
enabledPrevious = enabledPrevious,
currentPage = currentPage,
totalPages = totalPages,
onPageIndexChange = onPageIndexChange,
// SY -->
isVerticalSlider = false,
currentPageText = currentPageText,
// SY <--
)
}
ReaderBottomBar(
modifier = Modifier
.fillMaxWidth()
.background(backgroundColor)
.padding(horizontal = MaterialTheme.padding.small)
.windowInsetsPadding(WindowInsets.navigationBars),
readingMode = readingMode,
onClickReadingMode = onClickReadingMode,
orientation = orientation,
onClickOrientation = onClickOrientation,
cropEnabled = cropEnabled,
onClickCropBorder = onClickCropBorder,
onClickSettings = onClickSettings,
// SY -->
enabledButtons = enabledButtons,
currentReadingMode = currentReadingMode,
dualPageSplitEnabled = dualPageSplitEnabled,
doublePages = doublePages,
onClickChapterList = onClickChapterList,
onClickWebView = onOpenInWebView,
onClickBrowser = onOpenInBrowser,
onClickShare = onShare,
onClickPageLayout = onClickPageLayout,
onClickShiftPage = onClickShiftPage,
// SY <--
)
}
} }
} }
} }