Немного улучшен UI/UX экрана секретов

This commit is contained in:
2026-05-17 19:42:58 +03:00
parent fe0c0e3f8f
commit a138da2a40
3 changed files with 70 additions and 6 deletions

View File

@@ -1,5 +1,6 @@
package com.github.nullptroma.wallenc.ui.screens.main.screens.storage.secrets
import android.content.ClipData
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -9,9 +10,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ContentCopy
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -19,12 +24,16 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.toClipEntry
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.github.nullptroma.wallenc.ui.R
import kotlinx.coroutines.launch
@Composable
fun TextSecretDetailsScreen(
@@ -35,6 +44,8 @@ fun TextSecretDetailsScreen(
) {
val uiState by viewModel.state.collectAsStateWithLifecycle()
val secret = uiState.secret
val clipboard = LocalClipboard.current
val scope = rememberCoroutineScope()
Scaffold(
modifier = modifier,
@@ -90,10 +101,32 @@ fun TextSecretDetailsScreen(
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
Text(
text = item.value,
style = MaterialTheme.typography.bodyLarge,
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
Text(
text = item.value,
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.weight(1f),
)
IconButton(
onClick = {
scope.launch {
val clipData = ClipData.newPlainText(
item.label ?: "value",
item.value,
)
clipboard.setClipEntry(clipData.toClipEntry())
}
},
) {
Icon(
imageVector = Icons.Default.ContentCopy,
contentDescription = stringResource(R.string.text_secret_copy_value),
)
}
}
}
}
}

View File

@@ -11,6 +11,8 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.automirrored.outlined.Notes
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.material.icons.outlined.Notes
@@ -92,7 +94,7 @@ fun TextSecretsScreen(
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
Icon(
imageVector = Icons.Outlined.Notes,
imageVector = Icons.AutoMirrored.Outlined.Notes,
contentDescription = null,
modifier = Modifier
.size(22.dp)
@@ -111,10 +113,37 @@ fun TextSecretsScreen(
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
val fieldNames = secret.items
.map { item ->
item.label
?.trim()
.takeUnless { it.isNullOrBlank() }
?: stringResource(R.string.text_secret_item_without_label)
}
if (fieldNames.isNotEmpty()) {
fieldNames.take(3).forEach { fieldName ->
Text(
text = "\u2022 $fieldName",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
val hiddenCount = fieldNames.size - 3
if (hiddenCount > 0) {
Text(
text = stringResource(
R.string.text_secret_more_fields,
hiddenCount,
),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
}
}
}
Icon(
imageVector = Icons.Default.KeyboardArrowRight,
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
contentDescription = null,
)
}

View File

@@ -237,9 +237,11 @@
<string name="text_secret_empty_state">Пока нет текстовых секретов</string>
<string name="text_secret_items_count">Элементов: %1$d</string>
<string name="text_secret_item_without_label">Без названия</string>
<string name="text_secret_more_fields">ещё полей: %1$d</string>
<string name="text_secret_item_label_optional">Название (опционально)</string>
<string name="text_secret_item_value">Значение</string>
<string name="text_secret_add_item">Добавить пару</string>
<string name="text_secret_copy_value">Скопировать значение</string>
<string name="save">Сохранить</string>
<string name="cancel">Отмена</string>