From 467af609dc56217ad75b3a013a3265ba7a3de188 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 12 Nov 2023 16:11:11 +0100 Subject: [PATCH] bump reporting xep and add ability to report messages --- monocles_chat.doap | 2 +- .../conversations/generator/IqGenerator.java | 10 ++++-- .../services/XmppConnectionService.java | 4 +-- .../conversations/ui/BlockContactDialog.java | 33 ++++++++++++++++--- .../conversations/ui/BlocklistActivity.java | 2 +- .../ui/ConversationFragment.java | 19 +++++++++++ .../ui/util/MucDetailsContextMenuHelper.java | 2 +- .../eu/siacs/conversations/xml/Namespace.java | 2 ++ .../conversations/xmpp/XmppConnection.java | 2 +- src/main/res/menu/message_context.xml | 4 +++ src/main/res/values-de-rDE/strings.xml | 2 ++ src/main/res/values/strings.xml | 2 ++ 12 files changed, 72 insertions(+), 12 deletions(-) diff --git a/monocles_chat.doap b/monocles_chat.doap index e1b7a3d31..2808bb9ff 100644 --- a/monocles_chat.doap +++ b/monocles_chat.doap @@ -460,7 +460,7 @@ complete - 0.2 + 0.3.1 diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 225fd2340..f965b1293 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -375,12 +375,18 @@ public class IqGenerator extends AbstractGenerator { return iq; } - public IqPacket generateSetBlockRequest(final Jid jid, boolean reportSpam) { + public IqPacket generateSetBlockRequest(final Jid jid, final boolean reportSpam, final String serverMsgId) { final IqPacket iq = new IqPacket(IqPacket.TYPE.SET); final Element block = iq.addChild("block", Namespace.BLOCKING); final Element item = block.addChild("item").setAttribute("jid", jid); if (reportSpam) { - item.addChild("report", "urn:xmpp:reporting:0").addChild("spam"); + final Element report = item.addChild("report", Namespace.REPORTING); + report.setAttribute("reason", Namespace.REPORTING_REASON_SPAM); + if (serverMsgId != null) { + final Element stanzaId = report.addChild("stanza-id", Namespace.STANZA_IDS); + stanzaId.setAttribute("by", jid); + stanzaId.setAttribute("id", serverMsgId); + } } Log.d(Config.LOGTAG, iq.toString()); return iq; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 33a883b40..734b0d6f0 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -5798,10 +5798,10 @@ public class XmppConnectionService extends Service { } } - public boolean sendBlockRequest(final Blockable blockable, boolean reportSpam) { + public boolean sendBlockRequest(final Blockable blockable, final boolean reportSpam, final String serverMsgId) { if (blockable != null && blockable.getBlockedJid() != null) { final Jid jid = blockable.getBlockedJid(); - this.sendIqPacket(blockable.getAccount(), getIqGenerator().generateSetBlockRequest(jid, reportSpam), (a, response) -> { + this.sendIqPacket(blockable.getAccount(), getIqGenerator().generateSetBlockRequest(jid, reportSpam, serverMsgId), (a, response) -> { if (response.getType() == IqPacket.TYPE.RESULT) { a.getBlocklist().add(jid); updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED); diff --git a/src/main/java/eu/siacs/conversations/ui/BlockContactDialog.java b/src/main/java/eu/siacs/conversations/ui/BlockContactDialog.java index a54abf1b1..e7867d9cd 100644 --- a/src/main/java/eu/siacs/conversations/ui/BlockContactDialog.java +++ b/src/main/java/eu/siacs/conversations/ui/BlockContactDialog.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.ui; import android.view.View; +import android.widget.Toast; import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; @@ -14,13 +15,27 @@ import eu.siacs.conversations.ui.util.JidDialog; import me.drakeet.support.toast.ToastCompat; public final class BlockContactDialog { + public static void show(final XmppActivity xmppActivity, final Blockable blockable) { + show(xmppActivity, blockable, null); + } + public static void show(final XmppActivity xmppActivity, final Blockable blockable, final String serverMsgId) { final AlertDialog.Builder builder = new AlertDialog.Builder(xmppActivity); final boolean isBlocked = blockable.isBlocked(); builder.setNegativeButton(R.string.cancel, null); DialogBlockContactBinding binding = DataBindingUtil.inflate(xmppActivity.getLayoutInflater(), R.layout.dialog_block_contact, null, false); final boolean reporting = blockable.getAccount().getXmppConnection().getFeatures().spamReporting(); - binding.reportSpam.setVisibility(!isBlocked && reporting ? View.VISIBLE : View.GONE); + if (reporting && !isBlocked) { + binding.reportSpam.setVisibility(View.VISIBLE); + if (serverMsgId != null) { + binding.reportSpam.setChecked(true); + binding.reportSpam.setEnabled(false); + } else { + binding.reportSpam.setEnabled(true); + } + } else { + binding.reportSpam.setVisibility(View.GONE); + } builder.setView(binding.getRoot()); final String value; @@ -34,8 +49,18 @@ public final class BlockContactDialog { value =blockable.getJid().getDomain().toEscapedString(); res = isBlocked ? R.string.unblock_domain_text : R.string.block_domain_text; } else { - int resBlockAction = blockable instanceof Conversation && ((Conversation) blockable).isWithStranger() ? R.string.block_stranger : R.string.action_block_contact; - builder.setTitle(isBlocked ? R.string.action_unblock_contact : resBlockAction); + if (isBlocked) { + builder.setTitle(R.string.action_unblock_contact); + } else if (serverMsgId != null) { + builder.setTitle(R.string.report_spam_and_block); + } else { + final int resBlockAction = + blockable instanceof Conversation + && ((Conversation) blockable).isWithStranger() + ? R.string.block_stranger + : R.string.action_block_contact; + builder.setTitle(resBlockAction); + } value = blockable.getJid().asBareJid().toEscapedString(); res = isBlocked ? R.string.unblock_contact_text : R.string.block_contact_text; } @@ -45,7 +70,7 @@ public final class BlockContactDialog { xmppActivity.xmppConnectionService.sendUnblockRequest(blockable); } else { boolean toastShown = false; - if (xmppActivity.xmppConnectionService.sendBlockRequest(blockable, binding.reportSpam.isChecked())) { + if (xmppActivity.xmppConnectionService.sendBlockRequest(blockable, binding.reportSpam.isChecked(), serverMsgId)) { ToastCompat.makeText(xmppActivity, R.string.corresponding_conversations_closed, ToastCompat.LENGTH_SHORT).show(); toastShown = true; } diff --git a/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java b/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java index 7e05a0d45..e5e847fdb 100644 --- a/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/BlocklistActivity.java @@ -89,7 +89,7 @@ public class BlocklistActivity extends AbstractSearchableListItemActivity implem dialog.setOnEnterJidDialogPositiveListener((accountJid, contactJid, x, y) -> { Blockable blockable = new RawBlockable(account, contactJid); - if (xmppConnectionService.sendBlockRequest(blockable, false)) { + if (xmppConnectionService.sendBlockRequest(blockable, false, null)) { ToastCompat.makeText(BlocklistActivity.this, R.string.corresponding_conversations_closed, ToastCompat.LENGTH_SHORT).show(); } return true; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 8d25d3bae..f49744679 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -2043,6 +2043,7 @@ public class ConversationFragment extends XmppFragment || m.getEncryption() == Message.ENCRYPTION_PGP; final boolean receiving = m.getStatus() == Message.STATUS_RECEIVED && (t instanceof JingleFileTransferConnection || t instanceof HttpDownloadConnection); activity.getMenuInflater().inflate(R.menu.message_context, menu); + final MenuItem reportAndBlock = menu.findItem(R.id.action_report_and_block); MenuItem openWith = menu.findItem(R.id.open_with); MenuItem copyMessage = menu.findItem(R.id.copy_message); MenuItem quoteMessage = menu.findItem(R.id.quote_message); @@ -2067,6 +2068,17 @@ public class ConversationFragment extends XmppFragment onlyThisThread.setVisible(!conversation.getLockThread() && m.getThread() != null); final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(m); final boolean showError = m.getStatus() == Message.STATUS_SEND_FAILED && m.getErrorMessage() != null && !Message.ERROR_MESSAGE_CANCELLED.equals(m.getErrorMessage()); + final Conversational conversational = m.getConversation(); + if (m.getStatus() == Message.STATUS_RECEIVED && conversational instanceof Conversation c) { + final XmppConnection connection = c.getAccount().getXmppConnection(); + if (c.isWithStranger() + && m.getServerMsgId() != null + && !c.isBlocked() + && connection != null + && connection.getFeatures().spamReporting()) { + reportAndBlock.setVisible(true); + } + } final boolean messageDeleted = m.isMessageDeleted(); deleteMessage.setVisible(true); if (!encrypted && !m.getBody().equals("")) { @@ -2268,6 +2280,9 @@ public class ConversationFragment extends XmppFragment case R.id.show_error_message: showErrorMessage(selectedMessage); return true; + case R.id.action_report_and_block: + reportMessage(selectedMessage); + return true; case R.id.open_with: openWith(selectedMessage); return true; @@ -3451,6 +3466,10 @@ public class ConversationFragment extends XmppFragment } } + private void reportMessage(final Message message) { + BlockContactDialog.show(activity, conversation.getContact(), message.getServerMsgId()); + } + private void showErrorMessage(final Message message) { final AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); builder.setTitle(R.string.error_message); diff --git a/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java b/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java index 582cd8bb8..1e765ffa5 100644 --- a/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java +++ b/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java @@ -318,7 +318,7 @@ public final class MucDetailsContextMenuHelper { return true; case R.id.context_muc_contact_block_unblock: try { - activity.xmppConnectionService.sendBlockRequest(new RawBlockable(account, user.getFullJid()), false); + activity.xmppConnectionService.sendBlockRequest(new RawBlockable(account, user.getFullJid()), false,null); activity.xmppConnectionService.leaveMuc(conversation); activity.xmppConnectionService.joinMuc(conversation); } catch (Exception e) { diff --git a/src/main/java/eu/siacs/conversations/xml/Namespace.java b/src/main/java/eu/siacs/conversations/xml/Namespace.java index 9efc2f00b..abfc38219 100644 --- a/src/main/java/eu/siacs/conversations/xml/Namespace.java +++ b/src/main/java/eu/siacs/conversations/xml/Namespace.java @@ -69,4 +69,6 @@ public final class Namespace { public static final String UNIFIED_PUSH = "http://gultsch.de/xmpp/drafts/unified-push"; public static final String VCARD4 = "urn:ietf:params:xml:ns:vcard-4.0"; public static final String SDP_OFFER_ANSWER = "urn:ietf:rfc:3264"; + public static final String REPORTING = "urn:xmpp:reporting:1"; + public static final String REPORTING_REASON_SPAM = "urn:xmpp:reporting:spam"; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index e0972c979..2d40b0ac7 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -2926,7 +2926,7 @@ public class XmppConnection implements Runnable { } public boolean spamReporting() { - return hasDiscoFeature(account.getDomain(), "urn:xmpp:reporting:reason:spam:0"); + return hasDiscoFeature(account.getDomain(), Namespace.REPORTING); } public boolean flexibleOfflineMessageRetrieval() { diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml index c326036a2..4e66ef4c1 100644 --- a/src/main/res/menu/message_context.xml +++ b/src/main/res/menu/message_context.xml @@ -2,6 +2,10 @@ + Grau Blau GrĂ¼n und blau + Melde Spam + Melde Spam und blockiere Spammer \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index ee94bc8a1..3a07306dd 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1408,4 +1408,6 @@ Green and blue Send link previews Attach metadata about links when sending a message + Report spam + Report spam and block spammer