From 380667c6cd123d2e782d17ab1b4b2c46021ca1a7 Mon Sep 17 00:00:00 2001 From: Jubb Date: Fri, 22 Jan 2021 15:10:28 +1100 Subject: [PATCH] feat: add banning users as a mod in open group --- res/menu/conversation_context.xml | 6 ++ res/values/strings.xml | 5 ++ .../conversation/ConversationFragment.java | 66 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/res/menu/conversation_context.xml b/res/menu/conversation_context.xml index 4224c2bc5c..1204fedb31 100644 --- a/res/menu/conversation_context.xml +++ b/res/menu/conversation_context.xml @@ -11,6 +11,12 @@ android:icon="?menu_trash_icon" app:showAsAction="always" /> + + Yes No Delete + Ban Please wait... Save Note to Self @@ -206,6 +207,7 @@ This will permanently delete the selected message. This will permanently delete all %1$d selected messages. + Ban this user? Save to storage? Saving this media to storage will allow any other apps on your device to access it.\n\nContinue? @@ -230,6 +232,8 @@ SMS Deleting Deleting messages... + Banning + Banning user… Original message not found Original message no longer available @@ -1340,6 +1344,7 @@ Message details Copy text Delete message + Ban user Forward message Resend message Reply to message diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java index e8a766f0e4..31a9dea171 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -111,12 +111,16 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.TreeSet; +import kotlin.Unit; import network.loki.messenger.R; +import nl.komponents.kovenant.Kovenant; @SuppressLint("StaticFieldLeak") public class ConversationFragment extends Fragment @@ -406,18 +410,24 @@ public class ConversationFragment extends Fragment boolean isPublicChat = (publicChat != null); int selectedMessageCount = messageRecords.size(); boolean areAllSentByUser = true; + Set uniqueUserSet = new HashSet<>(); for (MessageRecord message : messageRecords) { if (!message.isOutgoing()) { areAllSentByUser = false; } + uniqueUserSet.add(message.getRecipient().getAddress().toPhoneString()); } menu.findItem(R.id.menu_context_copy_public_key).setVisible(selectedMessageCount == 1 && !areAllSentByUser); menu.findItem(R.id.menu_context_reply).setVisible(selectedMessageCount == 1); String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext()); boolean userCanModerate = isPublicChat && PublicChatAPI.Companion.isUserModerator(userHexEncodedPublicKey, publicChat.getChannel(), publicChat.getServer()); boolean isDeleteOptionVisible = !isPublicChat || (areAllSentByUser || userCanModerate); + // allow banning if moderating a public chat and only one user's messages are selected + boolean isBanOptionVisible = isPublicChat && userCanModerate && !areAllSentByUser && uniqueUserSet.size() == 1; menu.findItem(R.id.menu_context_delete_message).setVisible(isDeleteOptionVisible); + menu.findItem(R.id.menu_context_ban_user).setVisible(isBanOptionVisible); } else { menu.findItem(R.id.menu_context_copy_public_key).setVisible(false); menu.findItem(R.id.menu_context_delete_message).setVisible(true); + menu.findItem(R.id.menu_context_ban_user).setVisible(false); } } @@ -576,6 +586,59 @@ public class ConversationFragment extends Fragment builder.show(); } + private void handleBanUser(Set messageRecords) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + String userPublicKey = null; + for (MessageRecord record: messageRecords) { + String currentPublicKey = record.getRecipient().getAddress().toPhoneString(); + if (userPublicKey == null) { + userPublicKey = currentPublicKey; + } + } + final String finalPublicKey = userPublicKey; + + builder.setIconAttribute(R.attr.dialog_alert_icon); + builder.setTitle(R.string.ConversationFragment_ban_selected_user); + builder.setCancelable(true); + + PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); + + builder.setPositiveButton(R.string.ban, (dialog, which) -> { + ConversationAdapter chatAdapter = getListAdapter(); + chatAdapter.clearSelection(); + chatAdapter.notifyDataSetChanged(); + new ProgressDialogAsyncTask(getActivity(), + R.string.ConversationFragment_banning, + R.string.ConversationFragment_banning_user) { + @Override + protected Void doInBackground(String... userPublicKeyParam) { + String userPublicKey = userPublicKeyParam[0]; + if (publicChat != null) { + PublicChatAPI publicChatAPI = ApplicationContext.getInstance(getContext()).getPublicChatAPI(); + if (publicChat != null && publicChatAPI != null) { + publicChatAPI + .ban(userPublicKey, publicChat.getServer()) + .success(l -> { + Log.d("Loki", "User banned"); + return Unit.INSTANCE; + }).fail(e -> { + Log.d("Loki", "Couldn't ban user due to error: " + e.toString() + "."); + return null; + }); + } + } else { + Log.d("Loki", "Tried to ban user from a non-public chat"); + } + return null; + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, finalPublicKey); + }); + + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + } + private void handleDisplayDetails(MessageRecord message) { Intent intent = new Intent(getActivity(), MessageDetailsActivity.class); intent.putExtra(MessageDetailsActivity.MESSAGE_ID_EXTRA, message.getId()); @@ -1133,6 +1196,9 @@ public class ConversationFragment extends Fragment handleDeleteMessages(getListAdapter().getSelectedItems()); actionMode.finish(); return true; + case R.id.menu_context_ban_user: + handleBanUser(getListAdapter().getSelectedItems()); + return true; case R.id.menu_context_details: handleDisplayDetails(getSelectedMessageRecord()); actionMode.finish();