feat: Synchronize emoji panel visibility and keyboard height handling for improved UX

This commit is contained in:
k1ngsterr1
2026-01-14 03:27:30 +05:00
parent 85ebddc91a
commit be60071e58

View File

@@ -247,6 +247,7 @@ fun ChatDetailScreen(
// Высота эмодзи панели - берём высоту клавиатуры если она открыта, иначе 280dp // Высота эмодзи панели - берём высоту клавиатуры если она открыта, иначе 280dp
val imeInsets = WindowInsets.ime val imeInsets = WindowInsets.ime
val imeHeight = with(density) { imeInsets.getBottom(density).toDp() } val imeHeight = with(density) { imeInsets.getBottom(density).toDp() }
val isKeyboardVisible = imeHeight > 50.dp
// 🔥 Запоминаем высоту клавиатуры когда она открыта // 🔥 Запоминаем высоту клавиатуры когда она открыта
var savedKeyboardHeight by remember { mutableStateOf(280.dp) } var savedKeyboardHeight by remember { mutableStateOf(280.dp) }
@@ -258,10 +259,14 @@ fun ChatDetailScreen(
// 🔥 Высота панели эмодзи = сохранённая высота клавиатуры (минимум 280.dp) // 🔥 Высота панели эмодзи = сохранённая высота клавиатуры (минимум 280.dp)
val emojiPanelHeight = maxOf(savedKeyboardHeight, 280.dp) val emojiPanelHeight = maxOf(savedKeyboardHeight, 280.dp)
// 🔥 Флаг видимости панели эмодзи (тот же что в MessageInputBar) - единый источник правды
val isEmojiPanelVisible = showEmojiPicker && !isKeyboardVisible
// 🔥 Анимированный отступ для списка сообщений когда emoji picker открыт // 🔥 Анимированный отступ для списка сообщений когда emoji picker открыт
// Используем isEmojiPanelVisible для синхронизации с анимацией панели
val emojiPanelPadding by animateDpAsState( val emojiPanelPadding by animateDpAsState(
targetValue = if (showEmojiPicker && imeHeight < 50.dp) emojiPanelHeight else 0.dp, targetValue = if (isEmojiPanelVisible) emojiPanelHeight else 0.dp,
animationSpec = tween(120, easing = FastOutSlowInEasing), animationSpec = tween(100, easing = FastOutSlowInEasing), // 100ms как exit анимация панели
label = "emojiPanelPadding" label = "emojiPanelPadding"
) )
@@ -2017,7 +2022,7 @@ private fun MessageInputBar(
// 🔥 Отслеживаем высоту клавиатуры (Telegram-style) // 🔥 Отслеживаем высоту клавиатуры (Telegram-style)
val imeInsets = WindowInsets.ime val imeInsets = WindowInsets.ime
val imeHeight = with(density) { imeInsets.getBottom(density).toDp() } val imeHeight = with(density) { imeInsets.getBottom(density).toDp() }
val isKeyboardVisible = imeHeight > 0.dp val isKeyboardVisible = imeHeight > 50.dp // 🔥 Согласованный порог с ChatDetailScreen
// 🔥 Запоминаем высоту клавиатуры когда она открыта // 🔥 Запоминаем высоту клавиатуры когда она открыта
// Дефолт 320.dp - хорошая высота для большинства устройств // Дефолт 320.dp - хорошая высота для большинства устройств
@@ -2095,7 +2100,7 @@ private fun MessageInputBar(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.graphicsLayer { clip = false } .graphicsLayer { clip = false }
.windowInsetsPadding(WindowInsets.ime.only(WindowInsetsSides.Bottom)) // 🔥 Убран windowInsetsPadding - IME padding обрабатывается в родительском ChatDetailScreen
) { ) {
// Если пользователь заблокирован - показываем BlockedChatFooter (плоский как инпут) // Если пользователь заблокирован - показываем BlockedChatFooter (плоский как инпут)
if (isBlocked) { if (isBlocked) {
@@ -2327,11 +2332,11 @@ private fun MessageInputBar(
visible = showPanel, visible = showPanel,
enter = slideInVertically( enter = slideInVertically(
initialOffsetY = { it }, // Снизу вверх initialOffsetY = { it }, // Снизу вверх
animationSpec = tween(120, easing = FastOutSlowInEasing) animationSpec = tween(100, easing = FastOutSlowInEasing)
), ),
exit = slideOutVertically( exit = slideOutVertically(
targetOffsetY = { it }, // Сверху вниз targetOffsetY = { it }, // Сверху вниз
animationSpec = tween(100, easing = FastOutSlowInEasing) animationSpec = tween(100, easing = FastOutSlowInEasing) // 🔥 Синхронизировано с padding анимацией
) )
) { ) {
AppleEmojiPickerPanel( AppleEmojiPickerPanel(