Поправлен визуал пузырьков со звонками
This commit is contained in:
@@ -1277,7 +1277,8 @@ fun MainScreen(
|
||||
isDarkTheme = isDarkTheme,
|
||||
chatWallpaperId = chatWallpaperId,
|
||||
avatarRepository = avatarRepository,
|
||||
onImageViewerChanged = { isLocked -> isChatSwipeLocked = isLocked }
|
||||
onImageViewerChanged = { isLocked -> isChatSwipeLocked = isLocked },
|
||||
isCallActive = callUiState.isVisible
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ object CallManager {
|
||||
updateState {
|
||||
it.copy(
|
||||
phase = CallPhase.OUTGOING,
|
||||
statusText = "Calling..."
|
||||
statusText = "Calling"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -655,9 +655,14 @@ fun MessageInputBar(
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user