Немного улучшен 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 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.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row 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.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items 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.Button
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
@@ -19,12 +24,16 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier 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.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.github.nullptroma.wallenc.ui.R import com.github.nullptroma.wallenc.ui.R
import kotlinx.coroutines.launch
@Composable @Composable
fun TextSecretDetailsScreen( fun TextSecretDetailsScreen(
@@ -35,6 +44,8 @@ fun TextSecretDetailsScreen(
) { ) {
val uiState by viewModel.state.collectAsStateWithLifecycle() val uiState by viewModel.state.collectAsStateWithLifecycle()
val secret = uiState.secret val secret = uiState.secret
val clipboard = LocalClipboard.current
val scope = rememberCoroutineScope()
Scaffold( Scaffold(
modifier = modifier, modifier = modifier,
@@ -90,10 +101,32 @@ fun TextSecretDetailsScreen(
style = MaterialTheme.typography.labelMedium, style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant, color = MaterialTheme.colorScheme.onSurfaceVariant,
) )
Text( Row(
text = item.value, modifier = Modifier.fillMaxWidth(),
style = MaterialTheme.typography.bodyLarge, 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.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons 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.Add
import androidx.compose.material.icons.filled.KeyboardArrowRight import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.material.icons.outlined.Notes import androidx.compose.material.icons.outlined.Notes
@@ -92,7 +94,7 @@ fun TextSecretsScreen(
horizontalArrangement = Arrangement.spacedBy(12.dp), horizontalArrangement = Arrangement.spacedBy(12.dp),
) { ) {
Icon( Icon(
imageVector = Icons.Outlined.Notes, imageVector = Icons.AutoMirrored.Outlined.Notes,
contentDescription = null, contentDescription = null,
modifier = Modifier modifier = Modifier
.size(22.dp) .size(22.dp)
@@ -111,10 +113,37 @@ fun TextSecretsScreen(
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant, 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( Icon(
imageVector = Icons.Default.KeyboardArrowRight, imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight,
contentDescription = null, contentDescription = null,
) )
} }

View File

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