From b26aa533332065690ad18859791e6888ac7f5b0e Mon Sep 17 00:00:00 2001 From: k1ngsterr1 Date: Mon, 19 Jan 2026 18:11:30 +0500 Subject: [PATCH] feat: Implement back gesture handling in SearchScreen for improved navigation --- .../messenger/ui/chats/SearchScreen.kt | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt index ac6046c..cc2d3b6 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/SearchScreen.kt @@ -2,6 +2,7 @@ package com.rosetta.messenger.ui.chats import android.content.Context import android.view.inputmethod.InputMethodManager +import androidx.activity.compose.BackHandler import androidx.compose.animation.* import androidx.compose.animation.core.* import androidx.compose.foundation.* @@ -62,13 +63,15 @@ fun SearchScreen( } // Цвета ТОЧНО как в ChatsListScreen - remember для избежания пересоздания - val backgroundColor = remember(isDarkTheme) { if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) } + val backgroundColor = + remember(isDarkTheme) { if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) } val textColor = remember(isDarkTheme) { if (isDarkTheme) Color.White else Color(0xFF1a1a1a) } - val secondaryTextColor = remember(isDarkTheme) { if (isDarkTheme) Color(0xFFB0B0B0) else Color(0xFF6c757d) } + val secondaryTextColor = + remember(isDarkTheme) { if (isDarkTheme) Color(0xFFB0B0B0) else Color(0xFF6c757d) } // 🔥 ОПТИМИЗАЦИЯ: Отложенный рендеринг контента для плавной анимации перехода var isContentReady by remember { mutableStateOf(false) } - + // Search ViewModel - правильное создание через viewModel() val searchViewModel: SearchUsersViewModel = viewModel() val searchQuery by searchViewModel.searchQuery.collectAsState() @@ -79,29 +82,34 @@ fun SearchScreen( val recentUsers by RecentSearchesManager.recentUsers.collectAsState() // 🔥 ОПТИМИЗАЦИЯ: Lottie загружается асинхронно и не блокирует первый кадр - val searchLottieComposition by rememberLottieComposition( - LottieCompositionSpec.RawRes(R.raw.search) - ) + val searchLottieComposition by + rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.search)) // Focus requester для автофокуса val focusRequester = remember { FocusRequester() } + // 🔥 Обработка системного жеста Back + BackHandler { + hideKeyboardInstantly() + onBackClick() + } + // 🔥 ОПТИМИЗАЦИЯ: Все тяжелые операции выполняем после первого кадра LaunchedEffect(Unit) { // Даем анимации перехода завершиться kotlinx.coroutines.delay(50) isContentReady = true - + // Устанавливаем аккаунт для RecentSearchesManager if (currentUserPublicKey.isNotEmpty()) { RecentSearchesManager.setAccount(currentUserPublicKey) } - + // Устанавливаем privateKeyHash if (privateKeyHash.isNotEmpty()) { searchViewModel.setPrivateKeyHash(privateKeyHash) } - + // Автофокус с небольшой задержкой kotlinx.coroutines.delay(100) try { @@ -204,15 +212,16 @@ fun SearchScreen( ) { paddingValues -> // Контент - показываем recent users если поле пустое, иначе результаты Box( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) - // 🔥 ОПТИМИЗАЦИЯ: Скрываем контент до готовности без блокировки рендера - .drawWithContent { - if (isContentReady) { - drawContent() - } - } + modifier = + Modifier.fillMaxSize() + .padding(paddingValues) + // 🔥 ОПТИМИЗАЦИЯ: Скрываем контент до готовности без блокировки + // рендера + .drawWithContent { + if (isContentReady) { + drawContent() + } + } ) { if (searchQuery.isEmpty() && recentUsers.isNotEmpty()) { // Recent Users с аватарками