diff --git a/src/cheogram/res/values/strings.xml b/src/cheogram/res/values/strings.xml
index 437854cd1978db8f9ec2fa6cccd79820ec659bc2..9a45eedbb05b5910c8c99c80bbc9486a3e3e3841 100644
--- a/src/cheogram/res/values/strings.xml
+++ b/src/cheogram/res/values/strings.xml
@@ -48,4 +48,5 @@
Block inviter
Add Chat
Received invite from stranger
+ Hide chats in Chat Requests area
diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java
index ede29d066eeb5e525208e7a4fd55e9a0bd3ee692..223b28114e01635b0f88dc7ca88f6790ebb32ba1 100644
--- a/src/main/java/eu/siacs/conversations/entities/Conversation.java
+++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java
@@ -218,6 +218,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
protected HashMap threads = new HashMap<>();
protected Multimap reactions = HashMultimap.create();
private String displayState = null;
+ protected boolean anyMatchSpam = false;
public Conversation(final String name, final Account account, final Jid contactJid,
final int mode) {
@@ -1388,19 +1389,36 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
}
}
+ public void checkSpam(Message... messages) {
+ if (anyMatchSpam) return;
+
+ final var locale = java.util.Locale.getDefault();
+ final var script = locale.getScript();
+ for (final var m : messages) {
+ final var body = m.getRawBody();
+ if (body.length() > 320 || (!"Cyrl".equals(script) && body.matches(".*\\p{IsCyrillic}.*")) || body.matches(".*(?:\\n.*\\n.*\\n|[Aa]\\s*d\\s*v\\s*v\\s*e\\s*r\\s*t|[Pp]romotion|[Dd][Dd][Oo][Ss]|[Ee]scrow|payout|seller|\\?OTR|write me when will be|[Pp]rii?vee?t|there online|bit\\.ly|goo\\.gl|tinyurl\\.com|tiny\\.cc|lc\\.chat|is\\.gd|soo\\.gd|s2r\\.co|clicky\\.me|budrul\\.com|bc\\.vc|uguu\\.se).*")) {
+ anyMatchSpam = true;
+ return;
+ }
+ }
+ }
+
public void add(Message message) {
+ checkSpam(message);
synchronized (this.messages) {
this.messages.add(message);
}
}
public void prepend(int offset, Message message) {
+ checkSpam(message);
synchronized (this.messages) {
this.messages.add(Math.min(offset, this.messages.size()), message);
}
}
public void addAll(int index, List messages) {
+ checkSpam(messages.toArray(new Message[0]));
synchronized (this.messages) {
this.messages.addAll(index, messages);
}
@@ -1494,6 +1512,13 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
return sentMessagesCount() > 0;
}
+ public boolean isChatRequest(final String pref) {
+ if ("disable".equals(pref)) return false;
+ if ("strangers".equals(pref)) return isWithStranger();
+ if (!isWithStranger() && !strangerInvited()) return false;
+ return anyMatchSpam;
+ }
+
public boolean isWithStranger() {
final Contact contact = getContact();
return mode == MODE_SINGLE
diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java
index d50d7a75879354266a14fef5dda42277b5d7f419..6c04eb93b341ceb4159eb10f33cb5fb9ee23bdcc 100644
--- a/src/main/java/eu/siacs/conversations/services/NotificationService.java
+++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java
@@ -389,10 +389,11 @@ public class NotificationService {
private boolean notifyMessage(final Message message) {
final Conversation conversation = (Conversation) message.getConversation();
+ final var chatRequestsPref = mXmppConnectionService.getStringPreference("chat_requests", R.string.default_chat_requests);
return message.getStatus() == Message.STATUS_RECEIVED
&& !conversation.isMuted()
&& (conversation.alwaysNotify() || (wasHighlightedOrPrivate(message) || (conversation.notifyReplies() && wasReplyToMe(message))))
- && (!conversation.isWithStranger() || notificationsFromStrangers())
+ && !conversation.isChatRequest(chatRequestsPref)
&& message.getType() != Message.TYPE_RTP_SESSION;
}
@@ -401,11 +402,6 @@ public class NotificationService {
&& message.getStatus() == Message.STATUS_RECEIVED;
}
- public boolean notificationsFromStrangers() {
- return mXmppConnectionService.getBooleanPreference(
- "notifications_from_strangers", R.bool.notifications_from_strangers);
- }
-
private boolean isQuietHours(Account account) {
return isQuietHours(mXmppConnectionService, account);
}
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index ba8b4baf34c801418f8e439c3fa74a214578415a..3b2282af8ff1af8e4e2cff2dee65caa137407bdb 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -4985,6 +4985,10 @@ public class XmppConnectionService extends Service {
return getPreferences().getBoolean(name, getResources().getBoolean(res));
}
+ public String getStringPreference(String name, @BoolRes int res) {
+ return getPreferences().getString(name, getResources().getString(res));
+ }
+
public boolean confirmMessages() {
return getBooleanPreference("confirm_messages", R.bool.confirm_messages);
}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java
index 68b70fa891846d1b0bc6ed1505d7ece05e06e181..f9a57546566b6b26bde0d21c978afb15a212681a 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java
@@ -152,13 +152,14 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
public static final long DRAWER_MANAGE_ACCOUNT = 4;
public static final long DRAWER_MANAGE_PHONE_ACCOUNTS = 5;
public static final long DRAWER_CHANNELS = 6;
- public static final long DRAWER_SETTINGS = 7;
- public static final long DRAWER_START_CHAT = 8;
- public static final long DRAWER_START_CHAT_CONTACT = 9;
- public static final long DRAWER_START_CHAT_NEW = 10;
- public static final long DRAWER_START_CHAT_GROUP = 11;
- public static final long DRAWER_START_CHAT_PUBLIC = 12;
- public static final long DRAWER_START_CHAT_DISCOVER = 13;
+ public static final long DRAWER_CHAT_REQUESTS = 7;
+ public static final long DRAWER_SETTINGS = 8;
+ public static final long DRAWER_START_CHAT = 9;
+ public static final long DRAWER_START_CHAT_CONTACT = 10;
+ public static final long DRAWER_START_CHAT_NEW = 11;
+ public static final long DRAWER_START_CHAT_GROUP = 12;
+ public static final long DRAWER_START_CHAT_PUBLIC = 13;
+ public static final long DRAWER_START_CHAT_DISCOVER = 14;
//secondary fragment (when holding the conversation, must be initialized before refreshing the overview fragment
private static final @IdRes
@@ -200,6 +201,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
if (accountHeader == null) return;
+ final var chatRequestsPref = xmppConnectionService.getStringPreference("chat_requests", R.string.default_chat_requests);
final var accountUnreads = new HashMap();
binding.drawer.apply(dr -> {
final var items = binding.drawer.getItemAdapter().getAdapterItems();
@@ -208,6 +210,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
var totalUnread = 0;
var dmUnread = 0;
var channelUnread = 0;
+ var chatRequests = 0;
final var selectedAccount = selectedAccount();
populateWithOrderedConversations(conversations, false, false);
for (final var c : conversations) {
@@ -219,6 +222,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
} else {
dmUnread += unread;
}
+ if (c.isChatRequest(chatRequestsPref)) chatRequests++;
}
var accountUnread = accountUnreads.get(c.getAccount());
if (accountUnread == null) accountUnread = 0;
@@ -255,6 +259,27 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
new com.mikepenz.materialdrawer.holder.StringHolder(channelUnread > 0 ? new Integer(channelUnread).toString() : null)
);
+ if (chatRequests > 0) {
+ if (binding.drawer.getItemAdapter().getAdapterPosition(DRAWER_CHAT_REQUESTS) < 0) {
+ final var color = MaterialColors.getColor(binding.drawer, com.google.android.material.R.attr.colorPrimaryContainer);
+ final var textColor = MaterialColors.getColor(binding.drawer, com.google.android.material.R.attr.colorOnPrimaryContainer);
+ final var requests = new com.mikepenz.materialdrawer.model.PrimaryDrawerItem();
+ requests.setIdentifier(DRAWER_CHAT_REQUESTS);
+ com.mikepenz.materialdrawer.model.interfaces.NameableKt.setNameText(requests, "Chat Requests");
+ com.mikepenz.materialdrawer.model.interfaces.IconableKt.setIconRes(requests, R.drawable.ic_person_add_24dp);
+ requests.setBadgeStyle(new com.mikepenz.materialdrawer.holder.BadgeStyle(com.mikepenz.materialdrawer.R.drawable.material_drawer_badge, color, color, textColor));
+ binding.drawer.getItemAdapter().add(binding.drawer.getItemAdapter().getGlobalPosition(binding.drawer.getItemAdapter().getAdapterPosition(DRAWER_CHANNELS) + 1), requests);
+ }
+ com.mikepenz.materialdrawer.util.MaterialDrawerSliderViewExtensionsKt.updateBadge(
+ binding.drawer,
+ DRAWER_CHAT_REQUESTS,
+ new com.mikepenz.materialdrawer.holder.StringHolder(chatRequests > 0 ? new Integer(chatRequests).toString() : null)
+ );
+ } else {
+ binding.drawer.getItemAdapter().removeByIdentifier(DRAWER_CHAT_REQUESTS);
+ }
+
+ final var endOfMainFilters = chatRequests > 0 ? 6 : 5;
long id = 1000;
final var inDrawer = new HashMap();
for (final var item : ImmutableList.copyOf(items)) {
@@ -283,11 +308,11 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
final var color = MaterialColors.getColor(binding.drawer, com.google.android.material.R.attr.colorPrimaryContainer);
final var textColor = MaterialColors.getColor(binding.drawer, com.google.android.material.R.attr.colorOnPrimaryContainer);
item.setBadgeStyle(new com.mikepenz.materialdrawer.holder.BadgeStyle(com.mikepenz.materialdrawer.R.drawable.material_drawer_badge, color, color, textColor));
- binding.drawer.getItemAdapter().add(binding.drawer.getItemAdapter().getGlobalPosition(5), item);
+ binding.drawer.getItemAdapter().add(binding.drawer.getItemAdapter().getGlobalPosition(endOfMainFilters), item);
}
}
- items.subList(5, 5 + tags.size()).sort((x, y) -> x.getTag() == null ? -1 : ((Comparable) x.getTag()).compareTo(y.getTag()));
+ items.subList(endOfMainFilters, endOfMainFilters + tags.size()).sort((x, y) -> x.getTag() == null ? -1 : ((Comparable) x.getTag()).compareTo(y.getTag()));
binding.drawer.getItemAdapter().getFastAdapter().notifyDataSetChanged();
return kotlin.Unit.INSTANCE;
});
@@ -489,7 +514,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
launchStartConversation(R.id.create_public_channel);
} else if (id == DRAWER_START_CHAT_DISCOVER) {
launchStartConversation(R.id.discover_public_channels);
- } else if (id == DRAWER_ALL_CHATS || id == DRAWER_UNREAD_CHATS || id == DRAWER_DIRECT_MESSAGES || id == DRAWER_CHANNELS) {
+ } else if (id == DRAWER_ALL_CHATS || id == DRAWER_UNREAD_CHATS || id == DRAWER_DIRECT_MESSAGES || id == DRAWER_CHANNELS || id == DRAWER_CHAT_REQUESTS) {
selectedTag.clear();
mainFilter = id;
binding.drawer.getSelectExtension().deselect();
@@ -516,7 +541,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
binding.drawer.setOnDrawerItemLongClickListener((v, drawerItem, pos) -> {
final var id = drawerItem.getIdentifier();
- if (id == DRAWER_ALL_CHATS || id == DRAWER_UNREAD_CHATS || id == DRAWER_DIRECT_MESSAGES || id == DRAWER_CHANNELS) {
+ if (id == DRAWER_ALL_CHATS || id == DRAWER_UNREAD_CHATS || id == DRAWER_DIRECT_MESSAGES || id == DRAWER_CHANNELS || id == DRAWER_CHAT_REQUESTS) {
selectedTag.clear();
mainFilter = id;
binding.drawer.getSelectExtension().deselect();
@@ -639,6 +664,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
}
protected void filterByMainFilter(List list) {
+ final var chatRequests = xmppConnectionService.getStringPreference("chat_requests", R.string.default_chat_requests);
for (final var c : ImmutableList.copyOf(list)) {
if (mainFilter == DRAWER_CHANNELS && c.getMode() != Conversation.MODE_MULTI) {
list.remove(c);
@@ -646,6 +672,11 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
list.remove(c);
} else if (mainFilter == DRAWER_UNREAD_CHATS && c.unreadCount(xmppConnectionService) < 1) {
list.remove(c);
+ } else if (mainFilter == DRAWER_CHAT_REQUESTS && !c.isChatRequest(chatRequests)) {
+ list.remove(c);
+ }
+ if (mainFilter != DRAWER_CHAT_REQUESTS && c.isChatRequest(chatRequests)) {
+ list.remove(c);
}
}
}
diff --git a/src/main/java/eu/siacs/conversations/ui/fragment/settings/NotificationsSettingsFragment.java b/src/main/java/eu/siacs/conversations/ui/fragment/settings/NotificationsSettingsFragment.java
index 3af9a0c38c3c162db08be1649c0158dac55b95ca..4ba9ac8c41a517673d77f60024d248b84a9a472a 100644
--- a/src/main/java/eu/siacs/conversations/ui/fragment/settings/NotificationsSettingsFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/fragment/settings/NotificationsSettingsFragment.java
@@ -15,6 +15,7 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
+import androidx.preference.ListPreference;
import com.google.common.base.Optional;
@@ -65,6 +66,7 @@ public class NotificationsSettingsFragment extends XmppPreferenceFragment {
final var notificationHeadsUp = findPreference(AppSettings.NOTIFICATION_HEADS_UP);
final var notificationVibrate = findPreference(AppSettings.NOTIFICATION_VIBRATE);
final var notificationLed = findPreference(AppSettings.NOTIFICATION_LED);
+ final var chatRequests = (ListPreference) findPreference("chat_requests");
final var foregroundService = findPreference(AppSettings.KEEP_FOREGROUND_SERVICE);
if (messageNotificationSettings == null
|| fullscreenNotification == null
@@ -91,6 +93,11 @@ public class NotificationsSettingsFragment extends XmppPreferenceFragment {
.canUseFullScreenIntent()) {
fullscreenNotification.setVisible(false);
}
+
+ final var sharedPreferences = getPreferenceManager().getSharedPreferences();
+ if (!sharedPreferences.getBoolean("notifications_from_strangers", true) && sharedPreferences.getString("chat_requests", null) == null) {
+ chatRequests.setValue("strangers");
+ }
}
@Override
diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
index 20ce6bdda935f219128b5903bfd934fd0ca659be..068c4654976135942eb7e8a090c44658adbebd5b 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
@@ -16,6 +16,7 @@ import com.google.common.collect.Collections2;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableSet;
+import eu.siacs.conversations.R;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
@@ -255,13 +256,9 @@ public class JingleConnectionManager extends AbstractConnectionManager {
}
private boolean isWithStrangerAndStrangerNotificationsAreOff(final Account account, Jid with) {
- final boolean notifyForStrangers =
- mXmppConnectionService.getNotificationService().notificationsFromStrangers();
- if (notifyForStrangers) {
- return false;
- }
- final Contact contact = account.getRoster().getContact(with);
- return !contact.showInContactList();
+ final var chatRequestsPref = mXmppConnectionService.getStringPreference("chat_requests", R.string.default_chat_requests);
+ final var conversation = mXmppConnectionService.findOrCreateConversation(account, with, false, true);
+ return conversation.isChatRequest(chatRequestsPref);
}
ScheduledFuture> schedule(
diff --git a/src/main/res/values/arrays.xml b/src/main/res/values/arrays.xml
index 486bb025f720404fadedd1bda7d7fcd622703031..06278a7e6fd533be7970542845f22ab5e7b3e678 100644
--- a/src/main/res/values/arrays.xml
+++ b/src/main/res/values/arrays.xml
@@ -106,6 +106,18 @@
- @string/video_original
+
+ - Never
+ - Suspected SPAM
+ - Chats from strangers
+
+
+
+ - disable
+ - spam
+ - strangers
+
+
- @string/jabber_network
- @string/local_server
diff --git a/src/main/res/values/defaults.xml b/src/main/res/values/defaults.xml
index 8a6d2c8b4f892d88e9e111bd37720055829f1d7b..3b02d9d0102d04ecb77f08f3ad341ab9fdf6a21a 100644
--- a/src/main/res/values/defaults.xml
+++ b/src/main/res/values/defaults.xml
@@ -55,4 +55,5 @@
true
true
true
+ spam
diff --git a/src/main/res/xml/preferences_notifications.xml b/src/main/res/xml/preferences_notifications.xml
index 5daa4c5245e712b79f1313db6bfd65d3dbf71316..8088a85491d9d4d78f33a8bbbfce6f948ef5980e 100644
--- a/src/main/res/xml/preferences_notifications.xml
+++ b/src/main/res/xml/preferences_notifications.xml
@@ -1,5 +1,6 @@
-
+
-
+ android:key="chat_requests"
+ android:title="@string/pref_chat_requests"
+ app:useSimpleSummaryProvider="true" />