Optionally allow notifications for replies to my messages

Stephen Paul Weber created

Change summary

src/cheogram/res/values/strings.xml                                    |  1 
src/main/java/eu/siacs/conversations/entities/Conversation.java        |  5 
src/main/java/eu/siacs/conversations/services/NotificationService.java | 11 
src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java | 11 
4 files changed, 24 insertions(+), 4 deletions(-)

Detailed changes

src/cheogram/res/values/strings.xml 🔗

@@ -41,4 +41,5 @@
     <string name="you_are_not_participating">You are muted</string>
     <string name="pref_follow_thread_in_channel">Auto-follow thread in channels</string>
     <string name="pref_follow_thread_in_channel_summary">Set the thread marker to match the message currently being looked at</string>
+    <string name="notify_only_when_highlighted_or_replied">Notify for mentions and replies</string>
 </resources>

src/main/java/eu/siacs/conversations/entities/Conversation.java 🔗

@@ -160,6 +160,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
 
     public static final String ATTRIBUTE_MUTED_TILL = "muted_till";
     public static final String ATTRIBUTE_ALWAYS_NOTIFY = "always_notify";
+    public static final String ATTRIBUTE_NOTIFY_REPLIES = "notify_replies";
     public static final String ATTRIBUTE_LAST_CLEAR_HISTORY = "last_clear_history";
     public static final String ATTRIBUTE_FORMERLY_PRIVATE_NON_ANONYMOUS = "formerly_private_non_anonymous";
     public static final String ATTRIBUTE_PINNED_ON_TOP = "pinned_on_top";
@@ -1081,6 +1082,10 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
         return mode == MODE_SINGLE || getBooleanAttribute(ATTRIBUTE_ALWAYS_NOTIFY, Config.ALWAYS_NOTIFY_BY_DEFAULT || isPrivateAndNonAnonymous());
     }
 
+    public boolean notifyReplies() {
+        return alwaysNotify() || getBooleanAttribute(ATTRIBUTE_NOTIFY_REPLIES, false);
+    }
+
     public boolean setAttribute(String key, boolean value) {
         return setAttribute(key, String.valueOf(value));
     }

src/main/java/eu/siacs/conversations/services/NotificationService.java 🔗

@@ -86,6 +86,7 @@ import eu.siacs.conversations.utils.Compatibility;
 import eu.siacs.conversations.utils.GeoHelper;
 import eu.siacs.conversations.utils.TorServiceUtils;
 import eu.siacs.conversations.utils.UIHelper;
+import eu.siacs.conversations.xml.Element;
 import eu.siacs.conversations.xmpp.Jid;
 import eu.siacs.conversations.xmpp.XmppConnection;
 import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
@@ -316,7 +317,7 @@ public class NotificationService {
         final Conversation conversation = (Conversation) message.getConversation();
         return message.getStatus() == Message.STATUS_RECEIVED
                 && !conversation.isMuted()
-                && (conversation.alwaysNotify() || wasHighlightedOrPrivate(message))
+                && (conversation.alwaysNotify() || (wasHighlightedOrPrivate(message) || (conversation.notifyReplies() && wasReplyToMe(message))))
                 && (!conversation.isWithStranger() || notificationsFromStrangers())
                 && message.getType() != Message.TYPE_RTP_SESSION;
     }
@@ -1830,6 +1831,14 @@ public class NotificationService {
         }
     }
 
+    private boolean wasReplyToMe(final Message message) {
+       final Element reply = message.getReply();
+       if (reply == null || reply.getAttribute("id") == null) return false;
+       final Message parent = ((Conversation) message.getConversation()).findMessageWithRemoteIdAndCounterpart(reply.getAttribute("id"), null);
+       if (parent == null) return false;
+       return parent.getStatus() >= Message.STATUS_SEND;
+    }
+
     public void setOpenConversation(final Conversation conversation) {
         this.mOpenConversation = conversation;
     }

src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java 🔗

@@ -116,22 +116,24 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
             String[] choices = {
                     getString(R.string.notify_on_all_messages),
                     getString(R.string.notify_only_when_highlighted),
+                    getString(R.string.notify_only_when_highlighted_or_replied),
                     getString(R.string.notify_never)
             };
             final AtomicInteger choice;
             if (mConversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0) == Long.MAX_VALUE) {
-                choice = new AtomicInteger(2);
+                choice = new AtomicInteger(3);
             } else {
-                choice = new AtomicInteger(mConversation.alwaysNotify() ? 0 : 1);
+                choice = new AtomicInteger(mConversation.alwaysNotify() ? 0 : (mConversation.notifyReplies() ? 2 : 1));
             }
             builder.setSingleChoiceItems(choices, choice.get(), (dialog, which) -> choice.set(which));
             builder.setNegativeButton(R.string.cancel, null);
             builder.setPositiveButton(R.string.ok, (dialog, which) -> {
-                if (choice.get() == 2) {
+                if (choice.get() == 3) {
                     mConversation.setMutedTill(Long.MAX_VALUE);
                 } else {
                     mConversation.setMutedTill(0);
                     mConversation.setAttribute(Conversation.ATTRIBUTE_ALWAYS_NOTIFY, String.valueOf(choice.get() == 0));
+                    mConversation.setAttribute(Conversation.ATTRIBUTE_NOTIFY_REPLIES, String.valueOf(choice.get() == 2));
                 }
                 xmppConnectionService.updateConversation(mConversation);
                 updateView();
@@ -606,6 +608,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
         } else if (mConversation.alwaysNotify()) {
             this.binding.notificationStatusText.setText(R.string.notify_on_all_messages);
             this.binding.notificationStatusButton.setImageResource(ic_notifications);
+        } else if (mConversation.notifyReplies()) {
+            this.binding.notificationStatusText.setText(R.string.notify_only_when_highlighted_or_replied);
+            this.binding.notificationStatusButton.setImageResource(ic_notifications_none);
         } else {
             this.binding.notificationStatusText.setText(R.string.notify_only_when_highlighted);
             this.binding.notificationStatusButton.setImageResource(ic_notifications_none);