feat: Remove animation for emoji picker when keyboard opens and optimize height handling
This commit is contained in:
@@ -2298,73 +2298,49 @@ private fun MessageInputBar(
|
|||||||
} // Закрытие внешней Column с border
|
} // Закрытие внешней Column с border
|
||||||
} // End of else (not blocked)
|
} // End of else (not blocked)
|
||||||
|
|
||||||
// <20> APPLE EMOJI PICKER - ОПТИМИЗИРОВАННАЯ АНИМАЦИЯ
|
|
||||||
// Используем slide up + alpha вместо height анимации (нет relayout = супер плавно)
|
// 🔥 APPLE EMOJI PICKER - БЕЗ анимации когда клавиатура открывается
|
||||||
if (!isBlocked) {
|
if (!isBlocked) {
|
||||||
// Панель ВСЕГДА в DOM (pre-render), просто скрыта через offset/alpha
|
// Высота панели: 0 если клавиатура видна или эмодзи закрыты, иначе emojiPanelHeight
|
||||||
val shouldShow = showEmojiPicker && !isKeyboardVisible
|
val targetHeight = if (isKeyboardVisible || !showEmojiPicker) 0.dp else emojiPanelHeight
|
||||||
|
|
||||||
// 🚀 Animatable для максимального контроля (быстрее чем animateDpAsState)
|
// Анимируем только когда клавиатура закрыта
|
||||||
val slideProgress = remember { Animatable(0f) }
|
val animatedHeight by animateDpAsState(
|
||||||
|
targetValue = targetHeight,
|
||||||
LaunchedEffect(shouldShow) {
|
animationSpec = if (isKeyboardVisible) {
|
||||||
if (shouldShow) {
|
// Мгновенно когда клавиатура открывается
|
||||||
// Открытие: быстрая spring анимация (critically damped = без пружинистости)
|
snap()
|
||||||
slideProgress.animateTo(
|
|
||||||
targetValue = 1f,
|
|
||||||
animationSpec = spring(
|
|
||||||
dampingRatio = 1f, // Critically damped - без bounce
|
|
||||||
stiffness = 800f // Высокая жёсткость = быстро
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// Закрытие: мгновенно если клавиатура открылась, иначе быстрая анимация
|
// Быстрая анимация (200ms)
|
||||||
if (isKeyboardVisible) {
|
tween(durationMillis = 200, easing = FastOutSlowInEasing)
|
||||||
slideProgress.snapTo(0f)
|
},
|
||||||
} else {
|
label = "EmojiPanelHeight"
|
||||||
slideProgress.animateTo(
|
)
|
||||||
targetValue = 0f,
|
|
||||||
animationSpec = tween(120, easing = FastOutSlowInEasing)
|
// 🔥 Показываем Box только когда есть высота (НЕ занимает место когда скрыт!)
|
||||||
|
if (animatedHeight > 0.dp) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(animatedHeight)
|
||||||
|
.padding(bottom = 16.dp)
|
||||||
|
) {
|
||||||
|
if (showEmojiPicker) {
|
||||||
|
AppleEmojiPickerPanel(
|
||||||
|
isDarkTheme = isDarkTheme,
|
||||||
|
onEmojiSelected = { emoji ->
|
||||||
|
onValueChange(value + emoji)
|
||||||
|
},
|
||||||
|
onClose = {
|
||||||
|
onToggleEmojiPicker(false)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(emojiPanelHeight - 16.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val panelHeightPx = with(LocalDensity.current) { (emojiPanelHeight - 16.dp).toPx() }
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(emojiPanelHeight)
|
|
||||||
.padding(bottom = 16.dp)
|
|
||||||
.graphicsLayer {
|
|
||||||
// 🚀 Slide up анимация через translationY (НЕ вызывает relayout!)
|
|
||||||
translationY = panelHeightPx * (1f - slideProgress.value)
|
|
||||||
alpha = slideProgress.value
|
|
||||||
// Hardware layer для плавности
|
|
||||||
if (slideProgress.value > 0f && slideProgress.value < 1f) {
|
|
||||||
shadowElevation = 0f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.clipToBounds() // Обрезаем контент при slide
|
|
||||||
) {
|
|
||||||
// 🚀 Панель ВСЕГДА рендерится (pre-render для instant open)
|
|
||||||
// Но скрыта через alpha = 0 когда не нужна
|
|
||||||
if (slideProgress.value > 0f || shouldShow) {
|
|
||||||
AppleEmojiPickerPanel(
|
|
||||||
isDarkTheme = isDarkTheme,
|
|
||||||
onEmojiSelected = { emoji ->
|
|
||||||
onValueChange(value + emoji)
|
|
||||||
},
|
|
||||||
onClose = {
|
|
||||||
onToggleEmojiPicker(false)
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(emojiPanelHeight - 16.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // End of if (!isBlocked) for emoji picker
|
} // End of if (!isBlocked) for emoji picker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user