From be60071e589a3cd285932796b9e70803a0b52a8e Mon Sep 17 00:00:00 2001 From: k1ngsterr1 Date: Wed, 14 Jan 2026 03:27:30 +0500 Subject: [PATCH] feat: Synchronize emoji panel visibility and keyboard height handling for improved UX --- .../messenger/ui/chats/ChatDetailScreen.kt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) 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 01d930a..bb88d6e 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 @@ -247,6 +247,7 @@ fun ChatDetailScreen( // Высота эмодзи панели - берём высоту клавиатуры если она открыта, иначе 280dp val imeInsets = WindowInsets.ime val imeHeight = with(density) { imeInsets.getBottom(density).toDp() } + val isKeyboardVisible = imeHeight > 50.dp // 🔥 Запоминаем высоту клавиатуры когда она открыта var savedKeyboardHeight by remember { mutableStateOf(280.dp) } @@ -258,10 +259,14 @@ fun ChatDetailScreen( // 🔥 Высота панели эмодзи = сохранённая высота клавиатуры (минимум 280.dp) val emojiPanelHeight = maxOf(savedKeyboardHeight, 280.dp) + // 🔥 Флаг видимости панели эмодзи (тот же что в MessageInputBar) - единый источник правды + val isEmojiPanelVisible = showEmojiPicker && !isKeyboardVisible + // 🔥 Анимированный отступ для списка сообщений когда emoji picker открыт + // Используем isEmojiPanelVisible для синхронизации с анимацией панели val emojiPanelPadding by animateDpAsState( - targetValue = if (showEmojiPicker && imeHeight < 50.dp) emojiPanelHeight else 0.dp, - animationSpec = tween(120, easing = FastOutSlowInEasing), + targetValue = if (isEmojiPanelVisible) emojiPanelHeight else 0.dp, + animationSpec = tween(100, easing = FastOutSlowInEasing), // 100ms как exit анимация панели label = "emojiPanelPadding" ) @@ -2017,7 +2022,7 @@ private fun MessageInputBar( // 🔥 Отслеживаем высоту клавиатуры (Telegram-style) val imeInsets = WindowInsets.ime val imeHeight = with(density) { imeInsets.getBottom(density).toDp() } - val isKeyboardVisible = imeHeight > 0.dp + val isKeyboardVisible = imeHeight > 50.dp // 🔥 Согласованный порог с ChatDetailScreen // 🔥 Запоминаем высоту клавиатуры когда она открыта // Дефолт 320.dp - хорошая высота для большинства устройств @@ -2095,7 +2100,7 @@ private fun MessageInputBar( modifier = Modifier .fillMaxWidth() .graphicsLayer { clip = false } - .windowInsetsPadding(WindowInsets.ime.only(WindowInsetsSides.Bottom)) + // 🔥 Убран windowInsetsPadding - IME padding обрабатывается в родительском ChatDetailScreen ) { // Если пользователь заблокирован - показываем BlockedChatFooter (плоский как инпут) if (isBlocked) { @@ -2327,11 +2332,11 @@ private fun MessageInputBar( visible = showPanel, enter = slideInVertically( initialOffsetY = { it }, // Снизу вверх - animationSpec = tween(120, easing = FastOutSlowInEasing) + animationSpec = tween(100, easing = FastOutSlowInEasing) ), exit = slideOutVertically( targetOffsetY = { it }, // Сверху вниз - animationSpec = tween(100, easing = FastOutSlowInEasing) + animationSpec = tween(100, easing = FastOutSlowInEasing) // 🔥 Синхронизировано с padding анимацией ) ) { AppleEmojiPickerPanel(