Дизайн Файлов (чанк 1): строка списка по макету (Figma F-18/F-21/F-22)
CI / verify (push) Failing after 1m9s
CI / release (push) Has been skipped

- Имя + расширение инлайн (расширение серым TextSecondary), одна строка —
  вместо имени в 2 строки + мета (размер·дата). По мобильному макету.
- Выбранная строка — светло-зелёный фон (F7Colors.PrimaryLight), скругление.
- Иконка типа 28→24dp. На токенах F7Spacing/F7Radius.
- Строка на существующей загрузке иконок с сервера; локальные ico + офлайн — следом.

feature:files компилируется. Визуальная сверка — на устройстве (side-by-side).
This commit is contained in:
b-dev-mobile
2026-07-08 07:33:27 +00:00
parent 312537cd8a
commit 04227fa5c8
@@ -64,8 +64,13 @@ import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties import androidx.compose.ui.window.PopupProperties
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import coil.compose.AsyncImage import coil.compose.AsyncImage
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import ru.forbion.f7cloud.core.designsystem.F7AlertDialog import ru.forbion.f7cloud.core.designsystem.F7AlertDialog
import ru.forbion.f7cloud.core.designsystem.F7Colors import ru.forbion.f7cloud.core.designsystem.F7Colors
import ru.forbion.f7cloud.core.designsystem.F7Radius
import ru.forbion.f7cloud.core.designsystem.F7Spacing
import ru.forbion.f7cloud.core.designsystem.F7OutlinedField import ru.forbion.f7cloud.core.designsystem.F7OutlinedField
import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton
import ru.forbion.f7cloud.core.designsystem.F7SecondaryButton import ru.forbion.f7cloud.core.designsystem.F7SecondaryButton
@@ -775,16 +780,18 @@ fun FilesListRow(
onMenuClick: (Rect) -> Unit, onMenuClick: (Rect) -> Unit,
) { ) {
var menuAnchor by remember { mutableStateOf<Rect?>(null) } var menuAnchor by remember { mutableStateOf<Rect?>(null) }
val displayName = if (showExtensions || item.isDirectory) { // Имя + расширение (расширение серым, инлайн) — по макету моб. Файлов (F-18/F-22).
item.name val hasExt = !item.isDirectory && item.name.contains('.')
} else { val baseName = if (hasExt) item.name.substringBeforeLast('.') else item.name
item.name.substringBeforeLast('.', item.name) val extension = if (hasExt && showExtensions) "." + item.name.substringAfterLast('.') else ""
}
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clip(RoundedCornerShape(F7Radius.md))
// выбранная строка — светло-зелёный фон (макет F-21)
.background(if (selected) F7Colors.PrimaryLight else Color.Transparent)
.clickable(onClick = onOpenClick) .clickable(onClick = onOpenClick)
.padding(horizontal = 4.dp, vertical = 10.dp), .padding(horizontal = F7Spacing.sm, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
Checkbox( Checkbox(
@@ -795,37 +802,25 @@ fun FilesListRow(
AsyncImage( AsyncImage(
model = FileIcons.iconUrl(serverUrl, item.name, item.isDirectory), model = FileIcons.iconUrl(serverUrl, item.name, item.isDirectory),
contentDescription = null, contentDescription = null,
modifier = Modifier.size(28.dp), modifier = Modifier.size(24.dp),
contentScale = ContentScale.Fit, contentScale = ContentScale.Fit,
) )
Column( Text(
text = buildAnnotatedString {
append(baseName)
if (extension.isNotEmpty()) {
withStyle(SpanStyle(color = F7Colors.TextSecondary)) { append(" $extension") }
}
},
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.padding(horizontal = 8.dp), .padding(horizontal = F7Spacing.sm),
) { style = MaterialTheme.typography.bodyMedium,
Text( fontWeight = FontWeight.Medium,
text = displayName, color = F7Colors.TextPrimary,
style = MaterialTheme.typography.bodyMedium, maxLines = 1,
fontWeight = FontWeight.Medium, overflow = TextOverflow.Ellipsis,
maxLines = 2, )
overflow = TextOverflow.Ellipsis,
)
val meta = buildList {
if (!item.isDirectory && item.size != null && item.size > 0) {
add(formatFileSize(item.size))
}
item.lastModified?.let { add(formatModified(it)) }
}.joinToString(" · ")
if (meta.isNotBlank()) {
Text(
text = meta,
style = MaterialTheme.typography.bodySmall,
color = F7Colors.TextSecondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
Box( Box(
modifier = Modifier modifier = Modifier
.size(36.dp) .size(36.dp)