From 6949be6fd85e12335e02b45af3bebbfc279ceec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bi=C3=B6rn?= Date: Wed, 11 Mar 2026 00:40:04 +0100 Subject: [PATCH] leave and delete (#4262) * deleting groups/channels is available after leaving only * update CHANGELOG * Update src/main/java/org/thoughtcrime/securesms/ConversationActivity.java Co-authored-by: adb * mailing lists are not encrypted --------- Co-authored-by: adb --- CHANGELOG.md | 1 + src/main/java/com/b44t/messenger/DcChat.java | 12 +++++++++++ .../BaseConversationListFragment.java | 14 ++++++++++++- .../securesms/ConversationActivity.java | 21 +++++++++++-------- src/main/res/menu/conversation.xml | 6 +++--- src/main/res/values/strings.xml | 1 + 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 523440fd8..784c5bbb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Unified date display in call bubbles * Explain at "Settings / Chats / Outgoing Media Quality" how to send original quality * Add a basic sticker picker +* Leave groups and channels before deletion * Fix: keep original sent timestamp for resent messages * Fix: make clicking on broadcast member-added messages work always * Fix: remove notification when a message is deleted by sender diff --git a/src/main/java/com/b44t/messenger/DcChat.java b/src/main/java/com/b44t/messenger/DcChat.java index 90497a797..7fa460f54 100644 --- a/src/main/java/com/b44t/messenger/DcChat.java +++ b/src/main/java/com/b44t/messenger/DcChat.java @@ -1,5 +1,7 @@ package com.b44t.messenger; +import org.thoughtcrime.securesms.util.Util; + public class DcChat { public static final int DC_CHAT_TYPE_UNDEFINED = 0; @@ -56,6 +58,16 @@ public class DcChat { return type != DC_CHAT_TYPE_SINGLE; } + public boolean shallLeaveBeforeDelete(DcContext dcContext) { + if (isInBroadcast()) { + final int[] members = dcContext.getChatContacts(getId()); + return Util.contains(members, DcContact.DC_CONTACT_ID_SELF); + } else if (isMultiUser() && isEncrypted() && canSend() && !isOutBroadcast()) { + return true; + } + return false; + } + public boolean isMailingList() { return getType() == DC_CHAT_TYPE_MAILINGLIST; } diff --git a/src/main/java/org/thoughtcrime/securesms/BaseConversationListFragment.java b/src/main/java/org/thoughtcrime/securesms/BaseConversationListFragment.java index 9d74fc122..9c4baa6d3 100644 --- a/src/main/java/org/thoughtcrime/securesms/BaseConversationListFragment.java +++ b/src/main/java/org/thoughtcrime/securesms/BaseConversationListFragment.java @@ -29,6 +29,7 @@ import androidx.core.graphics.drawable.IconCompat; import androidx.fragment.app.Fragment; import com.b44t.messenger.DcChat; +import com.b44t.messenger.DcContact; import com.b44t.messenger.DcContext; import com.google.android.material.snackbar.Snackbar; @@ -267,11 +268,19 @@ public abstract class BaseConversationListFragment extends Fragment implements A alertText = activity.getResources().getQuantityString(R.plurals.ask_delete_chat, chatsCount, chatsCount); } + String alertButton = getString(R.string.delete_for_me); + for (long chatId : selectedChats) { + if (dcContext.getChat((int) chatId).shallLeaveBeforeDelete(dcContext)) { + alertButton = getString(R.string.menu_leave_and_delete); + break; + } + } + AlertDialog.Builder alert = new AlertDialog.Builder(activity); alert.setMessage(alertText); alert.setCancelable(true); - alert.setPositiveButton(R.string.delete, (dialog, which) -> { + alert.setPositiveButton(alertButton, (dialog, which) -> { if (!selectedChats.isEmpty()) { new AsyncTask() { @@ -290,6 +299,9 @@ public abstract class BaseConversationListFragment extends Fragment implements A int accountId = dcContext.getAccountId(); for (long chatId : selectedChats) { DcHelper.getNotificationCenter(requireContext()).removeNotifications(accountId, (int) chatId); + if (dcContext.getChat((int) chatId).shallLeaveBeforeDelete(dcContext)) { + dcContext.removeContactFromChat((int) chatId, DcContact.DC_CONTACT_ID_SELF); + } dcContext.deleteChat((int) chatId); DirectShareUtil.clearShortcut(requireContext(), (int) chatId); } diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java index 5bdbf98bd..efc3493cf 100644 --- a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java @@ -528,15 +528,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity menu.findItem(R.id.menu_ephemeral_messages).setVisible(false); } - if (isMultiUser()) { - if (dcChat.isInBroadcast() && !dcChat.isContactRequest()) { - menu.findItem(R.id.menu_leave).setTitle(R.string.menu_leave_channel).setVisible(true); - } else if (dcChat.isEncrypted() - && dcChat.canSend() - && !dcChat.isOutBroadcast() - && !dcChat.isMailingList()) { - menu.findItem(R.id.menu_leave).setVisible(true); + if (dcChat.shallLeaveBeforeDelete(DcHelper.getContext(context))) { + if (dcChat.isInBroadcast()) { + menu.findItem(R.id.menu_leave).setTitle(R.string.menu_leave_channel); } + menu.findItem(R.id.menu_leave).setVisible(true); + menu.findItem(R.id.menu_delete_chat).setVisible(false); } if (isArchived()) { @@ -729,9 +726,15 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity DcHelper.getContext(context).removeContactFromChat(chatId, DcContact.DC_CONTACT_ID_SELF); Toast.makeText(this, getString(R.string.done), Toast.LENGTH_SHORT).show(); }) - .setNegativeButton(R.string.cancel, null) + .setNegativeButton(R.string.menu_leave_and_delete, (d, which) -> { + DcHelper.getContext(context).removeContactFromChat(chatId, DcContact.DC_CONTACT_ID_SELF); + DcHelper.getContext(context).deleteChat(chatId); + Toast.makeText(this, getString(R.string.done), Toast.LENGTH_SHORT).show(); + }) + .setNeutralButton(R.string.cancel, null) .show(); Util.redPositiveButton(dialog); + Util.redButton(dialog, AlertDialog.BUTTON_NEGATIVE); } private void handleArchiveChat() { diff --git a/src/main/res/menu/conversation.xml b/src/main/res/menu/conversation.xml index 879e60b2e..daf20aafb 100644 --- a/src/main/res/menu/conversation.xml +++ b/src/main/res/menu/conversation.xml @@ -67,13 +67,13 @@ + + - - diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d9bb65e31..a102c8c73 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -281,6 +281,7 @@ Add Attachment Leave Group Leave Channel + Leave & Delete for Me Delete Chat Clear Chat