优化阅读记录界面

This commit is contained in:
HapeLee committed 2025-11-26 02:29:07 +08:00
1 parent d29c889de3
commit 3dfc1f5c25
1 file changed
+71 -17
@@ -2,6 +2,8 @@ package io.legado.app.ui.book.readRecord
import android.os.Bundle import android.os.Bundle
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@@ -36,10 +38,13 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import cn.hutool.core.date.DateUtil import cn.hutool.core.date.DateUtil
import io.legado.app.base.BaseComposeActivity import io.legado.app.base.BaseComposeActivity
import io.legado.app.data.entities.readRecord.ReadRecord import io.legado.app.data.entities.readRecord.ReadRecord
import io.legado.app.data.entities.readRecord.ReadRecordSession import io.legado.app.data.entities.readRecord.ReadRecordSession
import io.legado.app.ui.widget.compose.AnimatedTextLine
import io.legado.app.ui.widget.compose.EmptyMessageView
import io.legado.app.utils.StringUtils.formatFriendlyDate import io.legado.app.utils.StringUtils.formatFriendlyDate
import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.koinViewModel
@@ -108,8 +113,25 @@ fun ReadRecordScreen(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = { topBar = {
Column { Column {
LargeTopAppBar( MediumTopAppBar(
title = { Text("阅读记录") }, title = {
val (mainTitle, subTitle) = when (displayMode) {
DisplayMode.AGGREGATE -> "阅读记录" to "汇总视图"
DisplayMode.TIMELINE -> "阅读记录" to "时间线视图"
DisplayMode.LATEST -> "阅读记录" to "最后阅读"
}
Column {
Text(
text = mainTitle,
style = MaterialTheme.typography.titleLarge,
)
AnimatedTextLine(
text = subTitle,
style = MaterialTheme.typography.titleMedium
)
}
},
navigationIcon = { navigationIcon = {
IconButton(onClick = onBackClick) { IconButton(onClick = onBackClick) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null)
@@ -151,7 +173,27 @@ fun ReadRecordScreen(
Column(modifier = Modifier.padding(padding).fillMaxSize()) { Column(modifier = Modifier.padding(padding).fillMaxSize()) {
TotalTimeHeader(state.totalReadTime) TotalTimeHeader(state.totalReadTime)
val isEmpty = when (displayMode) {
DisplayMode.AGGREGATE -> state.groupedRecords.isEmpty()
DisplayMode.TIMELINE -> state.timelineRecords.isEmpty()
DisplayMode.LATEST -> state.latestRecords.isEmpty()
}
Crossfade(
targetState = isEmpty,
animationSpec = tween(durationMillis = 500),
label = "ContentCrossfade"
) { isListEmpty ->
if (isListEmpty){
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
EmptyMessageView(
message = "没有记录"
)
}
} else {
LazyColumn { LazyColumn {
when(displayMode){ when(displayMode){
DisplayMode.AGGREGATE -> { DisplayMode.AGGREGATE -> {
@@ -209,7 +251,8 @@ fun ReadRecordScreen(
} }
} }
} }
}
}
} }
} }
} }
@@ -232,7 +275,7 @@ fun LatestReadItem(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(onClick = onClick) .clickable(onClick = onClick)
.padding(16.dp), .padding(horizontal = 16.dp, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
BookCoverWithPlaceholder(coverPath) BookCoverWithPlaceholder(coverPath)
@@ -372,7 +415,7 @@ fun ReadRecordItem(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.clickable(onClick = onClick) .clickable(onClick = onClick)
.padding(16.dp), .padding(horizontal = 16.dp, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
BookCoverWithPlaceholder(coverPath) BookCoverWithPlaceholder(coverPath)
@@ -431,9 +474,8 @@ fun DateHeader(
dailyTotalTime: Long dailyTotalTime: Long
) { ) {
val dateText = formatFriendlyDate(date) val dateText = formatFriendlyDate(date)
val totalTimeText = "阅读时长: ${formatDuring(dailyTotalTime)}" val totalTimeText = "已读 ${formatDuring(dailyTotalTime)}"
Surface( Surface(
color = MaterialTheme.colorScheme.surface,
tonalElevation = 2.dp, tonalElevation = 2.dp,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
@@ -446,8 +488,6 @@ fun DateHeader(
color = MaterialTheme.colorScheme.secondary color = MaterialTheme.colorScheme.secondary
) )
Spacer(modifier = Modifier.height(4.dp))
Text( Text(
text = totalTimeText, text = totalTimeText,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
@@ -459,22 +499,36 @@ fun DateHeader(
@Composable @Composable
fun TotalTimeHeader(time: Long) { fun TotalTimeHeader(time: Long) {
Card(
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainer
),
shape = MaterialTheme.shapes.medium,
modifier = Modifier
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .padding(12.dp),
.background(MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.2f)) horizontalAlignment = Alignment.Start
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Text("总阅读时长", style = MaterialTheme.typography.labelMedium) Text(
text = "阅读时长",
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurface
)
Text( Text(
text = formatDuring(time), text = formatDuring(time),
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.labelLarge,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onSurface
) )
} }
}
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun SearchBarSection( fun SearchBarSection(