feat: Simplify search results condition in ChatsListScreen

This commit is contained in:
k1ngsterr1
2026-01-10 19:33:25 +05:00
parent fa634936f5
commit 3d8c9570b4
4 changed files with 63 additions and 40 deletions

View File

@@ -77,13 +77,14 @@ class PacketSearch : Packet() {
override fun receive(stream: Stream) { override fun receive(stream: Stream) {
privateKey = stream.readString() privateKey = stream.readString()
search = stream.readString() search = stream.readString()
val userCount = stream.readInt32() val userCount = stream.readInt16() // Int16, not Int32!
val usersList = mutableListOf<SearchUser>() val usersList = mutableListOf<SearchUser>()
for (i in 0 until userCount) { for (i in 0 until userCount) {
// Order: username, title, publicKey, verified, online (matching React Native)
val user = SearchUser( val user = SearchUser(
publicKey = stream.readString(),
title = stream.readString(),
username = stream.readString(), username = stream.readString(),
title = stream.readString(),
publicKey = stream.readString(),
verified = stream.readInt8(), verified = stream.readInt8(),
online = stream.readInt8() online = stream.readInt8()
) )

View File

@@ -135,11 +135,11 @@ class Protocol(
} }
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) { override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
log("WebSocket closing: $code - $reason") log("⚠️ WebSocket closing: $code - $reason")
} }
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
log("WebSocket closed: $code - $reason") log("WebSocket closed: $code - $reason")
handleDisconnect() handleDisconnect()
} }
@@ -210,6 +210,10 @@ class Protocol(
log("📤 Sending packet: ${packet.getPacketId()} (${data.size} bytes)") log("📤 Sending packet: ${packet.getPacketId()} (${data.size} bytes)")
// Debug: log first 50 bytes as hex
val hexDump = data.take(50).joinToString(" ") { String.format("%02X", it) }
log(" Hex: $hexDump${if (data.size > 50) "..." else ""}")
webSocket?.send(ByteString.of(*data)) webSocket?.send(ByteString.of(*data))
} }
@@ -222,10 +226,14 @@ class Protocol(
private fun handleMessage(data: ByteArray) { private fun handleMessage(data: ByteArray) {
try { try {
// Debug: log first 50 bytes as hex
val hexDump = data.take(50).joinToString(" ") { String.format("%02X", it.toInt() and 0xFF) }
log("📥 Received ${data.size} bytes: $hexDump${if (data.size > 50) "..." else ""}")
val stream = Stream(data) val stream = Stream(data)
val packetId = stream.readInt16() val packetId = stream.readInt16()
log("📥 Received packet: $packetId") log("📥 Packet ID: $packetId")
val packetFactory = supportedPackets[packetId] val packetFactory = supportedPackets[packetId]
if (packetFactory == null) { if (packetFactory == null) {
@@ -246,6 +254,7 @@ class Protocol(
} }
} catch (e: Exception) { } catch (e: Exception) {
log("❌ Error parsing packet: ${e.message}") log("❌ Error parsing packet: ${e.message}")
e.printStackTrace()
} }
} }

View File

@@ -757,8 +757,8 @@ fun ChatsListScreen(
.fillMaxSize() .fillMaxSize()
.padding(paddingValues) .padding(paddingValues)
) { ) {
// Show search results when search is expanded and has query // Show search results when search is expanded
if (isSearchExpanded && searchQuery.isNotEmpty()) { if (isSearchExpanded) {
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
// Search Results List // Search Results List
SearchResultsList( SearchResultsList(
@@ -767,6 +767,9 @@ fun ChatsListScreen(
currentUserPublicKey = accountPublicKey, currentUserPublicKey = accountPublicKey,
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
onUserClick = { user -> onUserClick = { user ->
// Логируем выбор пользователя
ProtocolManager.addLog("🎯 User selected: ${user.title.ifEmpty { user.publicKey.take(10) }}")
ProtocolManager.addLog(" PublicKey: ${user.publicKey.take(20)}...")
// Закрываем поиск и вызываем callback // Закрываем поиск и вызываем callback
searchViewModel.collapseSearch() searchViewModel.collapseSearch()
onUserSelect(user) onUserSelect(user)
@@ -774,41 +777,42 @@ fun ChatsListScreen(
) )
} }
} else { } else {
// Console button - hidden for now
AnimatedVisibility(
visible = false,
enter = fadeIn(tween(500, delayMillis = 400)) + slideInHorizontally(
initialOffsetX = { -it },
animationSpec = tween(500, delayMillis = 400)
),
modifier = Modifier
.align(Alignment.BottomStart)
.padding(16.dp)
) {
FloatingActionButton(
onClick = { showDevConsole = true },
containerColor = if (isDarkTheme) Color(0xFF2A2A2A) else Color(0xFFF5F5F5),
contentColor = if (protocolState == ProtocolState.AUTHENTICATED)
Color(0xFF4CAF50)
else
Color(0xFFFF9800),
shape = CircleShape,
modifier = Modifier.size(48.dp)
) {
Icon(
Icons.Default.Terminal,
contentDescription = "Dev Console",
modifier = Modifier.size(24.dp)
)
}
}
// Empty state with Lottie animation // Empty state with Lottie animation
EmptyChatsState( EmptyChatsState(
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) )
} }
// Console button - always visible at bottom left
AnimatedVisibility(
visible = visible,
enter = fadeIn(tween(500, delayMillis = 400)) + slideInHorizontally(
initialOffsetX = { -it },
animationSpec = tween(500, delayMillis = 400)
),
modifier = Modifier
.align(Alignment.BottomStart)
.padding(16.dp)
) {
FloatingActionButton(
onClick = { showDevConsole = true },
containerColor = if (isDarkTheme) Color(0xFF2A2A2A) else Color(0xFFF5F5F5),
contentColor = when (protocolState) {
ProtocolState.AUTHENTICATED -> Color(0xFF4CAF50)
ProtocolState.CONNECTING, ProtocolState.HANDSHAKING -> Color(0xFFFFA726)
else -> Color(0xFFFF5722)
},
shape = CircleShape,
modifier = Modifier.size(48.dp)
) {
Icon(
Icons.Default.Terminal,
contentDescription = "Dev Console",
modifier = Modifier.size(24.dp)
)
}
}
} }
} }
} }

