新增文件夹列表横排封面布局

This commit is contained in:
HapeLee
2026-05-12 19:47:22 +08:00
parent b3a294ff1e
commit 56b28009e3
4 changed files with 257 additions and 69 deletions
@@ -270,6 +270,8 @@ object PreferKey {
const val bookshelfCoverShadow = "bookshelfCoverShadow"
const val bookshelfSearchActionDirectToSearch = "bookshelfSearchActionDirectToSearch"
const val bookshelfCardColor = "bookshelfCardColor"
const val bookshelfGroupListStyle = "bookshelfGroupListStyle"
const val bookshelfGroupCoverCount = "bookshelfGroupCoverCount"
const val exploreLayoutGridLandscape = "exploreLayoutGridLandscape"
@@ -58,6 +58,16 @@ object BookshelfConfig {
*/
var showBookIntro by prefDelegate(PreferKey.showBookIntro, false)
/**
* 是否显示简介
*/
var bookshelfShowIntro by prefDelegate(PreferKey.bookshelfShowIntro, true)
/**
* 是否显示标签
*/
var bookshelfShowTag by prefDelegate(PreferKey.bookshelfShowTag, true)
/**
* 列表模式下简介显示行数 (0为显示全部)
*/
@@ -155,6 +165,16 @@ object BookshelfConfig {
postEvent(EventBus.NOTIFY_MAIN, false)
}
/**
* 文件夹在列表模式下的样式: 0: 默认, 1: 横排封面
*/
var bookshelfGroupListStyle by prefDelegate(PreferKey.bookshelfGroupListStyle, 0)
/**
* 文件夹在列表模式下横排封面的数量
*/
var bookshelfGroupCoverCount by prefDelegate(PreferKey.bookshelfGroupCoverCount, 4)
/**
* 书架搜索按钮是否直接跳转搜索页
*/
@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
@@ -20,6 +21,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
@@ -55,6 +58,8 @@ import io.legado.app.ui.widget.components.card.NormalCard
import io.legado.app.ui.widget.components.card.TextCard
import io.legado.app.ui.widget.components.cover.CoilBookCover
import io.legado.app.ui.widget.components.cover.BookshelfCover
import io.legado.app.ui.widget.components.icon.AppIcon
import io.legado.app.ui.widget.components.icon.AppIcons
import io.legado.app.ui.widget.components.text.AppText
import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.toTimeAgo
@@ -134,6 +139,7 @@ fun BookshelfItem(
if (isGrid) {
Box(
modifier = modifier
.clip(RoundedCornerShape(4.dp))
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick
@@ -450,16 +456,27 @@ fun BookGroupItemGrid(
fun BookGroupItemList(
group: BookGroupUi,
previewBooks: List<BookShelfItem>,
onClick: () -> Unit,
modifier: Modifier = Modifier,
countText: String? = null,
isCompact: Boolean = false,
titleSmallFont: Boolean = false,
titleCenter: Boolean = true,
titleMaxLines: Int = 2,
coverShadow: Boolean = false,
modifier: Modifier = Modifier,
onClick: () -> Unit,
onLongClick: (() -> Unit)?
onLongClick: (() -> Unit)? = null
) {
if (BookshelfConfig.bookshelfGroupListStyle == 2) {
BookGroupItemHorizontalCovers(
group = group,
previewBooks = previewBooks,
onClick = onClick,
modifier = modifier,
countText = countText,
onLongClick = onLongClick
)
return
}
val firstBookName = previewBooks.firstOrNull()?.name
val primaryColor = MaterialTheme.colorScheme.primary
val descAnnotated = if (firstBookName != null) {
@@ -475,7 +492,7 @@ fun BookGroupItemList(
BookshelfItem(
isGrid = false,
gridStyle = 0,
isCompact = isCompact,
isCompact = BookshelfConfig.bookshelfGroupListStyle == 1 || isCompact,
cover = { BookGroupCover(books = previewBooks, coverPath = group.cover, modifier = it) },
title = group.groupName,
titleColor = primaryColor,
@@ -491,6 +508,99 @@ fun BookGroupItemList(
)
}
@Composable
fun BookGroupItemHorizontalCovers(
group: BookGroupUi,
previewBooks: List<BookShelfItem>,
onClick: () -> Unit,
modifier: Modifier = Modifier,
countText: String? = null,
onLongClick: (() -> Unit)? = null
) {
Column {
NormalCard(
modifier = modifier
.fillMaxWidth()
.padding(all = 4.dp),
cornerRadius = 12.dp,
containerColor = if (BookshelfConfig.bookshelfCardColor != 0) {
Color(BookshelfConfig.bookshelfCardColor)
} else {
LegadoTheme.colorScheme.cardContainer
},
onClick = onClick,
onLongClick = onLongClick
) {
Column(
modifier = Modifier
.padding(vertical = 12.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 12.dp, top = 4.dp, bottom = 4.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
AppText(
text = group.groupName,
style = LegadoTheme.typography.titleMediumEmphasized,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(1f)
)
if (countText != null) {
AppText(
text = countText,
style = LegadoTheme.typography.labelSmallEmphasized,
color = LegadoTheme.colorScheme.onSurfaceVariant
)
}
AppIcon(
modifier = Modifier.padding(end = 6.dp),
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
contentDescription = "",
tint = LegadoTheme.colorScheme.onSurfaceVariant
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
val coverCount = BookshelfConfig.bookshelfGroupCoverCount
previewBooks.take(coverCount).forEach { book ->
Box(
modifier = Modifier
.weight(1f)
.aspectRatio(5f / 7f)
.clip(RoundedCornerShape(4.dp))
) {
CoilBookCover(
name = book.name,
author = book.author,
path = book.getDisplayCover(),
modifier = Modifier.fillMaxSize()
)
}
}
repeat(maxOf(0, coverCount - previewBooks.size)) {
Spacer(modifier = Modifier.weight(1f))
}
}
}
}
if (BookshelfConfig.bookshelfShowDivider)
HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp),
thickness = 0.5.dp,
color = LegadoTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)
)
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun BookItem(
@@ -582,7 +692,7 @@ fun BookItem(
val kindList = book.kind?.splitNotBlank(",", "\n")?.filter { it.isNotBlank() }
val intro = book.intro?.takeIf { it.isNotBlank() }
val customTagColors = if (ThemeConfig.enableCustomTagColors) ThemeConfig.getCustomTagColors() else emptyList()
if (!kindList.isNullOrEmpty()) {
if (BookshelfConfig.bookshelfShowTag && !kindList.isNullOrEmpty()) {
FlowRow(
modifier = Modifier
.fillMaxWidth()
@@ -608,7 +718,7 @@ fun BookItem(
}
}
}
if (intro != null) {
if (BookshelfConfig.bookshelfShowIntro && intro != null) {
val maxLines = if (BookshelfConfig.bookshelfIntroMaxLines == 0) Int.MAX_VALUE else BookshelfConfig.bookshelfIntroMaxLines
AppText(
text = intro,
@@ -108,6 +108,31 @@ fun BookshelfConfigSheet(
}
)
AnimatedVisibility(
visible = BookshelfConfig.bookGroupStyle == 2 && layoutMode == 0
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CompactDropdownSettingItem(
title = "文件夹列表样式",
selectedValue = BookshelfConfig.bookshelfGroupListStyle.toString(),
displayEntries = arrayOf("默认", "紧凑", "横排封面"),
entryValues = arrayOf("0", "1", "2"),
onValueChange = { BookshelfConfig.bookshelfGroupListStyle = it.toInt() }
)
AnimatedVisibility(visible = BookshelfConfig.bookshelfGroupListStyle == 2) {
CompactSliderSettingItem(
title = "横排封面数量",
value = BookshelfConfig.bookshelfGroupCoverCount.toFloat(),
valueRange = 1f..10f,
steps = 9,
onValueChange = { BookshelfConfig.bookshelfGroupCoverCount = it.toInt() }
)
}
}
}
AnimatedVisibility(
visible = layoutMode == 1
) {
@@ -155,78 +180,109 @@ fun BookshelfConfigSheet(
AnimatedVisibility(
visible = layoutMode != 1
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CompactSwitchSettingItem(
title = stringResource(R.string.compact_mode),
checked = BookshelfConfig.bookshelfLayoutCompact,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfLayoutCompact = it }
)
val isHorizontalCovers = BookshelfConfig.bookGroupStyle == 2 && BookshelfConfig.bookshelfGroupListStyle == 2
CompactSwitchSettingItem(
title = stringResource(R.string.show_divider_line),
checked = BookshelfConfig.bookshelfShowDivider,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfShowDivider = it }
)
val listColCount =
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscape else BookshelfConfig.bookshelfLayoutListPortrait
CompactSliderSettingItem(
title = stringResource(R.string.number_rows_columns),
value = listColCount.toFloat(),
valueRange = 1f..5f,
steps = 4,
onValueChange = {
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscape =
it.toInt()
else BookshelfConfig.bookshelfLayoutListPortrait = it.toInt()
}
)
CompactClickableSettingItem(
title = "卡片背景颜色",
color = LegadoTheme.colorScheme.surface,
onClick = { showColorPicker = true }
)
CompactSwitchSettingItem(
title = "显示更多信息",
checked = BookshelfConfig.showBookIntro,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.showBookIntro = it }
)
AnimatedVisibility(visible = BookshelfConfig.showBookIntro) {
AnimatedVisibility(visible = !isHorizontalCovers) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CompactSliderSettingItem(
title = "简介行数",
description = if (BookshelfConfig.bookshelfIntroMaxLines == 0) "显示全部简介" else "显示 ${BookshelfConfig.bookshelfIntroMaxLines} 行简介",
value = BookshelfConfig.bookshelfIntroMaxLines.toFloat(),
valueRange = 0f..10f,
steps = 10,
onValueChange = { BookshelfConfig.bookshelfIntroMaxLines = it.toInt() }
)
CompactSwitchSettingItem(
title = "自定义标签颜色",
checked = ThemeConfig.enableCustomTagColors,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { ThemeConfig.enableCustomTagColors = it }
)
AnimatedVisibility(visible = ThemeConfig.enableCustomTagColors) {
CompactClickableSettingItem(
title = "管理标签颜色",
if (BookshelfConfig.bookGroupStyle != 2) {
CompactSwitchSettingItem(
title = stringResource(R.string.compact_mode),
checked = BookshelfConfig.bookshelfLayoutCompact,
color = LegadoTheme.colorScheme.surface,
onClick = { showLabelColorManage = true }
onCheckedChange = { BookshelfConfig.bookshelfLayoutCompact = it }
)
}
CompactSwitchSettingItem(
title = stringResource(R.string.show_divider_line),
checked = BookshelfConfig.bookshelfShowDivider,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfShowDivider = it }
)
val listColCount =
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscape else BookshelfConfig.bookshelfLayoutListPortrait
CompactSliderSettingItem(
title = stringResource(R.string.number_rows_columns),
value = listColCount.toFloat(),
valueRange = 1f..5f,
steps = 4,
onValueChange = {
if (isLandscape) BookshelfConfig.bookshelfLayoutListLandscape =
it.toInt()
else BookshelfConfig.bookshelfLayoutListPortrait = it.toInt()
}
)
CompactClickableSettingItem(
title = "卡片背景颜色",
color = LegadoTheme.colorScheme.surface,
onClick = { showColorPicker = true }
)
CompactSwitchSettingItem(
title = "显示更多信息",
checked = BookshelfConfig.showBookIntro,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.showBookIntro = it }
)
AnimatedVisibility(visible = BookshelfConfig.showBookIntro) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CompactSwitchSettingItem(
title = "显示简介",
checked = BookshelfConfig.bookshelfShowIntro,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfShowIntro = it }
)
AnimatedVisibility(
visible = BookshelfConfig.bookshelfShowIntro
) {
CompactSliderSettingItem(
title = "简介行数",
description = if (BookshelfConfig.bookshelfIntroMaxLines == 0) "显示全部简介" else "显示 ${BookshelfConfig.bookshelfIntroMaxLines} 行简介",
value = BookshelfConfig.bookshelfIntroMaxLines.toFloat(),
valueRange = 0f..10f,
steps = 10,
onValueChange = { BookshelfConfig.bookshelfIntroMaxLines = it.toInt() }
)
}
CompactSwitchSettingItem(
title = "显示标签",
checked = BookshelfConfig.bookshelfShowTag,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfShowTag = it }
)
AnimatedVisibility(
visible = BookshelfConfig.bookshelfShowTag
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CompactSwitchSettingItem(
title = "自定义标签颜色",
checked = ThemeConfig.enableCustomTagColors,
color = LegadoTheme.colorScheme.surface,
onCheckedChange = { ThemeConfig.enableCustomTagColors = it }
)
AnimatedVisibility(visible = ThemeConfig.enableCustomTagColors) {
CompactClickableSettingItem(
title = "管理标签颜色",
color = LegadoTheme.colorScheme.surface,
onClick = { showLabelColorManage = true }
)
}
}
}
}
}
}
}
}
}
CompactSliderSettingItem(