feat: Add account initialization in ProtocolManager and enhance keyboard handling on screen exit

This commit is contained in:
k1ngsterr1
2026-01-13 21:17:47 +05:00
parent 912412bd56
commit e1b708d463
4 changed files with 60 additions and 24 deletions

View File

@@ -53,6 +53,15 @@ object ProtocolManager {
setupPacketHandlers()
}
/**
* 🔥 Инициализация аккаунта - КРИТИЧНО для получения сообщений!
* Должен вызываться после авторизации пользователя
*/
fun initializeAccount(publicKey: String, privateKey: String) {
addLog("🔐 Initializing account for message handling: ${publicKey.take(16)}...")
messageRepository?.initialize(publicKey, privateKey)
}
/**
* Настройка обработчиков пакетов
*/

View File

@@ -218,7 +218,7 @@ fun ChatDetailScreen(
onUserProfileClick: () -> Unit = {},
viewModel: ChatViewModel = viewModel()
) {
// 🔥 Автоматическое скрытие клавиатуры при выходе с экрана
// 🔥 Backup: скрывает клавиатуру при dispose (если не скрыли раньше)
HideKeyboardOnDispose()
val keyboardController = LocalSoftwareKeyboardController.current
@@ -288,14 +288,16 @@ fun ChatDetailScreen(
var selectedMessages by remember { mutableStateOf<Set<String>>(emptySet()) }
val isSelectionMode = selectedMessages.isNotEmpty()
// 🔥 Быстрое закрытие - мгновенный выход без дополнительной анимации
// 🔥 Быстрое закрытие - СНАЧАЛА скрываем клавиатуру, ПОТОМ выходим
val hideKeyboardAndBack: () -> Unit = {
// Мгновенно убираем фокус и клавиатуру
// 1. Убираем фокус (это важно сделать первым!)
focusManager.clearFocus(force = true)
keyboardController?.hide()
// Сразу выходим - анимация в MainActivity
// 2. Мгновенное синхронное скрытие клавиатуры через InputMethodManager
keyboard.hideNow()
// 3. Теперь выходим - клавиатура уже скрыта
onBack()
Unit
}
// Определяем это Saved Messages или обычный чат
@@ -378,8 +380,9 @@ fun ChatDetailScreen(
// 🔥 Cleanup при выходе из экрана
DisposableEffect(Unit) {
onDispose {
focusManager.clearFocus()
keyboardController?.hide()
// Скрываем клавиатуру синхронно (backup если не скрыли раньше)
focusManager.clearFocus(force = true)
keyboard.hideNow()
// 🔥 Закрываем диалог - сообщения больше не будут читаться автоматически
viewModel.closeDialog()
}
@@ -527,11 +530,15 @@ fun ChatDetailScreen(
) {
// 🔔 Кнопка назад с badge непрочитанных сообщений
Box {
IconButton(onClick = hideKeyboardAndBack) {
IconButton(
onClick = hideKeyboardAndBack,
modifier = Modifier.size(40.dp)
) {
Icon(
Icons.Default.ArrowBack,
Icons.Default.KeyboardArrowLeft,
contentDescription = "Back",
tint = headerIconColor
tint = headerIconColor,
modifier = Modifier.size(32.dp)
)
}
// Badge с количеством непрочитанных из других чатов
@@ -542,7 +549,7 @@ fun ChatDetailScreen(
.offset(x = (-4).dp, y = 6.dp)
.size(if (totalUnreadFromOthers > 9) 20.dp else 18.dp)
.clip(CircleShape)
.background(PrimaryBlue),
.background(Color(0xFFFF3B30)), // Красный цвет как в iOS
contentAlignment = Alignment.Center
) {
Text(
@@ -558,6 +565,8 @@ fun ChatDetailScreen(
}
}
Spacer(modifier = Modifier.width(4.dp))
// Аватар
Box(
modifier =

View File

@@ -189,6 +189,8 @@ fun ChatsListScreen(
chatsViewModel.setAccount(accountPublicKey, accountPrivateKey)
// Устанавливаем аккаунт для RecentSearchesManager
RecentSearchesManager.setAccount(accountPublicKey)
// 🔥 КРИТИЧНО: Инициализируем MessageRepository для обработки входящих сообщений
ProtocolManager.initializeAccount(accountPublicKey, accountPrivateKey)
}
}

View File

@@ -1,5 +1,6 @@
package com.rosetta.messenger.ui.components
import android.app.Activity
import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
@@ -38,10 +39,29 @@ class KeyboardManager(
private val context: Context
) {
/**
* Скрыть клавиатуру мгновенно (WindowInsetsController - API 30+)
* 🔥 Скрыть клавиатуру СИНХРОННО и МГНОВЕННО
* Использует 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() {
// WindowInsetsController - самый быстрый способ (API 30+)
ViewCompat.getWindowInsetsController(view)?.hide(WindowInsetsCompat.Type.ime())
}
@@ -86,6 +106,8 @@ fun rememberKeyboardController(): KeyboardManager {
/**
* 🔥 Автоматически скрывает клавиатуру при выходе с экрана (onDispose)
*
* ВАЖНО: Это backup. Основное скрытие должно быть в hideKeyboardAndBack()
*
* Добавьте в начало любого Composable экрана с клавиатурой:
* ```kotlin
* @Composable
@@ -99,14 +121,11 @@ fun rememberKeyboardController(): KeyboardManager {
@Composable
fun HideKeyboardOnDispose() {
val keyboard = rememberKeyboardController()
val keyboardController = LocalSoftwareKeyboardController.current
DisposableEffect(Unit) {
onDispose {
// WindowInsetsController - мгновенное скрытие
keyboard.hide()
// Fallback для Compose
keyboardController?.hide()
// Backup скрытие при dispose
keyboard.hideNow()
}
}
}
@@ -120,17 +139,14 @@ fun HideKeyboardOnDispose() {
@Composable
fun HideKeyboardAndClearFocusOnDispose() {
val keyboard = rememberKeyboardController()
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
DisposableEffect(Unit) {
onDispose {
// Сбрасываем фокус
focusManager.clearFocus(force = true)
// WindowInsetsController - мгновенное скрытие
keyboard.hide()
// Fallback для Compose
keyboardController?.hide()
// Мгновенное скрытие
keyboard.hideNow()
}
}
}