View File

@@ -40,7 +40,13 @@ class SearchUsersViewModel : ViewModel() {
// Callback для обработки ответа поиска // Callback для обработки ответа поиска
private val searchPacketHandler: (com.rosetta.messenger.network.Packet) -> Unit = { packet -> private val searchPacketHandler: (com.rosetta.messenger.network.Packet) -> Unit = { packet ->
if (packet is PacketSearch) { if (packet is PacketSearch) {
android.util.Log.d("SearchUsersVM", "📥 Search results received: ${packet.users.size} users") ProtocolManager.addLog("📥 Search response received")
ProtocolManager.addLog(" Users found: ${packet.users.size}")
packet.users.forEachIndexed { index, user ->
ProtocolManager.addLog(" [$index] ${user.title.ifEmpty { "No title" }} (@${user.username.ifEmpty { "no username" }})")
ProtocolManager.addLog(" Key: ${user.publicKey.take(20)}...")
ProtocolManager.addLog(" Verified: ${user.verified}, Online: ${user.online}")
}
_searchResults.value = packet.users _searchResults.value = packet.users
_isSearching.value = false _isSearching.value = false
} }
@@ -97,7 +103,7 @@ class SearchUsersViewModel : ViewModel() {
// Проверяем состояние протокола // Проверяем состояние протокола
if (ProtocolManager.state.value != ProtocolState.AUTHENTICATED) { if (ProtocolManager.state.value != ProtocolState.AUTHENTICATED) {
android.util.Log.w("SearchUsersVM", "Not authenticated, cannot search") ProtocolManager.addLog("⚠️ Search failed: Not authenticated")
_isSearching.value = false _isSearching.value = false
return@launch return@launch
} }
@@ -109,7 +115,8 @@ class SearchUsersViewModel : ViewModel() {
lastSearchedText = query lastSearchedText = query
android.util.Log.d("SearchUsersVM", "🔍 Sending search request: $query") ProtocolManager.addLog("🔍 Searching for: \"$query\"")
ProtocolManager.addLog(" PrivateKeyHash: ${privateKeyHash.take(20)}...")
// Создаем и отправляем пакет поиска // Создаем и отправляем пакет поиска
val packetSearch = PacketSearch().apply { val packetSearch = PacketSearch().apply {
@@ -125,6 +132,7 @@ class SearchUsersViewModel : ViewModel() {
* Открыть панель поиска * Открыть панель поиска
*/ */
fun expandSearch() { fun expandSearch() {
ProtocolManager.addLog("🔎 Search panel opened")
_isSearchExpanded.value = true _isSearchExpanded.value = true
} }
@@ -132,6 +140,7 @@ class SearchUsersViewModel : ViewModel() {
* Закрыть панель поиска и очистить результаты * Закрыть панель поиска и очистить результаты
*/ */
fun collapseSearch() { fun collapseSearch() {
ProtocolManager.addLog("🔎 Search panel closed")
_isSearchExpanded.value = false _isSearchExpanded.value = false
_searchQuery.value = "" _searchQuery.value = ""
_searchResults.value = emptyList() _searchResults.value = emptyList()