From 1484d67d7f32033af97b2099d7203364ee8cd131 Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 5 Apr 2026 15:17:57 +0300 Subject: [PATCH] feat: polish chat reply and edit composer bar feat: replace the old action strip with a Telegram-like compact reply preview feat: show author labels, message snippets, and close action inline above the composer --- .../messenger/ui/chat/ChatScreen.kt | 72 ++++++++++++++----- .../app/src/main/res/values-ru/strings.xml | 2 + android/app/src/main/res/values/strings.xml | 2 + 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt index d90f300..b0a7552 100644 --- a/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt +++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatScreen.kt @@ -1711,28 +1711,66 @@ private fun ChatScreen( } } - if (state.replyToMessage != null || state.editingMessage != null) { - val header = if (state.editingMessage != null) { - stringResource(id = R.string.chat_editing_message, state.editingMessage.id) + AnimatedVisibility( + visible = state.replyToMessage != null || state.editingMessage != null, + enter = fadeIn(), + exit = fadeOut(), + ) { + val composeTarget = state.editingMessage ?: state.replyToMessage + val composeLabel = if (state.editingMessage != null) { + stringResource(id = R.string.chat_editing_label) } else { - "${stringResource(id = R.string.chat_reply_to)} ${ - state.replyToMessage?.senderDisplayName - ?.takeIf { it.isNotBlank() } - ?: state.replyToMessage?.senderUsername?.takeIf { it.isNotBlank() }?.let { "@$it" } - ?: state.replyToMessage?.senderId?.let { senderNameByUserId[it] } - ?: stringResource(id = R.string.common_unknown_user) - }" + state.replyToMessage?.senderDisplayName + ?.takeIf { it.isNotBlank() } + ?: state.replyToMessage?.senderUsername?.takeIf { it.isNotBlank() }?.let { "@$it" } + ?: state.replyToMessage?.senderId?.let { senderNameByUserId[it] } + ?: stringResource(id = R.string.common_unknown_user) } - Row( + val composeSnippet = composeTarget?.text?.takeIf { it.isNotBlank() } + ?: composeTarget?.attachments?.firstOrNull()?.fileType + ?: composeTarget?.type?.let { "[$it]" } + ?: stringResource(id = R.string.chat_compose_preview_empty) + Surface( modifier = Modifier .fillMaxWidth() - .background(MaterialTheme.colorScheme.secondaryContainer) - .padding(horizontal = 12.dp, vertical = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, + .padding(horizontal = 10.dp, vertical = 4.dp), + color = MaterialTheme.colorScheme.surface.copy(alpha = 0.92f), + shape = RoundedCornerShape(18.dp), ) { - Text(text = header, style = MaterialTheme.typography.bodySmall) - Button(onClick = onCancelComposeAction) { Text(stringResource(id = R.string.common_cancel)) } + Row( + modifier = Modifier.padding(horizontal = 12.dp, vertical = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(10.dp), + ) { + Box( + modifier = Modifier + .width(3.dp) + .height(34.dp) + .clip(RoundedCornerShape(6.dp)) + .background(MaterialTheme.colorScheme.primary), + ) + Column(modifier = Modifier.weight(1f)) { + Text( + text = composeLabel, + style = MaterialTheme.typography.labelMedium, + fontWeight = FontWeight.SemiBold, + color = MaterialTheme.colorScheme.primary, + maxLines = 1, + ) + Text( + text = composeSnippet, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 1, + ) + } + IconButton(onClick = onCancelComposeAction) { + Icon( + imageVector = Icons.Filled.Close, + contentDescription = stringResource(id = R.string.common_cancel), + ) + } + } } } diff --git a/android/app/src/main/res/values-ru/strings.xml b/android/app/src/main/res/values-ru/strings.xml index 80eb6ec..d8e9570 100644 --- a/android/app/src/main/res/values-ru/strings.xml +++ b/android/app/src/main/res/values-ru/strings.xml @@ -122,7 +122,9 @@ Нет доступных чатов Пересылка... Редактирование сообщения #%1$d + Редактирование сообщения Ответ + Вложение Удалить выбранное сообщение для всех? Удалить выбранные сообщения у вас? Удалить все сообщения в этом чате? Это действие нельзя отменить. diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 8bf4774..e77fc57 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -122,7 +122,9 @@ No available chats Forwarding... Editing message #%1$d + Editing message Reply to + Attachment Delete selected message for everyone? Delete selected message(s) for you? Delete all messages in this chat? This action cannot be undone.