feat: enhance keyboard height management and emoji picker synchronization in GroupSetupScreen
This commit is contained in:
@@ -54,7 +54,7 @@ class KeyboardTransitionCoordinator {
|
||||
var keyboardHeight by mutableStateOf(0.dp)
|
||||
var emojiHeight by mutableStateOf(0.dp)
|
||||
|
||||
// 🔥 Сохраняем максимальную высоту клавиатуры для правильного восстановления emoji
|
||||
// Максимальная высота клавиатуры (защищает от промежуточных значений при анимации закрытия)
|
||||
private var maxKeyboardHeight by mutableStateOf(0.dp)
|
||||
|
||||
// ============ Флаги видимости ============
|
||||
@@ -84,8 +84,10 @@ class KeyboardTransitionCoordinator {
|
||||
currentState = TransitionState.KEYBOARD_TO_EMOJI
|
||||
isTransitioning = true
|
||||
|
||||
// 🔥 Гарантируем что emojiHeight = maxKeyboardHeight (не меняется при закрытии клавиатуры)
|
||||
if (maxKeyboardHeight > 0.dp) {
|
||||
// Устанавливаем emojiHeight = текущая высота клавиатуры (клавиатура ещё открыта)
|
||||
if (keyboardHeight > 0.dp) {
|
||||
emojiHeight = keyboardHeight
|
||||
} else if (maxKeyboardHeight > 0.dp) {
|
||||
emojiHeight = maxKeyboardHeight
|
||||
}
|
||||
|
||||
@@ -234,7 +236,7 @@ class KeyboardTransitionCoordinator {
|
||||
if (height > 100.dp && height != keyboardHeight) {
|
||||
keyboardHeight = height
|
||||
|
||||
// 🔥 Сохраняем максимальную высоту
|
||||
// Обновляем maxKeyboardHeight только вверх (защита от промежуточных значений анимации)
|
||||
if (height > maxKeyboardHeight) {
|
||||
maxKeyboardHeight = height
|
||||
}
|
||||
@@ -244,14 +246,14 @@ class KeyboardTransitionCoordinator {
|
||||
emojiHeight = height
|
||||
}
|
||||
} else if (height == 0.dp && keyboardHeight != 0.dp) {
|
||||
// 🔥 Клавиатура закрывается - восстанавливаем emojiHeight до МАКСИМАЛЬНОЙ высоты
|
||||
|
||||
// Восстанавливаем emojiHeight до максимальной высоты
|
||||
if (maxKeyboardHeight > 0.dp) {
|
||||
// Клавиатура закрывается.
|
||||
// Если emoji уже показан (keyboard→emoji переход), НЕ трогаем emojiHeight —
|
||||
// requestShowEmoji() уже установил правильное значение = текущая высота клавиатуры.
|
||||
// Восстанавливаем из maxKeyboardHeight только если emoji НЕ виден (обычное закрытие).
|
||||
if (!isEmojiVisible && !isEmojiBoxVisible && maxKeyboardHeight > 0.dp) {
|
||||
emojiHeight = maxKeyboardHeight
|
||||
}
|
||||
|
||||
// Обнуляем keyboardHeight
|
||||
keyboardHeight = 0.dp
|
||||
}
|
||||
|
||||
@@ -272,7 +274,8 @@ class KeyboardTransitionCoordinator {
|
||||
* emojiHeight должна оставаться фиксированной!
|
||||
*/
|
||||
fun syncHeights() {
|
||||
// 🔥 Синхронизируем ТОЛЬКО если клавиатура ОТКРЫТА и высота больше текущей emoji
|
||||
// Синхронизируем только вверх — при закрытии клавиатуры промежуточные значения
|
||||
// не должны уменьшать emojiHeight. Точная высота ставится в requestShowEmoji().
|
||||
if (keyboardHeight > 100.dp && keyboardHeight > emojiHeight) {
|
||||
emojiHeight = keyboardHeight
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import android.view.inputmethod.InputMethodManager
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -243,15 +245,28 @@ fun GroupSetupScreen(
|
||||
}
|
||||
|
||||
var lastStableKeyboardHeight by remember { mutableStateOf(0.dp) }
|
||||
var isKeyboardVisible by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(imeBottomPx) {
|
||||
val currentImeHeight = with(density) { imeBottomPx.toDp() }
|
||||
coordinator.updateKeyboardHeight(currentImeHeight)
|
||||
isKeyboardVisible = currentImeHeight > 50.dp
|
||||
if (currentImeHeight > 100.dp) {
|
||||
coordinator.syncHeights()
|
||||
lastStableKeyboardHeight = currentImeHeight
|
||||
}
|
||||
}
|
||||
|
||||
// Save keyboard height for emoji picker sync
|
||||
LaunchedEffect(isKeyboardVisible, showEmojiKeyboard) {
|
||||
if (isKeyboardVisible && !showEmojiKeyboard) {
|
||||
kotlinx.coroutines.delay(350)
|
||||
if (isKeyboardVisible && !showEmojiKeyboard && lastStableKeyboardHeight > 300.dp) {
|
||||
val heightPx = with(density) { lastStableKeyboardHeight.toPx().toInt() }
|
||||
KeyboardHeightProvider.saveKeyboardHeight(context, heightPx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleEmojiPicker() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (now - lastToggleTime < toggleCooldownMs || step != GroupSetupStep.DETAILS || isLoading) return
|
||||
@@ -725,22 +740,24 @@ fun GroupSetupScreen(
|
||||
containerColor = if (actionEnabled) accentColor else accentColor.copy(alpha = 0.42f),
|
||||
contentColor = Color.White,
|
||||
shape = CircleShape,
|
||||
modifier =
|
||||
modifier = run {
|
||||
var lastStableFabBottom by remember { mutableStateOf(18.dp) }
|
||||
val rawBottom = if (imeBottomDp > 0.dp) {
|
||||
imeBottomDp + 14.dp
|
||||
} else if (coordinator.isEmojiBoxVisible && coordinator.emojiHeight > 0.dp) {
|
||||
coordinator.emojiHeight + 14.dp
|
||||
} else {
|
||||
18.dp
|
||||
}
|
||||
// During keyboard switch, keep FAB at last stable position
|
||||
if (!coordinator.isTransitioning) {
|
||||
lastStableFabBottom = rawBottom
|
||||
}
|
||||
Modifier
|
||||
.align(Alignment.BottomEnd)
|
||||
.padding(
|
||||
end = 16.dp,
|
||||
// Consistent: always 14dp above whichever keyboard is showing.
|
||||
// This Box ignores paddingValues, so we measure from raw screen bottom.
|
||||
bottom = if (imeBottomDp > 0.dp) {
|
||||
imeBottomDp + 14.dp
|
||||
} else if (coordinator.isEmojiBoxVisible && coordinator.emojiHeight > 0.dp) {
|
||||
coordinator.emojiHeight + 14.dp
|
||||
} else {
|
||||
18.dp
|
||||
}
|
||||
)
|
||||
.padding(end = 16.dp, bottom = lastStableFabBottom)
|
||||
.size(58.dp)
|
||||
}
|
||||
) {
|
||||
if (isLoading && step == GroupSetupStep.DESCRIPTION) {
|
||||
CircularProgressIndicator(
|
||||
|
||||
Reference in New Issue
Block a user