android: wire chats popup actions and remove duplicate menu
Some checks failed
Android CI / android (push) Failing after 4m43s
Android Release / release (push) Has started running
CI / test (push) Has been cancelled

This commit is contained in:
Codex
2026-03-09 21:46:17 +03:00
parent 4502fdf9e9
commit cbd326ee12
2 changed files with 69 additions and 16 deletions

View File

@@ -556,3 +556,14 @@
- search field + section chips (`Chats/Channels/Apps/Posts`),
- horizontal recent avatars strip,
- list filtered by active query.
### Step 89 - Chats actions wiring + duplicate menu fix
- Removed duplicated overflow action in chats top bar (single `⋮` remains in default mode).
- Wired selection actions to behavior:
- delete selected -> leave selected chats,
- archive selected -> switch to archived section,
- non-implemented bulk actions now show explicit user feedback.
- Wired default menu actions:
- create group/channel -> open management panel,
- saved -> open saved chat if present,
- unsupported items show clear feedback instead of silent no-op.

View File

@@ -1,5 +1,6 @@
package ru.daemonlord.messenger.ui.chats
import android.widget.Toast
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.background
@@ -50,6 +51,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -149,6 +151,7 @@ fun ChatListScreen(
onBanMember: (Long, Long) -> Unit,
onUnbanMember: (Long, Long) -> Unit,
) {
val context = LocalContext.current
var managementExpanded by remember { mutableStateOf(false) }
var showDefaultMenu by remember { mutableStateOf(false) }
var showSelectionMenu by remember { mutableStateOf(false) }
@@ -237,19 +240,27 @@ fun ChatListScreen(
},
actions = {
if (selectedChatIds.isNotEmpty()) {
IconButton(onClick = {}) {
IconButton(onClick = {
Toast.makeText(context, "Bulk mute will be added next.", Toast.LENGTH_SHORT).show()
}) {
Icon(
imageVector = Icons.Filled.NotificationsOff,
contentDescription = "Mute selected",
)
}
IconButton(onClick = {}) {
IconButton(onClick = {
selectedChatIds = emptySet()
onTabSelected(ChatTab.ARCHIVED)
}) {
Icon(
imageVector = Icons.Filled.FolderOpen,
contentDescription = "Archive selected",
)
}
IconButton(onClick = {}) {
IconButton(onClick = {
selectedChatIds.forEach { chatId -> onLeaveChat(chatId) }
selectedChatIds = emptySet()
}) {
Icon(
imageVector = Icons.Filled.Delete,
contentDescription = "Delete selected",
@@ -269,22 +280,34 @@ fun ChatListScreen(
DropdownMenuItem(
text = { Text("Unpin") },
leadingIcon = { Icon(Icons.Filled.PushPin, contentDescription = null) },
onClick = { showSelectionMenu = false },
onClick = {
showSelectionMenu = false
Toast.makeText(context, "Bulk pin/unpin will be added next.", Toast.LENGTH_SHORT).show()
},
)
DropdownMenuItem(
text = { Text("Add to folder") },
leadingIcon = { Icon(Icons.Filled.FolderOpen, contentDescription = null) },
onClick = { showSelectionMenu = false },
onClick = {
showSelectionMenu = false
Toast.makeText(context, "Folders UI will be added next.", Toast.LENGTH_SHORT).show()
},
)
DropdownMenuItem(
text = { Text("Mark unread") },
leadingIcon = { Icon(Icons.Filled.DoneAll, contentDescription = null) },
onClick = { showSelectionMenu = false },
onClick = {
showSelectionMenu = false
Toast.makeText(context, "Mark unread action will be added next.", Toast.LENGTH_SHORT).show()
},
)
DropdownMenuItem(
text = { Text("Clear cache") },
leadingIcon = { Icon(Icons.Filled.Delete, contentDescription = null) },
onClick = { showSelectionMenu = false },
onClick = {
showSelectionMenu = false
Toast.makeText(context, "Media cache clear will be added next.", Toast.LENGTH_SHORT).show()
},
)
}
}
@@ -307,12 +330,6 @@ fun ChatListScreen(
contentDescription = "Show search",
)
}
IconButton(onClick = { managementExpanded = !managementExpanded }) {
Icon(
imageVector = if (managementExpanded) Icons.Filled.Close else Icons.Filled.MoreVert,
contentDescription = if (managementExpanded) "Close menu" else "Open menu",
)
}
Box {
IconButton(onClick = { showDefaultMenu = true }) {
Icon(
@@ -327,7 +344,10 @@ fun ChatListScreen(
DropdownMenuItem(
text = { Text("Day mode") },
leadingIcon = { Icon(Icons.Filled.LightMode, contentDescription = null) },
onClick = { showDefaultMenu = false },
onClick = {
showDefaultMenu = false
Toast.makeText(context, "Theme switch in Settings.", Toast.LENGTH_SHORT).show()
},
)
DropdownMenuItem(
text = { Text("Create group") },
@@ -337,15 +357,37 @@ fun ChatListScreen(
managementExpanded = true
},
)
DropdownMenuItem(
text = { Text("Create channel") },
leadingIcon = { Icon(Icons.Filled.FolderOpen, contentDescription = null) },
onClick = {
showDefaultMenu = false
managementExpanded = true
},
)
DropdownMenuItem(
text = { Text("Saved") },
leadingIcon = { Icon(Icons.Filled.Inventory2, contentDescription = null) },
onClick = { showDefaultMenu = false },
onClick = {
showDefaultMenu = false
val saved = state.chats.firstOrNull {
val title = it.displayTitle.lowercase()
title.contains("saved") || title.contains("избран")
}
if (saved != null) {
onOpenChat(saved.id)
} else {
Toast.makeText(context, "Saved chat not found.", Toast.LENGTH_SHORT).show()
}
},
)
DropdownMenuItem(
text = { Text("Proxy") },
leadingIcon = { Icon(Icons.Filled.NotificationsOff, contentDescription = null) },
onClick = { showDefaultMenu = false },
onClick = {
showDefaultMenu = false
Toast.makeText(context, "Proxy settings will be added next.", Toast.LENGTH_SHORT).show()
},
)
}
}