diff --git a/app/src/main/java/com/rosetta/messenger/MainActivity.kt b/app/src/main/java/com/rosetta/messenger/MainActivity.kt index 823917f..c7353ad 100644 --- a/app/src/main/java/com/rosetta/messenger/MainActivity.kt +++ b/app/src/main/java/com/rosetta/messenger/MainActivity.kt @@ -1277,7 +1277,8 @@ fun MainScreen( isDarkTheme = isDarkTheme, chatWallpaperId = chatWallpaperId, avatarRepository = avatarRepository, - onImageViewerChanged = { isLocked -> isChatSwipeLocked = isLocked } + onImageViewerChanged = { isLocked -> isChatSwipeLocked = isLocked }, + isCallActive = callUiState.isVisible ) } } diff --git a/app/src/main/java/com/rosetta/messenger/network/CallManager.kt b/app/src/main/java/com/rosetta/messenger/network/CallManager.kt index 55b3a3e..cc576b8 100644 --- a/app/src/main/java/com/rosetta/messenger/network/CallManager.kt +++ b/app/src/main/java/com/rosetta/messenger/network/CallManager.kt @@ -199,7 +199,7 @@ object CallManager { updateState { it.copy( phase = CallPhase.OUTGOING, - statusText = "Calling..." + statusText = "Calling" ) } diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt index ca3e0bc..7c5511d 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt @@ -295,7 +295,8 @@ fun ChatDetailScreen( isDarkTheme: Boolean, chatWallpaperId: String = "", avatarRepository: AvatarRepository? = null, - onImageViewerChanged: (Boolean) -> Unit = {} + onImageViewerChanged: (Boolean) -> Unit = {}, + isCallActive: Boolean = false ) { val viewModel: ChatViewModel = viewModel(key = "chat_${user.publicKey}") val context = LocalContext.current @@ -381,6 +382,13 @@ fun ChatDetailScreen( // Логирование изменений selection mode LaunchedEffect(isSelectionMode, selectedMessages.size) {} + // Сброс выделения при начале звонка + LaunchedEffect(isCallActive) { + if (isCallActive) { + selectedMessages = emptySet() + } + } + // 🔥 Backup: если клавиатура ещё открыта когда selection mode активировался // (клавиатура уже должна быть закрыта в onLongClick, это только backup) LaunchedEffect(isSelectionMode) { @@ -2974,7 +2982,7 @@ fun ChatDetailScreen( avatarRepository = avatarRepository, onLongClick = { - if (simplePickerPreviewUri != null) { + if (simplePickerPreviewUri != null || isCallActive) { return@MessageBubble } // 📳 Haptic feedback при долгом нажатии @@ -3017,7 +3025,7 @@ fun ChatDetailScreen( ) }, onClick = { - if (simplePickerPreviewUri != null) { + if (simplePickerPreviewUri != null || isCallActive) { return@MessageBubble } if (shouldIgnoreTapAfterLongPress( @@ -3039,12 +3047,17 @@ fun ChatDetailScreen( message.attachments.all { it.type == AttachmentType.IMAGE } + val isCallMessage = + message.attachments.isNotEmpty() && + message.attachments.all { + it.type == AttachmentType.CALL + } if (isSelectionMode) { toggleMessageSelection( selectionKey, !hasAvatar ) - } else if (!hasAvatar && !isPhotoOnly) { + } else if (!hasAvatar && (!isPhotoOnly || isCallMessage)) { // 💬 Tap = context menu contextMenuMessage = message showContextMenu = true diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt index dff05b0..28d2e72 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/AttachmentComponents.kt @@ -1593,7 +1593,7 @@ private fun resolveDesktopCallUi(preview: String, isOutgoing: Boolean): DesktopC } val subtitle = if (isError) { - "Call was not answered or was rejected" + if (isOutgoing) "Rejected" else "Missed" } else { formatDesktopCallDuration(durationSec) } @@ -1612,19 +1612,14 @@ fun CallAttachment( val callUi = remember(attachment.preview, isOutgoing) { resolveDesktopCallUi(attachment.preview, isOutgoing) } - val containerShape = RoundedCornerShape(10.dp) + val containerShape = RoundedCornerShape(17.dp) val containerBackground = if (isOutgoing) { - Color.White.copy(alpha = 0.12f) + PrimaryBlue } else { - if (isDarkTheme) Color(0xFF1F2733) else Color(0xFFF3F8FF) - } - val containerBorder = - if (isOutgoing) { - Color.White.copy(alpha = 0.2f) - } else { - if (isDarkTheme) Color(0xFF33435A) else Color(0xFFD8E5F4) + if (isDarkTheme) Color(0xFF212121) else Color(0xFFF5F5F5) } + val containerBorder = Color.Transparent val iconBackground = if (callUi.isError) Color(0xFFE55A5A) else PrimaryBlue val iconVector = when { @@ -1690,59 +1685,6 @@ fun CallAttachment( ) } - if (isOutgoing) { - Spacer(modifier = Modifier.width(8.dp)) - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = android.text.format.DateFormat.format("HH:mm", timestamp).toString(), - fontSize = 11.sp, - color = Color.White.copy(alpha = 0.7f) - ) - Spacer(modifier = Modifier.width(4.dp)) - when (messageStatus) { - MessageStatus.SENDING -> { - Icon( - painter = TelegramIcons.Clock, - contentDescription = null, - tint = Color.White.copy(alpha = 0.7f), - modifier = Modifier.size(14.dp) - ) - } - MessageStatus.SENT, MessageStatus.DELIVERED -> { - Icon( - painter = TelegramIcons.Done, - contentDescription = null, - tint = Color.White.copy(alpha = 0.8f), - modifier = Modifier.size(14.dp) - ) - } - MessageStatus.READ -> { - Box(modifier = Modifier.height(14.dp)) { - Icon( - painter = TelegramIcons.Done, - contentDescription = null, - tint = Color.White, - modifier = Modifier.size(14.dp) - ) - Icon( - painter = TelegramIcons.Done, - contentDescription = null, - tint = Color.White, - modifier = Modifier.size(14.dp).offset(x = 4.dp) - ) - } - } - MessageStatus.ERROR -> { - Icon( - imageVector = Icons.Default.Error, - contentDescription = null, - tint = Color(0xFFE53935), - modifier = Modifier.size(14.dp) - ) - } - } - } - } } } } diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt index 8ba9f5e..513c993 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/components/ChatDetailComponents.kt @@ -666,6 +666,15 @@ fun MessageBubble( .IMAGE } + val isCallMessage = + message.attachments.isNotEmpty() && + message.text.isEmpty() && + message.replyData == null && + message.forwardedMessages.isEmpty() && + message.attachments.all { + it.type == AttachmentType.CALL + } + val isStandaloneGroupInvite = message.attachments.isEmpty() && message.replyData == null && @@ -794,7 +803,8 @@ fun MessageBubble( onLongClick = onLongClick ) .then( - if (false) { + if (isCallMessage) { + // Звонки без фонового пузырька — у них свой контейнер внутри CallAttachment Modifier } else { Modifier.clip(bubbleShape) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt index c673a68..09efa68 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt @@ -652,12 +652,17 @@ fun MessageInputBar( Spacer(modifier = Modifier.height(2.dp)) if (panelReplyMessages.isNotEmpty()) { val msg = panelReplyMessages.first() - val hasImageAttachment = msg.attachments.any { + val hasImageAttachment = msg.attachments.any { it.type == AttachmentType.IMAGE } + val hasCallAttachment = msg.attachments.any { + it.type == AttachmentType.CALL + } AppleEmojiText( text = if (panelReplyMessages.size == 1) { - if (msg.text.isEmpty() && hasImageAttachment) { + if (msg.text.isEmpty() && hasCallAttachment) { + "Call" + } else if (msg.text.isEmpty() && hasImageAttachment) { "Photo" } else { val shortText = msg.text.take(40)