feat: Implement back gesture handling in SearchScreen for improved navigation
This commit is contained in:
@@ -2,6 +2,7 @@ package com.rosetta.messenger.ui.chats
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.*
|
import androidx.compose.animation.*
|
||||||
import androidx.compose.animation.core.*
|
import androidx.compose.animation.core.*
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
@@ -62,13 +63,15 @@ fun SearchScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Цвета ТОЧНО как в ChatsListScreen - remember для избежания пересоздания
|
// Цвета ТОЧНО как в 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 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) }
|
var isContentReady by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
// Search ViewModel - правильное создание через viewModel()
|
// Search ViewModel - правильное создание через viewModel()
|
||||||
val searchViewModel: SearchUsersViewModel = viewModel()
|
val searchViewModel: SearchUsersViewModel = viewModel()
|
||||||
val searchQuery by searchViewModel.searchQuery.collectAsState()
|
val searchQuery by searchViewModel.searchQuery.collectAsState()
|
||||||
@@ -79,29 +82,34 @@ fun SearchScreen(
|
|||||||
val recentUsers by RecentSearchesManager.recentUsers.collectAsState()
|
val recentUsers by RecentSearchesManager.recentUsers.collectAsState()
|
||||||
|
|
||||||
// 🔥 ОПТИМИЗАЦИЯ: Lottie загружается асинхронно и не блокирует первый кадр
|
// 🔥 ОПТИМИЗАЦИЯ: Lottie загружается асинхронно и не блокирует первый кадр
|
||||||
val searchLottieComposition by rememberLottieComposition(
|
val searchLottieComposition by
|
||||||
LottieCompositionSpec.RawRes(R.raw.search)
|
rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.search))
|
||||||
)
|
|
||||||
|
|
||||||
// Focus requester для автофокуса
|
// Focus requester для автофокуса
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
// 🔥 Обработка системного жеста Back
|
||||||
|
BackHandler {
|
||||||
|
hideKeyboardInstantly()
|
||||||
|
onBackClick()
|
||||||
|
}
|
||||||
|
|
||||||
// 🔥 ОПТИМИЗАЦИЯ: Все тяжелые операции выполняем после первого кадра
|
// 🔥 ОПТИМИЗАЦИЯ: Все тяжелые операции выполняем после первого кадра
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
// Даем анимации перехода завершиться
|
// Даем анимации перехода завершиться
|
||||||
kotlinx.coroutines.delay(50)
|
kotlinx.coroutines.delay(50)
|
||||||
isContentReady = true
|
isContentReady = true
|
||||||
|
|
||||||
// Устанавливаем аккаунт для RecentSearchesManager
|
// Устанавливаем аккаунт для RecentSearchesManager
|
||||||
if (currentUserPublicKey.isNotEmpty()) {
|
if (currentUserPublicKey.isNotEmpty()) {
|
||||||
RecentSearchesManager.setAccount(currentUserPublicKey)
|
RecentSearchesManager.setAccount(currentUserPublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Устанавливаем privateKeyHash
|
// Устанавливаем privateKeyHash
|
||||||
if (privateKeyHash.isNotEmpty()) {
|
if (privateKeyHash.isNotEmpty()) {
|
||||||
searchViewModel.setPrivateKeyHash(privateKeyHash)
|
searchViewModel.setPrivateKeyHash(privateKeyHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Автофокус с небольшой задержкой
|
// Автофокус с небольшой задержкой
|
||||||
kotlinx.coroutines.delay(100)
|
kotlinx.coroutines.delay(100)
|
||||||
try {
|
try {
|
||||||
@@ -204,15 +212,16 @@ fun SearchScreen(
|
|||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
// Контент - показываем recent users если поле пустое, иначе результаты
|
// Контент - показываем recent users если поле пустое, иначе результаты
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier =
|
||||||
.fillMaxSize()
|
Modifier.fillMaxSize()
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
// 🔥 ОПТИМИЗАЦИЯ: Скрываем контент до готовности без блокировки рендера
|
// 🔥 ОПТИМИЗАЦИЯ: Скрываем контент до готовности без блокировки
|
||||||
.drawWithContent {
|
// рендера
|
||||||
if (isContentReady) {
|
.drawWithContent {
|
||||||
drawContent()
|
if (isContentReady) {
|
||||||
}
|
drawContent()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
if (searchQuery.isEmpty() && recentUsers.isNotEmpty()) {
|
if (searchQuery.isEmpty() && recentUsers.isNotEmpty()) {
|
||||||
// Recent Users с аватарками
|
// Recent Users с аватарками
|
||||||
|
|||||||
Reference in New Issue
Block a user