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. - `Files / Links / Voice` use denser card rows with icon+meta layout.
- `Voice` rows now show a dedicated play affordance. - `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. - 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.Image
import androidx.compose.material.icons.filled.Link import androidx.compose.material.icons.filled.Link
import androidx.compose.material.icons.filled.PlayArrow 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 androidx.compose.material.icons.automirrored.filled.InsertDriveFile
import coil.compose.AsyncImage import coil.compose.AsyncImage
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
@@ -302,6 +304,12 @@ fun ChatScreen(
listState.animateScrollToItem(index = index) listState.animateScrollToItem(index = index)
} }
} }
LaunchedEffect(state.actionState.mode) {
if (state.actionState.mode == MessageSelectionMode.MULTI && showInlineSearch) {
showInlineSearch = false
onInlineSearchChanged("")
}
}
LaunchedEffect(listState, state.messages) { LaunchedEffect(listState, state.messages) {
snapshotFlow { snapshotFlow {
listState.layoutInfo.visibleItemsInfo listState.layoutInfo.visibleItemsInfo
@@ -493,6 +501,12 @@ fun ChatScreen(
onClick = { onJumpInlineSearch(true) }, onClick = { onJumpInlineSearch(true) },
enabled = state.inlineSearchMatches.isNotEmpty(), enabled = state.inlineSearchMatches.isNotEmpty(),
) { Icon(imageVector = Icons.Filled.ArrowDownward, contentDescription = "Next match") } ) { 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()) { if (showInlineSearch && state.inlineSearchMatches.isNotEmpty()) {
@@ -611,38 +625,109 @@ fun ChatScreen(
} }
} }
} }
Button( Surface(
onClick = { modifier = Modifier
onReplySelected(selected) .fillMaxWidth()
actionMenuMessage = null .clip(RoundedCornerShape(12.dp))
}, .clickable {
modifier = Modifier.fillMaxWidth(), onReplySelected(selected)
) { Text("Reply") } actionMenuMessage = null
Button( },
onClick = { color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
onEditSelected(selected) ) {
actionMenuMessage = null Row(
}, modifier = Modifier
enabled = state.selectedCanEdit, .fillMaxWidth()
modifier = Modifier.fillMaxWidth(), .padding(horizontal = 12.dp, vertical = 10.dp),
) { Text("Edit") } verticalAlignment = Alignment.CenterVertically,
Button( horizontalArrangement = Arrangement.spacedBy(12.dp),
onClick = { ) {
onSelectMessage(selected) Icon(imageVector = Icons.AutoMirrored.Filled.Reply, contentDescription = null)
onForwardSelected() Text("Reply", style = MaterialTheme.typography.bodyLarge)
actionMenuMessage = null }
}, }
modifier = Modifier.fillMaxWidth(), Surface(
) { Text("Forward") } modifier = Modifier
Button( .fillMaxWidth()
onClick = { .clip(RoundedCornerShape(12.dp))
onSelectMessage(selected) .clickable(enabled = state.selectedCanEdit) {
pendingDeleteForAll = false onEditSelected(selected)
showDeleteDialog = true actionMenuMessage = null
actionMenuMessage = null },
}, color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
modifier = Modifier.fillMaxWidth(), ) {
) { Text("Delete") } 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
},
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
},
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( TextButton(
onClick = { onClick = {
actionMenuMessage = null actionMenuMessage = null