feat: Enhance dialog message deletion logic; ensure correct dialog key calculation and improve UI overlay behavior

This commit is contained in:
k1ngsterr1
2026-01-17 00:39:54 +05:00
parent 1ce7e6498c
commit f71209f3c6
2 changed files with 83 additions and 76 deletions

View File

@@ -1267,10 +1267,17 @@ fun ChatDetailScreen(
showDeleteConfirm = false showDeleteConfirm = false
scope.launch { scope.launch {
try { try {
// Вычисляем правильный dialog_key (отсортированная комбинация ключей)
val dialogKey = if (currentUserPublicKey < user.publicKey) {
"$currentUserPublicKey:${user.publicKey}"
} else {
"${user.publicKey}:$currentUserPublicKey"
}
// Удаляем все сообщения из диалога по dialog_key // Удаляем все сообщения из диалога по dialog_key
database.messageDao().deleteDialog( database.messageDao().deleteDialog(
account = currentUserPublicKey, account = currentUserPublicKey,
dialogKey = user.publicKey dialogKey = dialogKey
) )
// Также пробуем удалить по from/to ключам (на всякий случай) // Также пробуем удалить по from/to ключам (на всякий случай)
database.messageDao().deleteMessagesBetweenUsers( database.messageDao().deleteMessagesBetweenUsers(
@@ -1404,6 +1411,8 @@ fun ChatDetailScreen(
onDismissRequest = { showMenu = false }, onDismissRequest = { showMenu = false },
containerColor = if (isDarkTheme) Color(0xFF1C1C1E) else Color.White, containerColor = if (isDarkTheme) Color(0xFF1C1C1E) else Color.White,
shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp), shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp),
scrimColor = Color.Black.copy(alpha = 0.6f),
windowInsets = WindowInsets(0, 0, 0, 0), // Перекрываем весь экран включая status bar
dragHandle = { dragHandle = {
Box( Box(
modifier = Modifier modifier = Modifier

View File

@@ -203,6 +203,9 @@ fun ChatsListScreen(
// Status dialog state // Status dialog state
var showStatusDialog by remember { mutableStateOf(false) } var showStatusDialog by remember { mutableStateOf(false) }
// 📬 Requests screen state
var showRequestsScreen by remember { mutableStateOf(false) }
// 🔥 Используем rememberSaveable чтобы сохранить состояние при навигации // 🔥 Используем rememberSaveable чтобы сохранить состояние при навигации
// Header сразу visible = true, без анимации при возврате из чата // Header сразу visible = true, без анимации при возврате из чата
var visible by rememberSaveable { mutableStateOf(true) } var visible by rememberSaveable { mutableStateOf(true) }
@@ -579,62 +582,88 @@ fun ChatsListScreen(
animationSpec = tween(200) animationSpec = tween(200)
) )
) { ) {
key(isDarkTheme) { key(isDarkTheme, showRequestsScreen) {
TopAppBar( TopAppBar(
navigationIcon = { navigationIcon = {
IconButton( if (showRequestsScreen) {
onClick = { // Back button for Requests
scope.launch { drawerState.open() } IconButton(onClick = { showRequestsScreen = false }) {
} Icon(
) { Icons.Default.ArrowBack,
Icon( contentDescription = "Back",
Icons.Default.Menu, tint = PrimaryBlue
contentDescription = "Menu", )
tint = textColor }
) } else {
// Menu button for main screen
IconButton(
onClick = {
scope.launch { drawerState.open() }
}
) {
Icon(
Icons.Default.Menu,
contentDescription = "Menu",
tint = textColor
)
}
} }
}, },
title = { title = {
Row( if (showRequestsScreen) {
verticalAlignment = Alignment.CenterVertically // Requests title
) {
Text( Text(
"Rosetta", "Requests",
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
fontSize = 20.sp, fontSize = 20.sp,
color = textColor color = textColor
) )
Spacer(modifier = Modifier.width(8.dp)) } else {
Box( // Rosetta title with status
modifier = Modifier Row(
.size(10.dp) verticalAlignment = Alignment.CenterVertically
.clip(CircleShape) ) {
.background( Text(
when (protocolState) { "Rosetta",
ProtocolState.AUTHENTICATED -> Color(0xFF4CAF50) fontWeight = FontWeight.Bold,
ProtocolState.CONNECTING, ProtocolState.CONNECTED, ProtocolState.HANDSHAKING -> Color(0xFFFFC107) fontSize = 20.sp,
ProtocolState.DISCONNECTED -> Color(0xFFF44336) color = textColor
} )
) Spacer(modifier = Modifier.width(8.dp))
.clickable { showStatusDialog = true } Box(
) modifier = Modifier
.size(10.dp)
.clip(CircleShape)
.background(
when (protocolState) {
ProtocolState.AUTHENTICATED -> Color(0xFF4CAF50)
ProtocolState.CONNECTING, ProtocolState.CONNECTED, ProtocolState.HANDSHAKING -> Color(0xFFFFC107)
ProtocolState.DISCONNECTED -> Color(0xFFF44336)
}
)
.clickable { showStatusDialog = true }
)
}
} }
}, },
actions = { actions = {
IconButton( // Search only on main screen
onClick = { if (!showRequestsScreen) {
if (protocolState == ProtocolState.AUTHENTICATED) { IconButton(
onSearchClick() onClick = {
} if (protocolState == ProtocolState.AUTHENTICATED) {
}, onSearchClick()
enabled = protocolState == ProtocolState.AUTHENTICATED }
) { },
Icon( enabled = protocolState == ProtocolState.AUTHENTICATED
Icons.Default.Search, ) {
contentDescription = "Search", Icon(
tint = if (protocolState == ProtocolState.AUTHENTICATED) Icons.Default.Search,
textColor else textColor.copy(alpha = 0.5f) contentDescription = "Search",
) tint = if (protocolState == ProtocolState.AUTHENTICATED)
textColor else textColor.copy(alpha = 0.5f)
)
}
} }
}, },
colors = TopAppBarDefaults.topAppBarColors( colors = TopAppBarDefaults.topAppBarColors(
@@ -669,9 +698,6 @@ fun ChatsListScreen(
}, },
containerColor = backgroundColor containerColor = backgroundColor
) { paddingValues -> ) { paddingValues ->
// 📬 State for showing requests screen
var showRequestsScreen by remember { mutableStateOf(false) }
// Main content // Main content
Box(modifier = Modifier.fillMaxSize().padding(paddingValues)) { Box(modifier = Modifier.fillMaxSize().padding(paddingValues)) {
// 📬 Requests count from ViewModel // 📬 Requests count from ViewModel
@@ -1537,9 +1563,8 @@ fun RequestsSection(
} }
/** /**
* 📬 Экран со списком Requests * 📬 Экран со списком Requests (без хедера - хедер в основном TopAppBar)
*/ */
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun RequestsScreen( fun RequestsScreen(
requests: List<DialogUiModel>, requests: List<DialogUiModel>,
@@ -1548,7 +1573,6 @@ fun RequestsScreen(
onRequestClick: (DialogUiModel) -> Unit onRequestClick: (DialogUiModel) -> Unit
) { ) {
val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)
val textColor = if (isDarkTheme) Color.White else Color.Black
val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8) val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8)
Column( Column(
@@ -1556,32 +1580,6 @@ fun RequestsScreen(
.fillMaxSize() .fillMaxSize()
.background(backgroundColor) .background(backgroundColor)
) { ) {
// Header
TopAppBar(
navigationIcon = {
IconButton(onClick = onBack) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Back",
tint = PrimaryBlue
)
}
},
title = {
Text(
text = "Requests",
fontWeight = FontWeight.Bold,
fontSize = 20.sp,
color = textColor
)
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = backgroundColor
)
)
Divider(color = dividerColor, thickness = 0.5.dp)
if (requests.isEmpty()) { if (requests.isEmpty()) {
// Empty state // Empty state
Box( Box(