1
0
Fork 1

Initial message requests feature

This commit is contained in:
Arne 2024-11-08 19:40:57 +01:00
parent 62a44980de
commit c1476de375
10 changed files with 107 additions and 30 deletions

View file

@ -234,6 +234,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
private byte[] symmetricKey;
private String mLastReceivedOtrMessageId = null;
protected boolean anyMatchSpam = false;
public Conversation(final String name, final Account account, final Jid contactJid,
final int mode) {
@ -1553,19 +1554,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|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<Message> messages) {
checkSpam(messages.toArray(new Message[0]));
synchronized (this.messages) {
this.messages.addAll(index, messages);
}
@ -1659,6 +1677,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

View file

@ -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);
}

View file

@ -5126,6 +5126,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);
}

View file

@ -170,13 +170,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
@ -224,6 +225,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<Account, Integer>();
binding.drawer.apply(dr -> {
final var items = binding.drawer.getItemAdapter().getAdapterItems();
@ -232,6 +234,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) {
@ -243,6 +246,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;
@ -279,6 +283,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<Tag, Long>();
for (final var item : ImmutableList.copyOf(items)) {
@ -307,11 +332,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;
});
@ -513,7 +538,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();
@ -540,7 +565,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();
@ -663,6 +688,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
}
protected void filterByMainFilter(List<Conversation> 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);
@ -670,6 +696,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);
}
}
}

View file

@ -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

View file

@ -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(

View file

@ -118,6 +118,18 @@
<item>@string/video_original</item>
</string-array>
<string-array name="chat_requests_entries">
<item>Never</item>
<item>Suspected SPAM</item>
<item>Chats from strangers</item>
</string-array>
<string-array name="chat_requests_values">
<item>disable</item>
<item>spam</item>
<item>strangers</item>
</string-array>
<string-array name="channel_discovery_entries">
<item>@string/jabber_network</item>
<item>@string/local_server</item>

View file

@ -58,4 +58,5 @@
<string name="avatar_shape">oval</string>
<bool name="show_nav_bar">true</bool>
<bool name="enforce_dane">false</bool>
<string name="default_chat_requests">spam</string>
</resources>

View file

@ -1307,4 +1307,5 @@
<string name="close_format_text">Do you really want to close the text formatting toolbar? You can enable the toolbar in the settings again.</string>
<string name="pref_showtextformatting_sum">Show text formatting toolbar in chat while keyboard is shown</string>
<string name="pref_showtextformatting">Text formatting toolbar</string>
<string name="pref_chat_requests">Hide chats in Chat Requests area</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- This preference links to the OS notification settings and only shows up on API >= 26 (Android 8) -->
<PreferenceScreen
android:icon="@drawable/ic_chat_24dp"
@ -65,12 +66,14 @@
android:key="grace_period_length"
android:summary="@string/pref_notification_grace_period_summary"
android:title="@string/pref_notification_grace_period" />
<SwitchPreferenceCompat
android:defaultValue="@bool/notifications_from_strangers"
<ListPreference
android:defaultValue="@string/default_chat_requests"
android:entries="@array/chat_requests_entries"
android:entryValues="@array/chat_requests_values"
android:icon="@drawable/ic_domino_mask_24dp"
android:key="notifications_from_strangers"
android:summary="@string/pref_notifications_from_strangers_summary"
android:title="@string/pref_notifications_from_strangers" />
android:key="chat_requests"
android:title="@string/pref_chat_requests"
app:useSimpleSummaryProvider="true" />
<SwitchPreferenceCompat
android:defaultValue="@bool/enable_foreground_service"