This commit is contained in:
2025-10-08 18:08:15 +08:00
parent dc71bb19a9
commit 989e5be041
109 changed files with 10815 additions and 170 deletions

View File

@@ -0,0 +1,258 @@
package com.taskttl.presentation.countdown
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CalendarToday
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.taskttl.core.ui.Chip
import com.taskttl.core.utils.DateUtils
import com.taskttl.data.state.CountdownEffect
import com.taskttl.data.viewmodel.CountdownViewModel
import com.taskttl.ui.components.AppHeader
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import taskttl.composeapp.generated.resources.Res
import taskttl.composeapp.generated.resources.countdown_not_found
import taskttl.composeapp.generated.resources.created_at
import taskttl.composeapp.generated.resources.detail_information
import taskttl.composeapp.generated.resources.event_description
import taskttl.composeapp.generated.resources.label_days
import taskttl.composeapp.generated.resources.reminder
import taskttl.composeapp.generated.resources.title_countdown_info
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CountdownDetailScreen(
countdownId: String,
onNavigateBack: () -> Unit,
onNavigateToEdit: () -> Unit,
viewModel: CountdownViewModel = koinViewModel()
) {
val state by viewModel.state.collectAsState()
val countdown = state.countdowns.find { it.id == countdownId }
LaunchedEffect(Unit) {
viewModel.effects.collect { effect ->
when (effect) {
is CountdownEffect.NavigateBack -> {
onNavigateBack()
}
else -> {}
}
}
}
if (countdown == null) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(stringResource(Res.string.countdown_not_found))
}
return
}
// 剩余天数
val daysRemaining = DateUtils.daysRemaining(countdown.targetDate)
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
Column(
modifier = Modifier.fillMaxSize()
) {
AppHeader(
title = Res.string.title_countdown_info,
showBack = true,
onBackClick = { onNavigateBack.invoke() },
trailingIcon = Icons.Default.Edit,
onTrailingClick = { onNavigateToEdit.invoke() }
)
Column(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFF5F5F5))
.padding(16.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(20.dp))
.background(
brush = androidx.compose.ui.graphics.Brush.linearGradient(
colors = listOf(
countdown.category.color.backgroundColor,
Color.Transparent
)
)
)
.padding(20.dp)
) {
Column(modifier = Modifier.align(Alignment.CenterStart)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = countdown.title,
fontSize = 18.sp,
fontWeight = FontWeight.ExtraBold,
color = Color(0xFF111111)
)
Spacer(modifier = Modifier.width(6.dp))
Chip(text = countdown.category.name)
}
Spacer(modifier = Modifier.height(6.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = Icons.Default.CalendarToday,
contentDescription = null
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = countdown.targetDate.toString(),
fontSize = 14.sp,
color = Color(0xFF444444)
)
}
}
Column(
modifier = Modifier.align(Alignment.TopEnd),
horizontalAlignment = Alignment.End
) {
Text(
text = daysRemaining.toString(),
fontSize = 44.sp,
fontWeight = FontWeight.ExtraBold,
color = Color(0xFF111111)
)
Text(
text = stringResource(Res.string.label_days),
fontSize = 12.sp,
fontWeight = FontWeight.SemiBold,
color = Color(0xFF666666)
)
}
}
countdown.description.let {
Spacer(modifier = Modifier.height(16.dp))
Column(modifier = Modifier.fillMaxWidth()) {
Text(
text = stringResource(Res.string.event_description),
fontWeight = FontWeight.SemiBold,
fontSize = 14.sp,
color = Color(0xFF333333)
)
Spacer(modifier = Modifier.height(10.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.background(Color.White)
.padding(12.dp)
) {
Column {
Text(
text = countdown.description,
color = countdown.category.color.textColor,
lineHeight = 20.sp
)
}
}
}
}
Spacer(modifier = Modifier.height(12.dp))
Column(modifier = Modifier.fillMaxWidth()) {
Text(
text = stringResource(Res.string.detail_information),
fontWeight = FontWeight.SemiBold,
fontSize = 14.sp,
color = Color(0xFF333333)
)
Spacer(modifier = Modifier.height(10.dp))
Column {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp)
) {
InfoItem(
iconTint = Color(0xFF667EEA),
text = "${stringResource(Res.string.reminder)}${
stringResource(countdown.notificationEnabled.displayNameRes)
}",
modifier = Modifier.weight(1f)
)
}
Spacer(modifier = Modifier.height(10.dp))
Row(modifier = Modifier.fillMaxWidth()) {
InfoItem(
iconTint = Color(0xFF999999),
text = "${stringResource(Res.string.created_at)}${countdown.createdAt}",
modifier = Modifier.fillMaxWidth()
)
}
}
}
}
}
}
}
@Composable
private fun InfoItem(iconTint: Color, text: String, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.clip(RoundedCornerShape(10.dp))
.background(Color.White)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier
.size(18.dp)
.clip(RoundedCornerShape(6.dp))
.background(iconTint)
) {}
Spacer(modifier = Modifier.width(10.dp))
Text(text = text, fontSize = 13.sp, color = Color(0xFF555555))
}
}