feat: Refactor emoji picker behavior and improve animation performance
This commit is contained in:
@@ -63,30 +63,30 @@ fun OptimizedEmojiPicker(
|
||||
onClose: () -> Unit = {},
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
// 🎭 Smooth animation для открытия/закрытия
|
||||
// 🎭 Быстрая и плавная анимация (как в Telegram)
|
||||
AnimatedVisibility(
|
||||
visible = isVisible,
|
||||
enter = slideInVertically(
|
||||
initialOffsetY = { it },
|
||||
animationSpec = tween(
|
||||
durationMillis = 250,
|
||||
durationMillis = 180, // 🔥 Быстрее!
|
||||
easing = FastOutSlowInEasing
|
||||
)
|
||||
) + fadeIn(
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
durationMillis = 120,
|
||||
easing = LinearEasing
|
||||
)
|
||||
),
|
||||
exit = slideOutVertically(
|
||||
targetOffsetY = { it },
|
||||
animationSpec = tween(
|
||||
durationMillis = 200,
|
||||
durationMillis = 150, // 🔥 Быстрое закрытие
|
||||
easing = FastOutLinearInEasing
|
||||
)
|
||||
) + fadeOut(
|
||||
animationSpec = tween(
|
||||
durationMillis = 150,
|
||||
durationMillis = 100,
|
||||
easing = LinearEasing
|
||||
)
|
||||
),
|
||||
@@ -122,8 +122,15 @@ private fun EmojiPickerContent(
|
||||
val gridState = rememberLazyGridState()
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
// 🚀 Загружаем эмодзи если еще не загружены
|
||||
// 🚀 Отложенный рендеринг - даём анимации начаться без фриза
|
||||
var shouldRenderContent by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
// Ждём 1 кадр чтобы анимация началась плавно
|
||||
kotlinx.coroutines.delay(16) // ~1 frame at 60fps
|
||||
shouldRenderContent = true
|
||||
|
||||
// Загружаем эмодзи если еще не загружены
|
||||
if (!OptimizedEmojiCache.isLoaded) {
|
||||
OptimizedEmojiCache.preload(context)
|
||||
}
|
||||
@@ -160,31 +167,45 @@ private fun EmojiPickerContent(
|
||||
.height(350.dp) // Фиксированная высота как у клавиатуры
|
||||
.background(panelBackground)
|
||||
) {
|
||||
// ============ КАТЕГОРИИ ============
|
||||
CategoryBar(
|
||||
categories = EMOJI_CATEGORIES,
|
||||
selectedCategory = selectedCategory,
|
||||
onCategorySelected = { selectedCategory = it },
|
||||
isDarkTheme = isDarkTheme,
|
||||
backgroundColor = categoryBarBackground
|
||||
)
|
||||
|
||||
// ============ РАЗДЕЛИТЕЛЬ ============
|
||||
Divider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(0.5.dp),
|
||||
color = dividerColor
|
||||
)
|
||||
|
||||
// ============ СЕТКА ЭМОДЗИ ============
|
||||
EmojiGrid(
|
||||
isLoaded = OptimizedEmojiCache.isLoaded,
|
||||
emojis = displayedEmojis,
|
||||
gridState = gridState,
|
||||
onEmojiSelected = onEmojiSelected,
|
||||
isDarkTheme = isDarkTheme
|
||||
)
|
||||
// 🔥 Показываем пустую панель пока не готово
|
||||
if (!shouldRenderContent) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(24.dp),
|
||||
color = PrimaryBlue,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// ============ КАТЕГОРИИ ============
|
||||
CategoryBar(
|
||||
categories = EMOJI_CATEGORIES,
|
||||
selectedCategory = selectedCategory,
|
||||
onCategorySelected = { selectedCategory = it },
|
||||
isDarkTheme = isDarkTheme,
|
||||
backgroundColor = categoryBarBackground
|
||||
)
|
||||
|
||||
// ============ РАЗДЕЛИТЕЛЬ ============
|
||||
Divider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(0.5.dp),
|
||||
color = dividerColor
|
||||
)
|
||||
|
||||
// ============ СЕТКА ЭМОДЗИ ============
|
||||
EmojiGrid(
|
||||
isLoaded = OptimizedEmojiCache.isLoaded,
|
||||
emojis = displayedEmojis,
|
||||
gridState = gridState,
|
||||
onEmojiSelected = onEmojiSelected,
|
||||
isDarkTheme = isDarkTheme
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user