Localize ProfileScreen labels and actions
Some checks failed
Android CI / android (push) Failing after 6m10s
Android Release / release (push) Failing after 6m47s
CI / test (push) Failing after 3m4s

This commit is contained in:
2026-03-11 21:03:55 +03:00
parent f88d9a2a36
commit e5e4fd653e
3 changed files with 58 additions and 22 deletions

View File

@@ -72,9 +72,11 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil.compose.AsyncImage
import kotlinx.coroutines.flow.collectLatest
import ru.daemonlord.messenger.R
import ru.daemonlord.messenger.ui.account.AccountViewModel
import java.io.ByteArrayOutputStream
import kotlin.math.max
import androidx.compose.ui.res.stringResource
@Composable
fun ProfileRoute(
@@ -167,7 +169,7 @@ fun ProfileScreen(
if (avatarUrl.isNotBlank()) {
AsyncImage(
model = avatarUrl,
contentDescription = "Avatar",
contentDescription = stringResource(id = R.string.profile_avatar_content_description),
modifier = Modifier
.size(108.dp)
.clip(CircleShape)
@@ -190,28 +192,32 @@ fun ProfileScreen(
}
Text(
text = if (name.isBlank()) "User" else name,
text = if (name.isBlank()) stringResource(id = R.string.profile_user_fallback) else name,
style = MaterialTheme.typography.headlineSmall,
color = MaterialTheme.colorScheme.onPrimaryContainer,
fontWeight = FontWeight.SemiBold,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text("online", color = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.8f), style = MaterialTheme.typography.bodyLarge)
Text(
stringResource(id = R.string.chat_status_online),
color = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.8f),
style = MaterialTheme.typography.bodyLarge,
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
HeroActionButton(
label = "Choose photo",
label = stringResource(id = R.string.profile_choose_photo),
icon = Icons.Filled.AddAPhoto,
modifier = Modifier.weight(1f),
) {
pickAvatarLauncher.launch("image/*")
}
HeroActionButton(
label = "Edit",
label = stringResource(id = R.string.profile_edit),
icon = Icons.Filled.Edit,
modifier = Modifier.weight(1f),
) {
@@ -240,10 +246,14 @@ fun ProfileScreen(
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(14.dp),
) {
ProfileInfoRow("Email", profile?.email.orEmpty())
ProfileInfoRow("Bio", bio.ifBlank { "Not set" })
ProfileInfoRow("Username", if (username.isBlank()) "Not set" else "@$username")
ProfileInfoRow("Name", name.ifBlank { "Not set" })
val notSet = stringResource(id = R.string.profile_not_set)
ProfileInfoRow(stringResource(id = R.string.auth_label_email), profile?.email.orEmpty())
ProfileInfoRow(stringResource(id = R.string.profile_bio), bio.ifBlank { notSet })
ProfileInfoRow(
stringResource(id = R.string.auth_label_username),
if (username.isBlank()) notSet else "@$username",
)
ProfileInfoRow(stringResource(id = R.string.auth_label_name), name.ifBlank { notSet })
}
}
}
@@ -262,9 +272,9 @@ fun ProfileScreen(
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(10.dp),
) {
Text("Edit profile", style = MaterialTheme.typography.titleMedium)
Text(stringResource(id = R.string.profile_edit_profile), style = MaterialTheme.typography.titleMedium)
HeroActionButton(
label = "Choose photo",
label = stringResource(id = R.string.profile_choose_photo),
icon = Icons.Filled.AddAPhoto,
modifier = Modifier.fillMaxWidth(),
) {
@@ -273,30 +283,30 @@ fun ProfileScreen(
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("Name") },
label = { Text(stringResource(id = R.string.auth_label_name)) },
modifier = Modifier.fillMaxWidth(),
)
OutlinedTextField(
value = username,
onValueChange = { username = it },
label = { Text("Username") },
label = { Text(stringResource(id = R.string.auth_label_username)) },
modifier = Modifier.fillMaxWidth(),
)
OutlinedTextField(
value = bio,
onValueChange = { bio = it },
label = { Text("Bio") },
label = { Text(stringResource(id = R.string.profile_bio)) },
modifier = Modifier.fillMaxWidth(),
)
OutlinedTextField(
value = avatarUrl,
onValueChange = { avatarUrl = it },
label = { Text("Avatar URL") },
label = { Text(stringResource(id = R.string.profile_avatar_url)) },
modifier = Modifier.fillMaxWidth(),
)
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
TextButton(onClick = { editMode = false }, modifier = Modifier.weight(1f)) {
Text("Cancel")
Text(stringResource(id = R.string.common_cancel))
}
Button(
onClick = {
@@ -311,7 +321,7 @@ fun ProfileScreen(
enabled = !state.isSaving && name.isNotBlank() && username.isNotBlank(),
modifier = Modifier.weight(1f),
) {
Text("Save")
Text(stringResource(id = R.string.common_save))
}
}
if (state.isSaving) {
@@ -421,7 +431,7 @@ private fun AvatarCropDialog(
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
Text("Crop avatar", style = MaterialTheme.typography.titleMedium)
Text(stringResource(id = R.string.profile_crop_avatar), style = MaterialTheme.typography.titleMedium)
Box(
modifier = Modifier
.fillMaxWidth()
@@ -441,7 +451,7 @@ private fun AvatarCropDialog(
) {
androidx.compose.foundation.Image(
bitmap = bitmap.asImageBitmap(),
contentDescription = "Avatar crop preview",
contentDescription = stringResource(id = R.string.profile_avatar_crop_preview),
contentScale = ContentScale.Crop,
modifier = Modifier
.fillMaxSize()
@@ -458,7 +468,7 @@ private fun AvatarCropDialog(
onClick = onDismiss,
modifier = Modifier.weight(1f),
) {
Text("Cancel")
Text(stringResource(id = R.string.common_cancel))
}
Button(
onClick = {
@@ -487,11 +497,11 @@ private fun AvatarCropDialog(
},
modifier = Modifier.weight(1f),
) {
Text("Use")
Text(stringResource(id = R.string.profile_use_crop))
}
}
Text(
text = "Use two fingers to zoom and move.",
text = stringResource(id = R.string.profile_crop_hint),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)

View File

@@ -75,7 +75,20 @@
<string name="common_delete">Удалить</string>
<string name="common_create">Создать</string>
<string name="common_send">Отправить</string>
<string name="common_save">Сохранить</string>
<string name="common_unknown_user">Неизвестный пользователь</string>
<string name="profile_avatar_content_description">Аватар</string>
<string name="profile_user_fallback">Пользователь</string>
<string name="profile_choose_photo">Выбрать фото</string>
<string name="profile_edit">Редактировать</string>
<string name="profile_bio">О себе</string>
<string name="profile_not_set">Не указано</string>
<string name="profile_edit_profile">Редактировать профиль</string>
<string name="profile_avatar_url">URL аватара</string>
<string name="profile_crop_avatar">Обрезать аватар</string>
<string name="profile_avatar_crop_preview">Предпросмотр обрезки аватара</string>
<string name="profile_use_crop">Использовать</string>
<string name="profile_crop_hint">Используйте два пальца для масштабирования и перемещения.</string>
<string name="chat_menu_notifications">Уведомления</string>
<string name="chat_menu_search">Поиск</string>

View File

@@ -75,7 +75,20 @@
<string name="common_delete">Delete</string>
<string name="common_create">Create</string>
<string name="common_send">Send</string>
<string name="common_save">Save</string>
<string name="common_unknown_user">Unknown user</string>
<string name="profile_avatar_content_description">Avatar</string>
<string name="profile_user_fallback">User</string>
<string name="profile_choose_photo">Choose photo</string>
<string name="profile_edit">Edit</string>
<string name="profile_bio">Bio</string>
<string name="profile_not_set">Not set</string>
<string name="profile_edit_profile">Edit profile</string>
<string name="profile_avatar_url">Avatar URL</string>
<string name="profile_crop_avatar">Crop avatar</string>
<string name="profile_avatar_crop_preview">Avatar crop preview</string>
<string name="profile_use_crop">Use</string>
<string name="profile_crop_hint">Use two fingers to zoom and move.</string>
<string name="chat_menu_notifications">Notifications</string>
<string name="chat_menu_search">Search</string>