feat: Remove HideKeyboardOnDispose component to streamline keyboard management across screens

This commit is contained in:
k1ngsterr1
2026-01-13 21:35:31 +05:00
parent 7f89ffc779
commit 145a3621a1
7 changed files with 2 additions and 194 deletions

View File

@@ -1,166 +0,0 @@
package com.rosetta.messenger.ui.components
import android.app.Activity
import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.LocalView
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
/**
* 🎹 Контроллер клавиатуры для Rosetta Messenger
*
* Использует современный WindowInsetsController (API 30+) для мгновенного
* скрытия клавиатуры. Решает проблему "залипания" клавиатуры при навигации.
*
* Использование:
* ```kotlin
* @Composable
* fun MyScreen() {
* // Автоматически скрывает клавиатуру при выходе с экрана
* HideKeyboardOnDispose()
*
* // Или получите контроллер для ручного управления
* val keyboard = rememberKeyboardController()
* Button(onClick = { keyboard.hide() }) { Text("Hide") }
* }
* ```
*/
class KeyboardManager(
private val view: View,
private val context: Context
) {
/**
* 🔥 Скрыть клавиатуру СИНХРОННО и МГНОВЕННО
* Использует InputMethodManager - самый надёжный способ
*/
fun hideNow() {
// 1. Убираем фокус с текущего view
view.clearFocus()
// 2. InputMethodManager - синхронное скрытие
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
imm?.hideSoftInputFromWindow(view.windowToken, 0)
// 3. WindowInsetsController как backup
try {
ViewCompat.getWindowInsetsController(view)?.hide(WindowInsetsCompat.Type.ime())
} catch (e: Exception) {
// Ignore
}
}
/**
* Скрыть клавиатуру (асинхронно через WindowInsetsController)
*/
fun hide() {
ViewCompat.getWindowInsetsController(view)?.hide(WindowInsetsCompat.Type.ime())
}
/**
* Показать клавиатуру
*/
fun show() {
ViewCompat.getWindowInsetsController(view)?.show(WindowInsetsCompat.Type.ime())
}
/**
* Скрыть клавиатуру с fallback для старых устройств
*/
fun hideWithFallback() {
// Сначала пробуем WindowInsetsController
ViewCompat.getWindowInsetsController(view)?.hide(WindowInsetsCompat.Type.ime())
// Fallback через InputMethodManager
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
imm?.hideSoftInputFromWindow(view.windowToken, 0)
}
/**
* Проверить, видна ли клавиатура
*/
fun isVisible(): Boolean {
val insets = ViewCompat.getRootWindowInsets(view)
return insets?.isVisible(WindowInsetsCompat.Type.ime()) == true
}
}
/**
* Composable для получения KeyboardManager
*/
@Composable
fun rememberKeyboardController(): KeyboardManager {
val view = LocalView.current
val context = LocalContext.current
return remember(view, context) { KeyboardManager(view, context) }
}
/**
* 🔥 Автоматически скрывает клавиатуру при выходе с экрана (onDispose)
*
* ВАЖНО: Это backup. Основное скрытие должно быть в hideKeyboardAndBack()
*
* Добавьте в начало любого Composable экрана с клавиатурой:
* ```kotlin
* @Composable
* fun ChatScreen() {
* HideKeyboardOnDispose()
* // ... остальной UI
* }
* ```
*/
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun HideKeyboardOnDispose() {
val keyboard = rememberKeyboardController()
DisposableEffect(Unit) {
onDispose {
// Backup скрытие при dispose
keyboard.hideNow()
}
}
}
/**
* 🔥 Расширенная версия с очисткой фокуса
*
* Использовать когда нужно также сбросить фокус с TextField
*/
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun HideKeyboardAndClearFocusOnDispose() {
val keyboard = rememberKeyboardController()
val focusManager = LocalFocusManager.current
DisposableEffect(Unit) {
onDispose {
// Сбрасываем фокус
focusManager.clearFocus(force = true)
// Мгновенное скрытие
keyboard.hideNow()
}
}
}
/**
* Extension function для View - скрыть клавиатуру мгновенно
*/
fun View.hideKeyboardNow() {
ViewCompat.getWindowInsetsController(this)?.hide(WindowInsetsCompat.Type.ime())
}
/**
* Extension function для View - показать клавиатуру
*/
fun View.showKeyboardNow() {
ViewCompat.getWindowInsetsController(this)?.show(WindowInsetsCompat.Type.ime())
}