更新阅读记录界面
This commit is contained in:
@@ -38,13 +38,14 @@ 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.components.AnimatedTextLine
|
||||||
import io.legado.app.ui.widget.compose.EmptyMessageView
|
import io.legado.app.ui.widget.components.Cover
|
||||||
|
import io.legado.app.ui.widget.components.EmptyMessageView
|
||||||
|
import io.legado.app.ui.widget.components.SearchBarSection
|
||||||
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
|
||||||
|
|
||||||
@@ -278,7 +279,7 @@ fun LatestReadItem(
|
|||||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
BookCoverWithPlaceholder(coverPath)
|
Cover(coverPath)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
@@ -372,7 +373,7 @@ fun TimelineSessionItem(
|
|||||||
Column(modifier = Modifier.weight(1f)) {
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
if (item.showHeader) {
|
if (item.showHeader) {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
BookCoverWithPlaceholder(coverPath)
|
Cover(coverPath)
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
Text(
|
Text(
|
||||||
text = session.bookName,
|
text = session.bookName,
|
||||||
@@ -419,7 +420,7 @@ fun ReadRecordItem(
|
|||||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
BookCoverWithPlaceholder(coverPath)
|
Cover(coverPath)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
@@ -443,32 +444,6 @@ fun ReadRecordItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BookCoverWithPlaceholder(path: String?) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.width(48.dp)
|
|
||||||
.height(68.dp)
|
|
||||||
.clip(RoundedCornerShape(4.dp))
|
|
||||||
.background(Color(0xFFEEEEEE)), // 灰色背景
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
if (path == null) {
|
|
||||||
Icon(Icons.Default.Book, null, tint = Color.Gray)
|
|
||||||
} else {
|
|
||||||
AsyncImage(
|
|
||||||
model = ImageRequest.Builder(LocalContext.current)
|
|
||||||
.data(path)
|
|
||||||
.crossfade(true)
|
|
||||||
.build(),
|
|
||||||
contentDescription = null,
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DateHeader(
|
fun DateHeader(
|
||||||
date: String,
|
date: String,
|
||||||
@@ -477,15 +452,13 @@ fun DateHeader(
|
|||||||
val dateText = formatFriendlyDate(date)
|
val dateText = formatFriendlyDate(date)
|
||||||
val totalTimeText = "已读 ${formatDuring(dailyTotalTime)}"
|
val totalTimeText = "已读 ${formatDuring(dailyTotalTime)}"
|
||||||
Surface(
|
Surface(
|
||||||
tonalElevation = 2.dp,
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
||||||
Text(
|
Text(
|
||||||
text = dateText,
|
text = dateText,
|
||||||
style = MaterialTheme.typography.titleMedium.copy(
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold,
|
||||||
),
|
|
||||||
color = MaterialTheme.colorScheme.secondary
|
color = MaterialTheme.colorScheme.secondary
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -529,47 +502,6 @@ fun TotalTimeHeader(time: Long) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun SearchBarSection(
|
|
||||||
query: String,
|
|
||||||
onQueryChange: (String) -> Unit
|
|
||||||
) {
|
|
||||||
Surface(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
|
||||||
shape = RoundedCornerShape(32.dp),
|
|
||||||
color = MaterialTheme.colorScheme.surfaceContainerLow
|
|
||||||
) {
|
|
||||||
|
|
||||||
TextField(
|
|
||||||
value = query,
|
|
||||||
onValueChange = onQueryChange,
|
|
||||||
placeholder = { Text("搜索书名…") },
|
|
||||||
leadingIcon = { Icon(Icons.Default.Search, null) },
|
|
||||||
trailingIcon = {
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
|
||||||
if (query.isNotEmpty()) {
|
|
||||||
IconButton(onClick = { onQueryChange("") }) {
|
|
||||||
Icon(Icons.Default.Clear, contentDescription = null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
singleLine = true,
|
|
||||||
colors = TextFieldDefaults.colors(
|
|
||||||
focusedContainerColor = Color.Transparent,
|
|
||||||
unfocusedContainerColor = Color.Transparent,
|
|
||||||
disabledContainerColor = Color.Transparent,
|
|
||||||
focusedIndicatorColor = Color.Transparent,
|
|
||||||
unfocusedIndicatorColor = Color.Transparent,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun formatDuring(mss: Long): String {
|
fun formatDuring(mss: Long): String {
|
||||||
val days = mss / (1000 * 60 * 60 * 24)
|
val days = mss / (1000 * 60 * 60 * 24)
|
||||||
val hours = mss % (1000 * 60 * 60 * 24) / (1000 * 60 * 60)
|
val hours = mss % (1000 * 60 * 60 * 24) / (1000 * 60 * 60)
|
||||||
|
|||||||
Reference in New Issue
Block a user