Migrate bottom reader menu to Compose
(cherry picked from commit 8680accd8e6f458a662dd5454bbcdcde482ce0a7) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt # app/src/main/res/layout/reader_activity.xml
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
package eu.kanade.presentation.reader
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
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.outlined.FormatListNumbered
|
||||
import androidx.compose.material.icons.outlined.Public
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||
|
||||
@Composable
|
||||
fun BottomReaderBar(
|
||||
// SY -->
|
||||
enabledButtons: Set<String>,
|
||||
// SY <--
|
||||
readingMode: ReadingModeType,
|
||||
onClickReadingMode: () -> Unit,
|
||||
orientationMode: OrientationType,
|
||||
onClickOrientationMode: () -> Unit,
|
||||
cropEnabled: Boolean,
|
||||
onClickCropBorder: () -> Unit,
|
||||
onClickSettings: () -> Unit,
|
||||
// SY -->
|
||||
isHttpSource: Boolean,
|
||||
dualPageSplitEnabled: Boolean,
|
||||
doublePages: Boolean,
|
||||
onClickChapterList: () -> Unit,
|
||||
onClickWebView: () -> Unit,
|
||||
onClickShare: () -> Unit,
|
||||
onClickPageLayout: () -> Unit,
|
||||
onClickShiftPage: () -> Unit,
|
||||
// SY <--
|
||||
) {
|
||||
// Match with toolbar background color set in ReaderActivity
|
||||
val backgroundColor = MaterialTheme.colorScheme
|
||||
.surfaceColorAtElevation(3.dp)
|
||||
.copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f)
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(backgroundColor)
|
||||
.padding(8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
// SY -->
|
||||
if (ReaderBottomButton.ViewChapters.isIn(enabledButtons)) {
|
||||
IconButton(onClick = onClickChapterList) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.FormatListNumbered,
|
||||
contentDescription = stringResource(R.string.chapters),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (ReaderBottomButton.WebView.isIn(enabledButtons) && isHttpSource) {
|
||||
IconButton(onClick = onClickWebView) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Public,
|
||||
contentDescription = stringResource(R.string.action_open_in_web_view),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (ReaderBottomButton.Share.isIn(enabledButtons) && isHttpSource) {
|
||||
IconButton(onClick = onClickShare) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Share,
|
||||
contentDescription = stringResource(R.string.action_share),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (ReaderBottomButton.ReadingMode.isIn(enabledButtons)) {
|
||||
IconButton(onClick = onClickReadingMode) {
|
||||
Icon(
|
||||
painter = painterResource(readingMode.iconRes),
|
||||
contentDescription = stringResource(R.string.viewer),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val cropBorders = when (readingMode) {
|
||||
ReadingModeType.WEBTOON -> ReaderBottomButton.CropBordersWebtoon
|
||||
ReadingModeType.CONTINUOUS_VERTICAL -> ReaderBottomButton.CropBordersContinuesVertical
|
||||
else -> ReaderBottomButton.CropBordersPager
|
||||
}
|
||||
if (cropBorders.isIn(enabledButtons)) {
|
||||
IconButton(onClick = onClickCropBorder) {
|
||||
Icon(
|
||||
painter = painterResource(if (cropEnabled) R.drawable.ic_crop_24dp else R.drawable.ic_crop_off_24dp),
|
||||
contentDescription = stringResource(R.string.pref_crop_borders),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (ReaderBottomButton.Rotation.isIn(enabledButtons)) {
|
||||
IconButton(onClick = onClickOrientationMode) {
|
||||
Icon(
|
||||
painter = painterResource(orientationMode.iconRes),
|
||||
contentDescription = stringResource(R.string.pref_rotation_type),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!dualPageSplitEnabled &&
|
||||
ReaderBottomButton.PageLayout.isIn(enabledButtons) &&
|
||||
ReadingModeType.isPagerType(readingMode.prefValue)
|
||||
) {
|
||||
IconButton(onClick = onClickPageLayout) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_book_open_variant_24dp),
|
||||
contentDescription = stringResource(R.string.page_layout),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (doublePages) {
|
||||
IconButton(onClick = onClickShiftPage) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_page_next_outline_24dp),
|
||||
contentDescription = stringResource(R.string.shift_double_pages),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
IconButton(onClick = onClickSettings) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Settings,
|
||||
contentDescription = stringResource(R.string.action_settings),
|
||||
)
|
||||
}
|
||||
// SY <--
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package eu.kanade.presentation.reader
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.components.AdaptiveSheet
|
||||
import eu.kanade.presentation.manga.components.MangaChapterListItem
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.ui.reader.chapter.ReaderChapterItem
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
|
||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||
import exh.metadata.MetadataUtil
|
||||
import exh.source.isEhBasedManga
|
||||
import tachiyomi.domain.chapter.model.Chapter
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import java.util.Date
|
||||
|
||||
@Composable
|
||||
fun ChapterListDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
screenModel: ReaderSettingsScreenModel,
|
||||
chapters: List<ReaderChapterItem>,
|
||||
onClickChapter: (Chapter) -> Unit,
|
||||
onBookmark: (Chapter) -> Unit,
|
||||
) {
|
||||
val manga by screenModel.mangaFlow.collectAsState()
|
||||
val context = LocalContext.current
|
||||
val state = rememberLazyListState(chapters.indexOfFirst { it.isCurrent }.coerceAtLeast(0))
|
||||
|
||||
AdaptiveSheet(
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
LazyColumn(
|
||||
state = state,
|
||||
modifier = Modifier.defaultMinSize(minHeight = 200.dp),
|
||||
contentPadding = PaddingValues(vertical = 16.dp),
|
||||
) {
|
||||
items(
|
||||
items = chapters,
|
||||
key = { "chapter-${it.chapter.id}" },
|
||||
) { chapterItem ->
|
||||
MangaChapterListItem(
|
||||
title = chapterItem.chapter.name,
|
||||
date = chapterItem.chapter.dateUpload
|
||||
.takeIf { it > 0L }
|
||||
?.let {
|
||||
// SY -->
|
||||
if (manga?.isEhBasedManga() == true) {
|
||||
MetadataUtil.EX_DATE_FORMAT.format(Date(it))
|
||||
} else {
|
||||
Date(it).toRelativeString(context, chapterItem.dateFormat)
|
||||
}
|
||||
// SY <--
|
||||
},
|
||||
readProgress = null,
|
||||
scanlator = chapterItem.chapter.scanlator,
|
||||
sourceName = null,
|
||||
read = false,
|
||||
bookmark = chapterItem.chapter.bookmark,
|
||||
selected = false,
|
||||
downloadIndicatorEnabled = false,
|
||||
downloadStateProvider = { Download.State.NOT_DOWNLOADED },
|
||||
downloadProgressProvider = { 0 },
|
||||
chapterSwipeStartAction = LibraryPreferences.ChapterSwipeAction.ToggleBookmark,
|
||||
chapterSwipeEndAction = LibraryPreferences.ChapterSwipeAction.ToggleBookmark,
|
||||
onLongClick = { /*TODO*/ },
|
||||
onClick = { onClickChapter(chapterItem.chapter) },
|
||||
onDownloadClick = null,
|
||||
onChapterSwipe = {
|
||||
onBookmark(chapterItem.chapter)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,15 @@ fun ChapterNavigator(
|
||||
val layoutDirection = if (isRtl) LayoutDirection.Rtl else LayoutDirection.Ltr
|
||||
val haptic = LocalHapticFeedback.current
|
||||
|
||||
// Match with toolbar background color set in ReaderActivity
|
||||
val backgroundColor = MaterialTheme.colorScheme
|
||||
.surfaceColorAtElevation(3.dp)
|
||||
.copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f)
|
||||
val buttonColor = IconButtonDefaults.filledIconButtonColors(
|
||||
containerColor = backgroundColor,
|
||||
disabledContainerColor = backgroundColor,
|
||||
)
|
||||
|
||||
// We explicitly handle direction based on the reader viewer rather than the system direction
|
||||
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||
Row(
|
||||
@@ -87,14 +96,6 @@ fun ChapterNavigator(
|
||||
.padding(horizontal = horizontalPadding),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
// Match with toolbar background color set in ReaderActivity
|
||||
val backgroundColor = MaterialTheme.colorScheme
|
||||
.surfaceColorAtElevation(3.dp)
|
||||
.copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f)
|
||||
val buttonColor = IconButtonDefaults.filledIconButtonColors(
|
||||
containerColor = backgroundColor,
|
||||
disabledContainerColor = backgroundColor,
|
||||
)
|
||||
FilledIconButton(
|
||||
enabled = if (isRtl) enabledNext else enabledPrevious,
|
||||
onClick = if (isRtl) onNextChapter else onPreviousChapter,
|
||||
|
||||
Reference in New Issue
Block a user