android: fix inline search close and polish message action sheet
Some checks failed
Android CI / android (push) Has started running
Android Release / release (push) Has been cancelled
CI / test (push) Has been cancelled

This commit is contained in:
Codex
2026-03-10 01:38:46 +03:00
parent 90c25c5eb8
commit 5a0bb9ff08
2 changed files with 124 additions and 32 deletions

View File

@@ -884,3 +884,10 @@
- `Files / Links / Voice` use denser card rows with icon+meta layout.
- `Voice` rows now show a dedicated play affordance.
- Refined menu order in chat `3-dot` popup and kept actions consistent with current no-calls scope.
### Step 124 - Inline search close fix + message menu visual pass
- Fixed inline chat search UX:
- added explicit close button in the search row,
- closing search now also clears active query/filter without re-entering chat.
- Added automatic inline-search collapse when entering multi-select mode.
- Reworked message tap action sheet to Telegram-like list actions with icons and clearer destructive `Delete` row styling.

View File

@@ -110,6 +110,8 @@ import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.Image
import androidx.compose.material.icons.filled.Link
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.automirrored.filled.Reply
import androidx.compose.material.icons.automirrored.filled.InsertDriveFile
import coil.compose.AsyncImage
import kotlinx.coroutines.flow.collectLatest
@@ -302,6 +304,12 @@ fun ChatScreen(
listState.animateScrollToItem(index = index)
}
}
LaunchedEffect(state.actionState.mode) {
if (state.actionState.mode == MessageSelectionMode.MULTI && showInlineSearch) {
showInlineSearch = false
onInlineSearchChanged("")
}
}
LaunchedEffect(listState, state.messages) {
snapshotFlow {
listState.layoutInfo.visibleItemsInfo
@@ -493,6 +501,12 @@ fun ChatScreen(
onClick = { onJumpInlineSearch(true) },
enabled = state.inlineSearchMatches.isNotEmpty(),
) { Icon(imageVector = Icons.Filled.ArrowDownward, contentDescription = "Next match") }
IconButton(
onClick = {
showInlineSearch = false
onInlineSearchChanged("")
},
) { Icon(imageVector = Icons.Filled.Close, contentDescription = "Close search") }
}
}
if (showInlineSearch && state.inlineSearchMatches.isNotEmpty()) {
@@ -611,38 +625,109 @@ fun ChatScreen(
}
}
}
Button(
onClick = {
Surface(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.clickable {
onReplySelected(selected)
actionMenuMessage = null
},
modifier = Modifier.fillMaxWidth(),
) { Text("Reply") }
Button(
onClick = {
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
Icon(imageVector = Icons.AutoMirrored.Filled.Reply, contentDescription = null)
Text("Reply", style = MaterialTheme.typography.bodyLarge)
}
}
Surface(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.clickable(enabled = state.selectedCanEdit) {
onEditSelected(selected)
actionMenuMessage = null
},
enabled = state.selectedCanEdit,
modifier = Modifier.fillMaxWidth(),
) { Text("Edit") }
Button(
onClick = {
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
Icon(imageVector = Icons.Filled.Edit, contentDescription = null)
Text(
"Edit",
style = MaterialTheme.typography.bodyLarge,
color = if (state.selectedCanEdit) {
MaterialTheme.colorScheme.onSurface
} else {
MaterialTheme.colorScheme.onSurfaceVariant
},
)
}
}
Surface(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.clickable {
onSelectMessage(selected)
onForwardSelected()
actionMenuMessage = null
},
modifier = Modifier.fillMaxWidth(),
) { Text("Forward") }
Button(
onClick = {
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
Icon(imageVector = Icons.AutoMirrored.Filled.Forward, contentDescription = null)
Text("Forward", style = MaterialTheme.typography.bodyLarge)
}
}
Surface(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.clickable {
onSelectMessage(selected)
pendingDeleteForAll = false
showDeleteDialog = true
actionMenuMessage = null
},
modifier = Modifier.fillMaxWidth(),
) { Text("Delete") }
color = MaterialTheme.colorScheme.errorContainer.copy(alpha = 0.45f),
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
Icon(
imageVector = Icons.Filled.DeleteOutline,
contentDescription = null,
tint = MaterialTheme.colorScheme.error,
)
Text(
"Delete",
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.error,
)
}
}
TextButton(
onClick = {
actionMenuMessage = null