[修复] 修复分组管理的抽动问题
[优化] 布局模式为网格时,添加仅封面样式
This commit is contained in:
@@ -52,6 +52,7 @@ object PreferKey {
|
|||||||
const val bookshelfLayoutModePortrait = "bookshelfLayoutPortrait"
|
const val bookshelfLayoutModePortrait = "bookshelfLayoutPortrait"
|
||||||
const val bookshelfLayoutModeLandscape = "bookshelf_layout_landscape"
|
const val bookshelfLayoutModeLandscape = "bookshelf_layout_landscape"
|
||||||
const val bookshelfLayoutCompact = "bookshelfLayoutCompact"
|
const val bookshelfLayoutCompact = "bookshelfLayoutCompact"
|
||||||
|
const val bookshelfGridLayout = "bookshelfGridLayout"
|
||||||
const val bookshelfSort = "bookshelfSort"
|
const val bookshelfSort = "bookshelfSort"
|
||||||
const val bookExportFileName = "bookExportFileName"
|
const val bookExportFileName = "bookExportFileName"
|
||||||
const val bookImportFileName = "bookImportFileName"
|
const val bookImportFileName = "bookImportFileName"
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ object BookshelfConfig {
|
|||||||
*/
|
*/
|
||||||
var bookshelfLayoutGridLandscape by prefDelegate(PreferKey.bookshelfLayoutGridLandscape, 7)
|
var bookshelfLayoutGridLandscape by prefDelegate(PreferKey.bookshelfLayoutGridLandscape, 7)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网格模式布局样式: 0:标准, 1:紧凑, 2:仅封面
|
||||||
|
*/
|
||||||
|
var bookshelfGridLayout by prefDelegate(PreferKey.bookshelfGridLayout, 0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 紧凑模式
|
* 紧凑模式
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -26,23 +26,30 @@ import androidx.compose.ui.draw.shadow
|
|||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.Shadow
|
import androidx.compose.ui.graphics.Shadow
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.Book
|
import io.legado.app.data.entities.Book
|
||||||
import io.legado.app.data.entities.BookGroup
|
import io.legado.app.data.entities.BookGroup
|
||||||
|
import io.legado.app.help.book.isLocal
|
||||||
|
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
||||||
import io.legado.app.ui.widget.components.cover.BookCover
|
import io.legado.app.ui.widget.components.cover.BookCover
|
||||||
|
import io.legado.app.ui.widget.components.cover.BookCoverWithProgress
|
||||||
|
import io.legado.app.utils.toTimeAgo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用的书架条目布局组件
|
* 通用的书架条目布局组件
|
||||||
* 支持 列表/网格 模式及 紧凑/常规 样式
|
* 支持 列表/网格 模式及 标准/紧凑/仅封面 样式
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun BookshelfItem(
|
fun BookshelfItem(
|
||||||
isGrid: Boolean,
|
isGrid: Boolean,
|
||||||
isCompact: Boolean,
|
gridStyle: Int, // 0: Standard, 1: Compact, 2: Cover Only
|
||||||
|
isCompact: Boolean, // For List Mode
|
||||||
cover: @Composable (Modifier) -> Unit,
|
cover: @Composable (Modifier) -> Unit,
|
||||||
title: String,
|
title: String,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
@@ -57,7 +64,6 @@ fun BookshelfItem(
|
|||||||
onLongClick: () -> Unit
|
onLongClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
if (isGrid) {
|
if (isGrid) {
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clip(MaterialTheme.shapes.small)
|
.clip(MaterialTheme.shapes.small)
|
||||||
@@ -80,7 +86,7 @@ fun BookshelfItem(
|
|||||||
modifier = Modifier.clip(MaterialTheme.shapes.extraSmall)
|
modifier = Modifier.clip(MaterialTheme.shapes.extraSmall)
|
||||||
) {
|
) {
|
||||||
cover(coverModifier)
|
cover(coverModifier)
|
||||||
if (isCompact) {
|
if (gridStyle == 1) {
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
style = (if (titleSmallFont) MaterialTheme.typography.labelSmall else MaterialTheme.typography.labelMedium).copy(
|
style = (if (titleSmallFont) MaterialTheme.typography.labelSmall else MaterialTheme.typography.labelMedium).copy(
|
||||||
@@ -108,7 +114,7 @@ fun BookshelfItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCompact) {
|
if (gridStyle == 0) {
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
style = if (titleSmallFont) MaterialTheme.typography.labelSmall else MaterialTheme.typography.labelMedium,
|
style = if (titleSmallFont) MaterialTheme.typography.labelSmall else MaterialTheme.typography.labelMedium,
|
||||||
@@ -272,7 +278,7 @@ fun BookGroupCover(
|
|||||||
fun BookGroupItemGrid(
|
fun BookGroupItemGrid(
|
||||||
group: BookGroup,
|
group: BookGroup,
|
||||||
previewBooks: List<Book>,
|
previewBooks: List<Book>,
|
||||||
isCompact: Boolean = false,
|
gridStyle: Int = 0,
|
||||||
titleSmallFont: Boolean = false,
|
titleSmallFont: Boolean = false,
|
||||||
titleCenter: Boolean = true,
|
titleCenter: Boolean = true,
|
||||||
titleMaxLines: Int = 2,
|
titleMaxLines: Int = 2,
|
||||||
@@ -283,7 +289,8 @@ fun BookGroupItemGrid(
|
|||||||
) {
|
) {
|
||||||
BookshelfItem(
|
BookshelfItem(
|
||||||
isGrid = true,
|
isGrid = true,
|
||||||
isCompact = isCompact,
|
gridStyle = gridStyle,
|
||||||
|
isCompact = false,
|
||||||
cover = { BookGroupCover(books = previewBooks, modifier = it) },
|
cover = { BookGroupCover(books = previewBooks, modifier = it) },
|
||||||
title = group.groupName,
|
title = group.groupName,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
@@ -311,6 +318,7 @@ fun BookGroupItemList(
|
|||||||
) {
|
) {
|
||||||
BookshelfItem(
|
BookshelfItem(
|
||||||
isGrid = false,
|
isGrid = false,
|
||||||
|
gridStyle = 0,
|
||||||
isCompact = isCompact,
|
isCompact = isCompact,
|
||||||
cover = { BookGroupCover(books = previewBooks, modifier = it) },
|
cover = { BookGroupCover(books = previewBooks, modifier = it) },
|
||||||
title = group.groupName,
|
title = group.groupName,
|
||||||
@@ -325,3 +333,67 @@ fun BookGroupItemList(
|
|||||||
onLongClick = onLongClick
|
onLongClick = onLongClick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BookItem(
|
||||||
|
book: Book,
|
||||||
|
layoutMode: Int,
|
||||||
|
gridStyle: Int = 0,
|
||||||
|
isCompact: Boolean = false,
|
||||||
|
isUpdating: Boolean = false,
|
||||||
|
titleSmallFont: Boolean = false,
|
||||||
|
titleCenter: Boolean = true,
|
||||||
|
titleMaxLines: Int = 2,
|
||||||
|
coverShadow: Boolean = false,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
onLongClick: () -> Unit
|
||||||
|
) {
|
||||||
|
val unreadCount = book.getUnreadChapterNum()
|
||||||
|
|
||||||
|
BookshelfItem(
|
||||||
|
isGrid = layoutMode != 0,
|
||||||
|
gridStyle = gridStyle,
|
||||||
|
isCompact = isCompact,
|
||||||
|
cover = { modifier ->
|
||||||
|
BookCoverWithProgress(
|
||||||
|
name = book.name,
|
||||||
|
author = book.author,
|
||||||
|
path = book.getDisplayCover(),
|
||||||
|
isUpdating = isUpdating,
|
||||||
|
modifier = modifier,
|
||||||
|
badgeText = if (BookshelfConfig.showUnread && unreadCount > 0) unreadCount.toString() else null,
|
||||||
|
showBadgeDot = !BookshelfConfig.showUnread && BookshelfConfig.showUnreadNew && unreadCount > 0 && book.lastCheckCount > 0
|
||||||
|
)
|
||||||
|
},
|
||||||
|
title = book.name,
|
||||||
|
subTitle = if (layoutMode == 0 && isCompact) {
|
||||||
|
stringResource(R.string.author_read, book.author, unreadCount)
|
||||||
|
} else {
|
||||||
|
book.author
|
||||||
|
},
|
||||||
|
desc = stringResource(R.string.read_dur_progress, book.durChapterTitle ?: ""),
|
||||||
|
extra = {
|
||||||
|
if (BookshelfConfig.showLastUpdateTime && !book.isLocal) {
|
||||||
|
Text(
|
||||||
|
text = book.latestChapterTime.toTimeAgo(),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = if (layoutMode != 0 || !isCompact) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary,
|
||||||
|
modifier = Modifier.padding(end = 4.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = book.latestChapterTitle ?: "",
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
titleSmallFont = titleSmallFont,
|
||||||
|
titleCenter = titleCenter,
|
||||||
|
titleMaxLines = titleMaxLines,
|
||||||
|
coverShadow = coverShadow,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
|||||||
import io.legado.app.ui.widget.components.modalBottomSheet.GlassModalBottomSheet
|
import io.legado.app.ui.widget.components.modalBottomSheet.GlassModalBottomSheet
|
||||||
import io.legado.app.ui.widget.components.settingItem.CompactDropdownSettingItem
|
import io.legado.app.ui.widget.components.settingItem.CompactDropdownSettingItem
|
||||||
import io.legado.app.ui.widget.components.settingItem.CompactSliderSettingItem
|
import io.legado.app.ui.widget.components.settingItem.CompactSliderSettingItem
|
||||||
import io.legado.app.ui.widget.components.settingItem.SwitchSettingItem
|
import io.legado.app.ui.widget.components.settingItem.CompactSwitchSettingItem
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -107,13 +107,24 @@ fun BookshelfConfigSheet(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
if (layoutMode == 1) {
|
||||||
title = "紧凑模式",
|
CompactDropdownSettingItem(
|
||||||
checked = BookshelfConfig.bookshelfLayoutCompact,
|
title = "网格样式",
|
||||||
imageVector = Icons.Default.ViewCompact,
|
selectedValue = BookshelfConfig.bookshelfGridLayout.toString(),
|
||||||
color = MaterialTheme.colorScheme.surface,
|
displayEntries = stringArrayResource(R.array.bookshelf_grid_layout),
|
||||||
onCheckedChange = { BookshelfConfig.bookshelfLayoutCompact = it }
|
entryValues = Array(stringArrayResource(R.array.bookshelf_grid_layout).size) { it.toString() },
|
||||||
)
|
imageVector = Icons.Default.ViewCompact,
|
||||||
|
onValueChange = { BookshelfConfig.bookshelfGridLayout = it.toInt() }
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
CompactSwitchSettingItem(
|
||||||
|
title = "紧凑模式",
|
||||||
|
checked = BookshelfConfig.bookshelfLayoutCompact,
|
||||||
|
imageVector = Icons.Default.ViewCompact,
|
||||||
|
color = MaterialTheme.colorScheme.surface,
|
||||||
|
onCheckedChange = { BookshelfConfig.bookshelfLayoutCompact = it }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Grid Count
|
// Grid Count
|
||||||
val gridCount =
|
val gridCount =
|
||||||
@@ -129,7 +140,7 @@ fun BookshelfConfigSheet(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = "标题小字体",
|
title = "标题小字体",
|
||||||
checked = BookshelfConfig.bookshelfTitleSmallFont,
|
checked = BookshelfConfig.bookshelfTitleSmallFont,
|
||||||
imageVector = Icons.Default.TextFormat,
|
imageVector = Icons.Default.TextFormat,
|
||||||
@@ -137,7 +148,7 @@ fun BookshelfConfigSheet(
|
|||||||
onCheckedChange = { BookshelfConfig.bookshelfTitleSmallFont = it }
|
onCheckedChange = { BookshelfConfig.bookshelfTitleSmallFont = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = "标题居中",
|
title = "标题居中",
|
||||||
checked = BookshelfConfig.bookshelfTitleCenter,
|
checked = BookshelfConfig.bookshelfTitleCenter,
|
||||||
color = MaterialTheme.colorScheme.surface,
|
color = MaterialTheme.colorScheme.surface,
|
||||||
@@ -152,7 +163,7 @@ fun BookshelfConfigSheet(
|
|||||||
onValueChange = { BookshelfConfig.bookshelfTitleMaxLines = it.toInt() }
|
onValueChange = { BookshelfConfig.bookshelfTitleMaxLines = it.toInt() }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = "封面阴影",
|
title = "封面阴影",
|
||||||
checked = BookshelfConfig.bookshelfCoverShadow,
|
checked = BookshelfConfig.bookshelfCoverShadow,
|
||||||
imageVector = Icons.Default.BlurOn,
|
imageVector = Icons.Default.BlurOn,
|
||||||
@@ -161,7 +172,7 @@ fun BookshelfConfigSheet(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Switches
|
// Switches
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.show_unread),
|
title = stringResource(R.string.show_unread),
|
||||||
checked = BookshelfConfig.showUnread,
|
checked = BookshelfConfig.showUnread,
|
||||||
imageVector = Icons.Default.Notifications,
|
imageVector = Icons.Default.Notifications,
|
||||||
@@ -169,14 +180,14 @@ fun BookshelfConfigSheet(
|
|||||||
onCheckedChange = { BookshelfConfig.showUnread = it }
|
onCheckedChange = { BookshelfConfig.showUnread = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.show_unread_new),
|
title = stringResource(R.string.show_unread_new),
|
||||||
checked = BookshelfConfig.showUnreadNew,
|
checked = BookshelfConfig.showUnreadNew,
|
||||||
color = MaterialTheme.colorScheme.surface,
|
color = MaterialTheme.colorScheme.surface,
|
||||||
onCheckedChange = { BookshelfConfig.showUnreadNew = it }
|
onCheckedChange = { BookshelfConfig.showUnreadNew = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.show_tip),
|
title = stringResource(R.string.show_tip),
|
||||||
checked = BookshelfConfig.showTip,
|
checked = BookshelfConfig.showTip,
|
||||||
imageVector = Icons.Default.Info,
|
imageVector = Icons.Default.Info,
|
||||||
@@ -184,7 +195,7 @@ fun BookshelfConfigSheet(
|
|||||||
onCheckedChange = { BookshelfConfig.showTip = it }
|
onCheckedChange = { BookshelfConfig.showTip = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.show_last_update_time),
|
title = stringResource(R.string.show_last_update_time),
|
||||||
checked = BookshelfConfig.showLastUpdateTime,
|
checked = BookshelfConfig.showLastUpdateTime,
|
||||||
imageVector = Icons.Default.History,
|
imageVector = Icons.Default.History,
|
||||||
@@ -192,21 +203,21 @@ fun BookshelfConfigSheet(
|
|||||||
onCheckedChange = { BookshelfConfig.showLastUpdateTime = it }
|
onCheckedChange = { BookshelfConfig.showLastUpdateTime = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.show_wait_up_count),
|
title = stringResource(R.string.show_wait_up_count),
|
||||||
checked = BookshelfConfig.showWaitUpCount,
|
checked = BookshelfConfig.showWaitUpCount,
|
||||||
color = MaterialTheme.colorScheme.surface,
|
color = MaterialTheme.colorScheme.surface,
|
||||||
onCheckedChange = { BookshelfConfig.showWaitUpCount = it }
|
onCheckedChange = { BookshelfConfig.showWaitUpCount = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.show_bookshelf_fast_scroller),
|
title = stringResource(R.string.show_bookshelf_fast_scroller),
|
||||||
checked = BookshelfConfig.showBookshelfFastScroller,
|
checked = BookshelfConfig.showBookshelfFastScroller,
|
||||||
color = MaterialTheme.colorScheme.surface,
|
color = MaterialTheme.colorScheme.surface,
|
||||||
onCheckedChange = { BookshelfConfig.showBookshelfFastScroller = it }
|
onCheckedChange = { BookshelfConfig.showBookshelfFastScroller = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
SwitchSettingItem(
|
CompactSwitchSettingItem(
|
||||||
title = stringResource(R.string.show_bookshelf_tab_menu),
|
title = stringResource(R.string.show_bookshelf_tab_menu),
|
||||||
checked = BookshelfConfig.shouldShowExpandButton,
|
checked = BookshelfConfig.shouldShowExpandButton,
|
||||||
imageVector = Icons.Default.Menu,
|
imageVector = Icons.Default.Menu,
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.Book
|
import io.legado.app.data.entities.Book
|
||||||
import io.legado.app.help.book.isLocal
|
|
||||||
import io.legado.app.ui.book.cache.CacheActivity
|
import io.legado.app.ui.book.cache.CacheActivity
|
||||||
import io.legado.app.ui.book.import.local.ImportBookActivity
|
import io.legado.app.ui.book.import.local.ImportBookActivity
|
||||||
import io.legado.app.ui.book.import.remote.RemoteBookActivity
|
import io.legado.app.ui.book.import.remote.RemoteBookActivity
|
||||||
@@ -66,14 +65,12 @@ import io.legado.app.ui.book.search.SearchActivity
|
|||||||
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
||||||
import io.legado.app.ui.file.HandleFileContract
|
import io.legado.app.ui.file.HandleFileContract
|
||||||
import io.legado.app.ui.widget.components.GlassTopAppBarDefaults
|
import io.legado.app.ui.widget.components.GlassTopAppBarDefaults
|
||||||
import io.legado.app.ui.widget.components.cover.BookCoverWithProgress
|
|
||||||
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
|
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
|
||||||
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
|
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
|
||||||
import io.legado.app.ui.widget.components.list.ListScaffold
|
import io.legado.app.ui.widget.components.list.ListScaffold
|
||||||
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
|
||||||
import io.legado.app.utils.readText
|
import io.legado.app.utils.readText
|
||||||
import io.legado.app.utils.startActivity
|
import io.legado.app.utils.startActivity
|
||||||
import io.legado.app.utils.toTimeAgo
|
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -332,7 +329,7 @@ fun BookshelfScreen(
|
|||||||
BookGroupItemGrid(
|
BookGroupItemGrid(
|
||||||
group = group,
|
group = group,
|
||||||
previewBooks = uiState.groupPreviews[group.groupId] ?: emptyList(),
|
previewBooks = uiState.groupPreviews[group.groupId] ?: emptyList(),
|
||||||
isCompact = BookshelfConfig.bookshelfLayoutCompact,
|
gridStyle = BookshelfConfig.bookshelfGridLayout,
|
||||||
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFont,
|
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFont,
|
||||||
titleCenter = BookshelfConfig.bookshelfTitleCenter,
|
titleCenter = BookshelfConfig.bookshelfTitleCenter,
|
||||||
titleMaxLines = BookshelfConfig.bookshelfTitleMaxLines,
|
titleMaxLines = BookshelfConfig.bookshelfTitleMaxLines,
|
||||||
@@ -462,6 +459,7 @@ fun BookshelfPage(
|
|||||||
BookItem(
|
BookItem(
|
||||||
book = book,
|
book = book,
|
||||||
layoutMode = bookshelfLayoutMode,
|
layoutMode = bookshelfLayoutMode,
|
||||||
|
gridStyle = BookshelfConfig.bookshelfGridLayout,
|
||||||
isCompact = BookshelfConfig.bookshelfLayoutCompact,
|
isCompact = BookshelfConfig.bookshelfLayoutCompact,
|
||||||
isUpdating = uiState.updatingBooks.contains(book.bookUrl),
|
isUpdating = uiState.updatingBooks.contains(book.bookUrl),
|
||||||
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFont,
|
titleSmallFont = BookshelfConfig.bookshelfTitleSmallFont,
|
||||||
@@ -474,65 +472,3 @@ fun BookshelfPage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BookItem(
|
|
||||||
book: Book,
|
|
||||||
layoutMode: Int,
|
|
||||||
isCompact: Boolean = false,
|
|
||||||
isUpdating: Boolean = false,
|
|
||||||
titleSmallFont: Boolean = false,
|
|
||||||
titleCenter: Boolean = true,
|
|
||||||
titleMaxLines: Int = 2,
|
|
||||||
coverShadow: Boolean = false,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
onLongClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val unreadCount = book.getUnreadChapterNum()
|
|
||||||
|
|
||||||
BookshelfItem(
|
|
||||||
isGrid = layoutMode != 0,
|
|
||||||
isCompact = isCompact,
|
|
||||||
cover = { modifier ->
|
|
||||||
BookCoverWithProgress(
|
|
||||||
name = book.name,
|
|
||||||
author = book.author,
|
|
||||||
path = book.getDisplayCover(),
|
|
||||||
isUpdating = isUpdating,
|
|
||||||
modifier = modifier,
|
|
||||||
badgeText = if (BookshelfConfig.showUnread && unreadCount > 0) unreadCount.toString() else null,
|
|
||||||
showBadgeDot = !BookshelfConfig.showUnread && BookshelfConfig.showUnreadNew && unreadCount > 0 && book.lastCheckCount > 0
|
|
||||||
)
|
|
||||||
},
|
|
||||||
title = book.name,
|
|
||||||
subTitle = if (isCompact && layoutMode == 0) {
|
|
||||||
stringResource(R.string.author_read, book.author, unreadCount)
|
|
||||||
} else {
|
|
||||||
book.author
|
|
||||||
},
|
|
||||||
desc = stringResource(R.string.read_dur_progress, book.durChapterTitle ?: ""),
|
|
||||||
extra = {
|
|
||||||
if (BookshelfConfig.showLastUpdateTime && !book.isLocal) {
|
|
||||||
Text(
|
|
||||||
text = book.latestChapterTime.toTimeAgo(),
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
color = if (!isCompact) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary,
|
|
||||||
modifier = Modifier.padding(end = 4.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Text(
|
|
||||||
text = book.latestChapterTitle ?: "",
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
titleSmallFont = titleSmallFont,
|
|
||||||
titleCenter = titleCenter,
|
|
||||||
titleMaxLines = titleMaxLines,
|
|
||||||
coverShadow = coverShadow,
|
|
||||||
onClick = onClick,
|
|
||||||
onLongClick = onLongClick
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package io.legado.app.ui.main.bookshelf
|
package io.legado.app.ui.main.bookshelf
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.SizeTransform
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
|
import androidx.compose.animation.togetherWith
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@@ -73,63 +78,71 @@ fun GroupManageSheet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
GlassModalBottomSheet(onDismissRequest = onDismissRequest) {
|
GlassModalBottomSheet(onDismissRequest = onDismissRequest) {
|
||||||
if (isEditing) {
|
AnimatedContent(
|
||||||
GroupEditContent(
|
targetState = isEditing,
|
||||||
group = editingGroup,
|
transitionSpec = {
|
||||||
onDismissRequest = { isEditing = false },
|
fadeIn() togetherWith fadeOut() using SizeTransform(clip = false)
|
||||||
viewModel = viewModel
|
},
|
||||||
)
|
label = "GroupManageState"
|
||||||
} else {
|
) { editing ->
|
||||||
Column(
|
if (editing) {
|
||||||
modifier = Modifier
|
GroupEditContent(
|
||||||
.fillMaxWidth()
|
group = editingGroup,
|
||||||
.padding(bottom = 32.dp)
|
onDismissRequest = { isEditing = false },
|
||||||
) {
|
viewModel = viewModel
|
||||||
Row(
|
)
|
||||||
|
} else {
|
||||||
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 16.dp)
|
.padding(bottom = 32.dp)
|
||||||
.padding(vertical = 8.dp),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
) {
|
||||||
Text(
|
Row(
|
||||||
text = stringResource(R.string.group_manage),
|
modifier = Modifier
|
||||||
style = MaterialTheme.typography.titleLarge
|
.fillMaxWidth()
|
||||||
)
|
.padding(horizontal = 16.dp)
|
||||||
IconButton(onClick = {
|
.padding(vertical = 8.dp),
|
||||||
editingGroup = null
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
isEditing = true
|
verticalAlignment = Alignment.CenterVertically
|
||||||
}) {
|
) {
|
||||||
Icon(
|
Text(
|
||||||
Icons.Default.Add,
|
text = stringResource(R.string.group_manage),
|
||||||
contentDescription = stringResource(R.string.add)
|
style = MaterialTheme.typography.titleLarge
|
||||||
)
|
)
|
||||||
|
IconButton(onClick = {
|
||||||
|
editingGroup = null
|
||||||
|
isEditing = true
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Add,
|
||||||
|
contentDescription = stringResource(R.string.add)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
) {
|
) {
|
||||||
items(listData, key = { it.groupId }) { group ->
|
items(listData, key = { it.groupId }) { group ->
|
||||||
val manageNameInfo = remember(group) { group.getManageName(context) }
|
val manageNameInfo = remember(group) { group.getManageName(context) }
|
||||||
ReorderableSelectionItem(
|
ReorderableSelectionItem(
|
||||||
state = reorderableState,
|
state = reorderableState,
|
||||||
key = group.groupId,
|
key = group.groupId,
|
||||||
title = group.groupName.ifBlank { manageNameInfo.suffix.orEmpty() },
|
title = group.groupName.ifBlank { manageNameInfo.suffix.orEmpty() },
|
||||||
subtitle = if (group.groupName.isNotBlank()) manageNameInfo.suffix else null,
|
subtitle = if (group.groupName.isNotBlank()) manageNameInfo.suffix else null,
|
||||||
isEnabled = group.show,
|
isEnabled = group.show,
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
onEnabledChange = { isChecked ->
|
onEnabledChange = { isChecked ->
|
||||||
viewModel.upGroup(group.copy(show = isChecked))
|
viewModel.upGroup(group.copy(show = isChecked))
|
||||||
},
|
},
|
||||||
onClickEdit = {
|
onClickEdit = {
|
||||||
editingGroup = group
|
editingGroup = group
|
||||||
isEditing = true
|
isEditing = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import android.text.TextPaint
|
|||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
@@ -79,15 +78,17 @@ fun BookCover(
|
|||||||
)
|
)
|
||||||
.clip(RoundedCornerShape(4.dp))
|
.clip(RoundedCornerShape(4.dp))
|
||||||
.background(MaterialTheme.colorScheme.surfaceContainerLow)
|
.background(MaterialTheme.colorScheme.surfaceContainerLow)
|
||||||
.then(
|
/*
|
||||||
if (CoverConfig.coverShowStroke) {
|
.then(
|
||||||
Modifier.border(
|
if (CoverConfig.coverShowStroke) {
|
||||||
0.5.dp,
|
Modifier.border(
|
||||||
MaterialTheme.colorScheme.outlineVariant,
|
0.5.dp,
|
||||||
RoundedCornerShape(4.dp)
|
MaterialTheme.colorScheme.outlineVariant,
|
||||||
)
|
RoundedCornerShape(4.dp)
|
||||||
} else Modifier
|
)
|
||||||
)
|
} else Modifier
|
||||||
|
)
|
||||||
|
*/
|
||||||
) {
|
) {
|
||||||
// 1. 封面底图
|
// 1. 封面底图
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
|
|||||||
-2
@@ -1,6 +1,5 @@
|
|||||||
package io.legado.app.ui.widget.components.modalBottomSheet
|
package io.legado.app.ui.widget.components.modalBottomSheet
|
||||||
|
|
||||||
import androidx.compose.animation.animateContentSize
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -47,7 +46,6 @@ fun GlassModalBottomSheet(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.animateContentSize()
|
|
||||||
.then(modifier),
|
.then(modifier),
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
|
|||||||
+31
@@ -12,6 +12,7 @@ import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
|||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Slider
|
import androidx.compose.material3.Slider
|
||||||
|
import androidx.compose.material3.Switch
|
||||||
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
|
||||||
@@ -21,6 +22,7 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.scale
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
@@ -151,3 +153,32 @@ fun CompactSliderSettingItem(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CompactSwitchSettingItem(
|
||||||
|
title: String,
|
||||||
|
checked: Boolean,
|
||||||
|
description: String? = null,
|
||||||
|
imageVector: ImageVector? = null,
|
||||||
|
color: Color? = MaterialTheme.colorScheme.surface,
|
||||||
|
shape: Shape = MaterialTheme.shapes.small,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
onCheckedChange: (Boolean) -> Unit
|
||||||
|
) {
|
||||||
|
SettingItem(
|
||||||
|
title = title,
|
||||||
|
description = description,
|
||||||
|
imageVector = imageVector,
|
||||||
|
color = color,
|
||||||
|
shape = shape,
|
||||||
|
onClick = { if (enabled) onCheckedChange(!checked) },
|
||||||
|
trailingContent = {
|
||||||
|
Switch(
|
||||||
|
modifier = Modifier.scale(0.8f),
|
||||||
|
checked = checked,
|
||||||
|
onCheckedChange = onCheckedChange,
|
||||||
|
enabled = enabled
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -208,5 +208,11 @@
|
|||||||
<item>不显示</item>
|
<item>不显示</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="bookshelf_grid_layout">
|
||||||
|
<item>标准</item>
|
||||||
|
<item>紧凑</item>
|
||||||
|
<item>仅封面</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string name="all_version">所有版本</string>
|
<string name="all_version">所有版本</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -87,4 +87,10 @@
|
|||||||
<item>替換規則</item>
|
<item>替換規則</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="bookshelf_grid_layout">
|
||||||
|
<item>标准</item>
|
||||||
|
<item>紧凑</item>
|
||||||
|
<item>仅封面</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -124,4 +124,10 @@
|
|||||||
<item>取代規則</item>
|
<item>取代規則</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="bookshelf_grid_layout">
|
||||||
|
<item>标准</item>
|
||||||
|
<item>紧凑</item>
|
||||||
|
<item>仅封面</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -286,7 +286,13 @@
|
|||||||
<item>@string/cover_grid</item>
|
<item>@string/cover_grid</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="label_vis_mode" >
|
<string-array name="bookshelf_grid_layout">
|
||||||
|
<item>Standard</item>
|
||||||
|
<item>Compact</item>
|
||||||
|
<item>Cover Only</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="label_vis_mode" >
|
||||||
<item>Auto</item>
|
<item>Auto</item>
|
||||||
<item>Selected</item>
|
<item>Selected</item>
|
||||||
<item>Labeled</item>
|
<item>Labeled</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user