design(mail): список, навигация, sender-card 1:1 по живой теме
_mobile-mail.css: - Карточка письма: r8 (было 12), фон #FDFDFD, нижняя граница #E6E6E6 + тень #CBCBCB, отправитель 16/500, тема 14/600 чёрный-50%, ДОБАВЛЕНА превью-строка письма (14/500 чёрный-50%, 1 строка), дата 14/500, зазор между карточками 2px (был 8). - Навигация: панель 90% ширины, фон #FBFBFB, имя папки 14/500 (без жирнения активной), счётчик 16/500 серым без фона, разделитель #E6E6E6 под шапкой аккаунта. - Sender-card сообщения: аватар 40 (был 44), имя 16/500. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ import androidx.compose.foundation.verticalScroll
|
|||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.Checkbox
|
||||||
import androidx.compose.material3.CheckboxDefaults
|
import androidx.compose.material3.CheckboxDefaults
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MenuDefaults
|
import androidx.compose.material3.MenuDefaults
|
||||||
@@ -46,6 +47,7 @@ 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.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.drawBehind
|
||||||
import androidx.compose.ui.draw.shadow
|
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
|
||||||
@@ -328,8 +330,8 @@ fun MailNavigationSidebar(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.fillMaxWidth(0.8f)
|
.fillMaxWidth(0.9f)
|
||||||
.background(F7Colors.Surface)
|
.background(F7Colors.Background)
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
.padding(horizontal = 12.dp, vertical = 12.dp),
|
.padding(horizontal = 12.dp, vertical = 12.dp),
|
||||||
) {
|
) {
|
||||||
@@ -422,7 +424,10 @@ fun MailNavigationSidebar(
|
|||||||
expanded = !collapsed,
|
expanded = !collapsed,
|
||||||
onToggleExpanded = { onToggleAccountCollapsed(account.id) },
|
onToggleExpanded = { onToggleAccountCollapsed(account.id) },
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(4.dp))
|
HorizontalDivider(
|
||||||
|
modifier = Modifier.padding(bottom = 8.dp),
|
||||||
|
color = F7Colors.Border,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (!collapsed) {
|
if (!collapsed) {
|
||||||
accountFolders.forEach { folder ->
|
accountFolders.forEach { folder ->
|
||||||
@@ -533,14 +538,17 @@ private fun MailSidebarRow(
|
|||||||
title,
|
title,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Medium,
|
fontWeight = FontWeight.Medium,
|
||||||
|
color = F7Colors.TextPrimary,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
if (unread != null && unread > 0) {
|
if (unread != null && unread > 0) {
|
||||||
|
// Живая тема: счётчик 16/500, серый, без фона
|
||||||
Text(
|
Text(
|
||||||
unread.toString(),
|
unread.toString(),
|
||||||
style = MaterialTheme.typography.labelMedium,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
color = F7Colors.TextSecondary,
|
color = F7Colors.TextSecondary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -598,7 +606,9 @@ fun MailEnvelopeRow(
|
|||||||
val sender = message.fromEmail.takeIf { it.isNotBlank() }
|
val sender = message.fromEmail.takeIf { it.isNotBlank() }
|
||||||
?: message.from.takeIf { it.isNotBlank() && !it.equals("Unknown", ignoreCase = true) }
|
?: message.from.takeIf { it.isNotBlank() && !it.equals("Unknown", ignoreCase = true) }
|
||||||
?: "Неизвестный"
|
?: "Неизвестный"
|
||||||
val mutedColor = F7Colors.TextSecondary
|
// Живая тема (_mobile-mail.css): карточка #FDFDFD r8, нижняя граница #E6E6E6 + тень #CBCBCB,
|
||||||
|
// отправитель 16/500 чёрный, тема 14/600 и превью/дата 14/500 — чёрный 50%.
|
||||||
|
val fadedColor = Color(0x80151515)
|
||||||
val subject = message.subject.ifBlank { "(без темы)" }
|
val subject = message.subject.ifBlank { "(без темы)" }
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
@@ -606,14 +616,21 @@ fun MailEnvelopeRow(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.shadow(
|
.shadow(
|
||||||
elevation = 1.dp,
|
elevation = 1.dp,
|
||||||
shape = RoundedCornerShape(12.dp),
|
shape = RoundedCornerShape(8.dp),
|
||||||
spotColor = Color(0x14000000),
|
spotColor = Color(0xFFCBCBCB),
|
||||||
)
|
)
|
||||||
.clip(RoundedCornerShape(12.dp))
|
.clip(RoundedCornerShape(8.dp))
|
||||||
.background(MailCardSurface)
|
.background(MailCardSurface)
|
||||||
.border(1.dp, F7Colors.Border.copy(alpha = 0.45f), RoundedCornerShape(12.dp))
|
.drawBehind {
|
||||||
|
drawLine(
|
||||||
|
color = Color(0xFFE6E6E6),
|
||||||
|
start = androidx.compose.ui.geometry.Offset(0f, size.height - 0.5f),
|
||||||
|
end = androidx.compose.ui.geometry.Offset(size.width, size.height - 0.5f),
|
||||||
|
strokeWidth = 1.dp.toPx(),
|
||||||
|
)
|
||||||
|
}
|
||||||
.clickable(onClick = onClick)
|
.clickable(onClick = onClick)
|
||||||
.padding(12.dp),
|
.padding(8.dp),
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@@ -624,7 +641,7 @@ fun MailEnvelopeRow(
|
|||||||
email = message.fromEmail,
|
email = message.fromEmail,
|
||||||
modifier = Modifier.size(40.dp),
|
modifier = Modifier.size(40.dp),
|
||||||
)
|
)
|
||||||
Spacer(Modifier.width(10.dp))
|
Spacer(Modifier.width(8.dp))
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@@ -634,15 +651,15 @@ fun MailEnvelopeRow(
|
|||||||
sender,
|
sender,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
fontWeight = if (unread) FontWeight.SemiBold else FontWeight.Medium,
|
fontWeight = FontWeight.Medium,
|
||||||
color = F7Colors.TextPrimary,
|
color = F7Colors.TextPrimary,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
formatEnvelopeDate(message.dateInt),
|
formatEnvelopeDate(message.dateInt),
|
||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = mutedColor,
|
color = fadedColor,
|
||||||
)
|
)
|
||||||
if (message.flags.flagged) {
|
if (message.flags.flagged) {
|
||||||
Spacer(Modifier.width(4.dp))
|
Spacer(Modifier.width(4.dp))
|
||||||
@@ -654,18 +671,27 @@ fun MailEnvelopeRow(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(Modifier.height(4.dp))
|
|
||||||
Text(
|
Text(
|
||||||
subject,
|
subject,
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.SemiBold,
|
||||||
color = mutedColor,
|
color = fadedColor,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
|
if (message.preview.isNotBlank()) {
|
||||||
|
Text(
|
||||||
|
message.preview,
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
color = fadedColor,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
}
|
||||||
// Теги письма цветными пилюлями (макет «Список сообщений»)
|
// Теги письма цветными пилюлями (макет «Список сообщений»)
|
||||||
if (message.tags.isNotEmpty()) {
|
if (message.tags.isNotEmpty()) {
|
||||||
Spacer(Modifier.height(6.dp))
|
Spacer(Modifier.height(4.dp))
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||||
message.tags.take(4).forEach { MailTagChip(it) }
|
message.tags.take(4).forEach { MailTagChip(it) }
|
||||||
}
|
}
|
||||||
@@ -987,15 +1013,15 @@ fun MailMessageSenderCard(
|
|||||||
MailAvatar(
|
MailAvatar(
|
||||||
name = fromName,
|
name = fromName,
|
||||||
email = fromEmail,
|
email = fromEmail,
|
||||||
modifier = Modifier.size(44.dp),
|
modifier = Modifier.size(40.dp),
|
||||||
)
|
)
|
||||||
Spacer(Modifier.width(10.dp))
|
Spacer(Modifier.width(8.dp))
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
Text(
|
Text(
|
||||||
displayName,
|
displayName,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
fontWeight = FontWeight.SemiBold,
|
fontWeight = FontWeight.Medium,
|
||||||
color = F7Colors.TextPrimary,
|
color = F7Colors.TextPrimary,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
|||||||
@@ -680,7 +680,8 @@ private fun MailInboxScreen(
|
|||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
// Живая тема: зазор между карточками писем 2px
|
||||||
|
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||||
) {
|
) {
|
||||||
items(
|
items(
|
||||||
listItems,
|
listItems,
|
||||||
|
|||||||
Reference in New Issue
Block a user