feat: Enhance dialog message deletion logic; ensure correct dialog key calculation and improve UI overlay behavior
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user