diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt index aee76df586324230b872638df8d40eb725aba234..a854d7ea11cd8e106e12f9b1b281b6bceb490c30 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt @@ -45,6 +45,7 @@ fun ContactDropDown( close: () -> Unit, onMakeIntroduction: () -> Unit, onDeleteAllMessages: () -> Unit, + onDeleteContact: () -> Unit, ) { val coreFeatureFlags = getCoreFeatureFlags() val desktopFeatureFlags = getDesktopFeatureFlags() @@ -121,7 +122,7 @@ fun ContactDropDown( DropdownMenuItem(onClick = { false }, enabled = false) { Text(i18n("contacts.dropdown.contact.change"), fontSize = 14.sp) } - DropdownMenuItem(onClick = { false }) { + DropdownMenuItem(onClick = { close(); onDeleteContact() }) { Text(i18n("contacts.dropdown.contact.delete"), fontSize = 14.sp) } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt index db100352581bdcee8dc3efb2c031e96d4083d318..f43dc960efb702e42e67d76901681f71d6e37ac9 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationDialogs.kt @@ -156,3 +156,37 @@ fun DeleteAllMessagesFailedDialog( } ) } + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun DeleteContactConfirmationDialog( + isVisible: Boolean, + close: () -> Unit, + onDelete: () -> Unit = {}, + onCancel: () -> Unit = {}, +) { + if (!isVisible) return + + AlertDialog( + onDismissRequest = close, + title = { + Text( + text = i18n("conversation.delete.contact.dialog.title"), + modifier = Modifier.width(IntrinsicSize.Max) + ) + }, + text = { + Text(i18n("conversation.delete.contact.dialog.message")) + }, + dismissButton = { + TextButton(onClick = { close(); onDelete() }) { + Text(i18n("delete")) + } + }, + confirmButton = { + TextButton(onClick = { close(); onCancel() }) { + Text(i18n("cancel")) + } + } + ) +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt index 22b29ffbe4500c551ef84b4cba81acd197010e3e..9100b8bdbec34196b7825f248e56c7aa6eb76029 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt @@ -56,6 +56,7 @@ fun ConversationHeader( contactItem: ContactItem, onMakeIntroduction: () -> Unit, onDeleteAllMessages: () -> Unit, + onDeleteContact: () -> Unit, ) { val (isExpanded, setExpanded) = remember { mutableStateOf(false) } val onlineColor = @@ -95,7 +96,13 @@ fun ConversationHeader( modifier = Modifier.align(Alignment.CenterVertically).padding(end = 16.dp) ) { Icon(Icons.Filled.MoreVert, i18n("access.contact.menu"), modifier = Modifier.size(24.dp)) - ContactDropDown(isExpanded, { setExpanded(false) }, onMakeIntroduction, onDeleteAllMessages) + ContactDropDown( + isExpanded, + { setExpanded(false) }, + onMakeIntroduction, + onDeleteAllMessages, + onDeleteContact + ) } } HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter)) diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt index e028b054bd1369bbab21f889edd625a0728dbfe5..5389849dcf37282b800d8c14190bdf217d3a640a 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt @@ -71,6 +71,7 @@ fun ConversationScreen( val (infoDrawer, setInfoDrawer) = remember { mutableStateOf(false) } val (contactDrawerState, setDrawerState) = remember { mutableStateOf(ContactInfoDrawerState.MakeIntro) } val (deleteAllMessagesDialogVisible, setDeleteAllMessagesDialog) = remember { mutableStateOf(false) } + val (deleteContactDialogVisible, setDeleteContactDialog) = remember { mutableStateOf(false) } BoxWithConstraints(Modifier.fillMaxSize()) { val animatedInfoDrawerOffsetX by animateDpAsState(if (infoDrawer) (-275).dp else 0.dp) @@ -83,6 +84,9 @@ fun ConversationScreen( }, onDeleteAllMessages = { setDeleteAllMessagesDialog(true) + }, + onDeleteContact = { + setDeleteContactDialog(true) } ) }, @@ -158,5 +162,11 @@ fun ConversationScreen( deletionResult = viewModel.deletionResult.value, close = viewModel::confirmDeletionResult ) + + DeleteContactConfirmationDialog( + isVisible = deleteContactDialogVisible, + close = { setDeleteContactDialog(false) }, + onDelete = viewModel::deleteContact + ) } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt index a26baff16b7614cfd1a513bbd88bc5069e49bc58..fce0ab729ba5ae566c99487ac376110fc19e6f2a 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt @@ -430,4 +430,8 @@ constructor( fun confirmDeletionResult() { _deletionResult.value = null } + + fun deleteContact() = runOnDbThread { + contactManager.removeContact(_contactId.value!!) + } } diff --git a/src/main/resources/strings/BriarDesktop.properties b/src/main/resources/strings/BriarDesktop.properties index 72c22adff3044dc8043eaebe9ba3317315e4d06c..7b65487cb91c483f896ed058c121e14e1322c33b 100644 --- a/src/main/resources/strings/BriarDesktop.properties +++ b/src/main/resources/strings/BriarDesktop.properties @@ -45,6 +45,8 @@ conversation.delete.failed.dialog.message.ongoing_invitations=Messages related t conversation.delete.failed.dialog.message.not_all_selected_both=To delete an invitation or introduction, you need to select the request and the response. conversation.delete.failed.dialog.message.not_all_selected_introductions=To delete an introduction, you need to select the request and the response. conversation.delete.failed.dialog.message.not_all_selected_invitations=To delete an invitation, you need to select the request and the response. +conversation.delete.contact.dialog.title=Confirm Contact Deletion +conversation.delete.contact.dialog.message=Are you sure that you want to remove this contact and all messages exchanged with this contact? # Private Groups groups.card.created=Created by {0}