android: polish fullscreen chats search interactions
Some checks failed
Android CI / android (push) Has been cancelled
Android Release / release (push) Has been cancelled
CI / test (push) Has been cancelled

This commit is contained in:
Codex
2026-03-09 22:12:51 +03:00
parent 4a31612df0
commit 4f53e3ef99
2 changed files with 41 additions and 5 deletions

View File

@@ -592,3 +592,10 @@
### Step 92 - Search filter leak fix on exit
- Fixed chats search state leak: leaving fullscreen search now resets local/global query.
- Main chats list no longer stays filtered by previous search input after returning from search mode.
### Step 93 - Fullscreen search UX polish
- Added system back-handler for search mode with safe query reset.
- Improved fullscreen search result sections:
- `Показать больше / Свернуть` toggle for global users,
- `Показать больше / Свернуть` toggle for message results.
- Added explicit empty-state text when local/global/message search sections all have no results.

View File

@@ -1,6 +1,7 @@
package ru.daemonlord.messenger.ui.chats
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.background
@@ -45,8 +46,8 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -176,6 +177,12 @@ fun ChatListScreen(
var manageRoleText by remember { mutableStateOf("member") }
val isTabletLayout = LocalConfiguration.current.screenWidthDp >= 840
val listState = rememberLazyListState()
BackHandler(enabled = isSearchMode) {
isSearchMode = false
localSearchQuery = ""
onSearchChanged("")
onGlobalSearchChanged("")
}
LaunchedEffect(Unit) {
onMainBarVisibilityChanged(true)
@@ -712,6 +719,12 @@ private fun ChatSearchFullscreen(
onOpenChat: (Long) -> Unit,
) {
val trimmedQuery = searchQuery.trim()
var showMoreGlobalUsers by remember { mutableStateOf(false) }
var showMoreMessages by remember { mutableStateOf(false) }
LaunchedEffect(trimmedQuery) {
showMoreGlobalUsers = false
showMoreMessages = false
}
val sectionChats = remember(state.chats, searchSection) {
when (searchSection) {
SearchSection.Chats -> state.chats
@@ -864,11 +877,13 @@ private fun ChatSearchFullscreen(
item(key = "global_header") {
SectionHeader(
title = "Глобальный поиск",
action = "Показать больше",
action = if (showMoreGlobalUsers) "Свернуть" else "Показать больше",
onActionClick = { showMoreGlobalUsers = !showMoreGlobalUsers },
)
}
if (state.globalUsers.isNotEmpty()) {
items(state.globalUsers.take(8), key = { "user_${it.id}" }) { user ->
val users = if (showMoreGlobalUsers) state.globalUsers else state.globalUsers.take(5)
items(users, key = { "user_${it.id}" }) { user ->
SearchUserRow(
title = user.name,
subtitle = buildString {
@@ -890,10 +905,12 @@ private fun ChatSearchFullscreen(
item(key = "messages_header") {
SectionHeader(
title = "Сообщения",
action = "Из всех чатов",
action = if (showMoreMessages) "Свернуть" else "Показать больше",
onActionClick = { showMoreMessages = !showMoreMessages },
)
}
items(state.globalMessages.take(12), key = { "msg_${it.id}" }) { message ->
val messages = if (showMoreMessages) state.globalMessages else state.globalMessages.take(8)
items(messages, key = { "msg_${it.id}" }) { message ->
SearchMessageRow(
state = state,
messageText = message.text?.take(70).orEmpty().ifBlank { "[${message.type}]" },
@@ -905,6 +922,16 @@ private fun ChatSearchFullscreen(
chatId = message.chatId,
)
}
if (localQueryResults.isEmpty() && state.globalUsers.isEmpty() && state.globalMessages.isEmpty()) {
item(key = "all_empty") {
Text(
text = "Ничего не найдено",
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = 8.dp, vertical = 12.dp),
)
}
}
}
}
}
@@ -914,6 +941,7 @@ private fun ChatSearchFullscreen(
private fun SectionHeader(
title: String,
action: String,
onActionClick: (() -> Unit)? = null,
) {
Row(
modifier = Modifier
@@ -931,6 +959,7 @@ private fun SectionHeader(
text = action,
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = if (onActionClick != null) Modifier.clickable(onClick = onActionClick) else Modifier,
)
}
}