mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
fix: notifications deduplicate based on last message ID, ConversationActivityV2.kt updates notification by thread ID
This commit is contained in:
parent
7f047f1c2b
commit
ff853e01b4
@ -24,7 +24,6 @@ import android.widget.Toast
|
|||||||
import androidx.annotation.DimenRes
|
import androidx.annotation.DimenRes
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import androidx.core.view.get
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
@ -53,17 +52,13 @@ import org.session.libsession.messaging.mentions.MentionsManager
|
|||||||
import org.session.libsession.messaging.messages.control.DataExtractionNotification
|
import org.session.libsession.messaging.messages.control.DataExtractionNotification
|
||||||
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage
|
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage
|
||||||
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
|
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
|
||||||
import org.session.libsession.messaging.messages.visible.LinkPreview.Companion.from
|
|
||||||
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation
|
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation
|
||||||
import org.session.libsession.messaging.messages.visible.Quote.Companion.from
|
|
||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageSender
|
import org.session.libsession.messaging.sending_receiving.MessageSender
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
|
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
|
||||||
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
|
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
||||||
import org.session.libsession.messaging.utilities.UpdateMessageData
|
|
||||||
import org.session.libsession.messaging.utilities.UpdateMessageData.Companion.fromJSON
|
|
||||||
import org.session.libsession.utilities.Address
|
import org.session.libsession.utilities.Address
|
||||||
import org.session.libsession.utilities.Address.Companion.fromSerialized
|
import org.session.libsession.utilities.Address.Companion.fromSerialized
|
||||||
import org.session.libsession.utilities.MediaTypes
|
import org.session.libsession.utilities.MediaTypes
|
||||||
@ -116,6 +111,23 @@ import org.thoughtcrime.securesms.permissions.Permissions
|
|||||||
import org.thoughtcrime.securesms.util.*
|
import org.thoughtcrime.securesms.util.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
|
import kotlin.collections.List
|
||||||
|
import kotlin.collections.Set
|
||||||
|
import kotlin.collections.component1
|
||||||
|
import kotlin.collections.component2
|
||||||
|
import kotlin.collections.filter
|
||||||
|
import kotlin.collections.find
|
||||||
|
import kotlin.collections.first
|
||||||
|
import kotlin.collections.forEach
|
||||||
|
import kotlin.collections.indices
|
||||||
|
import kotlin.collections.isNotEmpty
|
||||||
|
import kotlin.collections.iterator
|
||||||
|
import kotlin.collections.listOf
|
||||||
|
import kotlin.collections.mutableListOf
|
||||||
|
import kotlin.collections.mutableMapOf
|
||||||
|
import kotlin.collections.set
|
||||||
|
import kotlin.collections.sortedBy
|
||||||
|
import kotlin.collections.toTypedArray
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
// Some things that seemingly belong to the input bar (e.g. the voice message recording UI) are actually
|
// Some things that seemingly belong to the input bar (e.g. the voice message recording UI) are actually
|
||||||
@ -502,7 +514,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
} else {
|
} else {
|
||||||
MarkReadReceiver.process(this, messages)
|
MarkReadReceiver.process(this, messages)
|
||||||
}
|
}
|
||||||
ApplicationContext.getInstance(this).messageNotifier.updateNotification(this)
|
ApplicationContext.getInstance(this).messageNotifier.updateNotification(this, threadID)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun inputBarHeightChanged(newValue: Int) {
|
override fun inputBarHeightChanged(newValue: Int) {
|
||||||
|
@ -4,18 +4,21 @@ import android.app.Notification;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.annotation.NonNull;
|
import android.os.Bundle;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
|
||||||
import org.session.libsession.utilities.NotificationPrivacyPreference;
|
import org.session.libsession.utilities.NotificationPrivacyPreference;
|
||||||
import org.session.libsession.utilities.recipients.Recipient;
|
|
||||||
import org.session.libsession.utilities.recipients.Recipient.*;
|
|
||||||
import org.session.libsession.utilities.TextSecurePreferences;
|
import org.session.libsession.utilities.TextSecurePreferences;
|
||||||
import org.session.libsession.utilities.Util;
|
import org.session.libsession.utilities.Util;
|
||||||
|
import org.session.libsession.utilities.recipients.Recipient;
|
||||||
|
import org.session.libsession.utilities.recipients.Recipient.VibrateState;
|
||||||
|
|
||||||
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
public abstract class AbstractNotificationBuilder extends NotificationCompat.Builder {
|
public abstract class AbstractNotificationBuilder extends NotificationCompat.Builder {
|
||||||
|
|
||||||
@ -26,10 +29,11 @@ public abstract class AbstractNotificationBuilder extends NotificationCompat.Bui
|
|||||||
|
|
||||||
protected Context context;
|
protected Context context;
|
||||||
protected NotificationPrivacyPreference privacy;
|
protected NotificationPrivacyPreference privacy;
|
||||||
|
protected final Bundle extras;
|
||||||
|
|
||||||
public AbstractNotificationBuilder(Context context, NotificationPrivacyPreference privacy) {
|
public AbstractNotificationBuilder(Context context, NotificationPrivacyPreference privacy) {
|
||||||
super(context);
|
super(context);
|
||||||
|
extras = new Bundle();
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.privacy = privacy;
|
this.privacy = privacy;
|
||||||
|
|
||||||
@ -97,4 +101,10 @@ public abstract class AbstractNotificationBuilder extends NotificationCompat.Bui
|
|||||||
return text.length() <= MAX_DISPLAY_LENGTH ? text
|
return text.length() <= MAX_DISPLAY_LENGTH ? text
|
||||||
: text.subSequence(0, MAX_DISPLAY_LENGTH);
|
: text.subSequence(0, MAX_DISPLAY_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Notification build() {
|
||||||
|
addExtras(extras);
|
||||||
|
return super.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
private static final String TAG = DefaultMessageNotifier.class.getSimpleName();
|
private static final String TAG = DefaultMessageNotifier.class.getSimpleName();
|
||||||
|
|
||||||
public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply";
|
public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply";
|
||||||
|
public static final String LATEST_MESSAGE_ID_TAG = "extra_latest_message_id";
|
||||||
|
|
||||||
private static final int FOREGROUND_ID = 313399;
|
private static final int FOREGROUND_ID = 313399;
|
||||||
private static final int SUMMARY_NOTIFICATION_ID = 1338;
|
private static final int SUMMARY_NOTIFICATION_ID = 1338;
|
||||||
@ -238,14 +239,6 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipients != null && recipients.notifyType != RecipientDatabase.NOTIFY_TYPE_ALL) {
|
|
||||||
// if mentions and no mention then return
|
|
||||||
if (recipients.notifyType == RecipientDatabase.NOTIFY_TYPE_MENTIONS) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
sendInThreadNotification(context, threads.getRecipientForThreadId(threadId));
|
sendInThreadNotification(context, threads.getRecipientForThreadId(threadId));
|
||||||
} else if (!homeScreenVisible) {
|
} else if (!homeScreenVisible) {
|
||||||
@ -280,16 +273,9 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
lastAudibleNotification = System.currentTimeMillis();
|
lastAudibleNotification = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notificationState.hasMultipleThreads()) {
|
boolean hasMultipleThreads = notificationState.hasMultipleThreads();
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
|
||||||
for (long threadId : notificationState.getThreads()) {
|
for (long threadId : notificationState.getThreads()) {
|
||||||
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), false, true);
|
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), signal, hasMultipleThreads);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMultipleThreadNotification(context, notificationState, signal);
|
|
||||||
} else if (notificationState.getMessageCount() > 0){
|
|
||||||
sendSingleThreadNotification(context, notificationState, signal, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelOrphanedNotifications(context, notificationState);
|
cancelOrphanedNotifications(context, notificationState);
|
||||||
@ -320,7 +306,20 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
List<NotificationItem> notifications = notificationState.getNotifications();
|
List<NotificationItem> notifications = notificationState.getNotifications();
|
||||||
Recipient recipient = notifications.get(0).getRecipient();
|
Recipient recipient = notifications.get(0).getRecipient();
|
||||||
int notificationId = (int) (SUMMARY_NOTIFICATION_ID + (bundled ? notifications.get(0).getThreadId() : 0));
|
int notificationId = (int) (SUMMARY_NOTIFICATION_ID + (bundled ? notifications.get(0).getThreadId() : 0));
|
||||||
|
String messageIdTag = String.valueOf(notifications.get(0).getId());
|
||||||
|
|
||||||
|
NotificationManager notificationManager = ServiceUtil.getNotificationManager(context);
|
||||||
|
for (StatusBarNotification notification: notificationManager.getActiveNotifications()) {
|
||||||
|
|
||||||
|
if (messageIdTag.equals(notification.getNotification().extras.getString(LATEST_MESSAGE_ID_TAG))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long timestamp = notifications.get(0).getTimestamp();
|
||||||
|
if (timestamp != 0) builder.setWhen(timestamp);
|
||||||
|
|
||||||
|
builder.putStringExtra(LATEST_MESSAGE_ID_TAG, messageIdTag);
|
||||||
|
|
||||||
builder.setThread(notifications.get(0).getRecipient());
|
builder.setThread(notifications.get(0).getRecipient());
|
||||||
builder.setMessageCount(notificationState.getMessageCount());
|
builder.setMessageCount(notificationState.getMessageCount());
|
||||||
@ -333,11 +332,6 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY);
|
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY);
|
||||||
builder.setAutoCancel(true);
|
builder.setAutoCancel(true);
|
||||||
|
|
||||||
long timestamp = notifications.get(0).getTimestamp();
|
|
||||||
if (timestamp != 0) builder.setWhen(timestamp);
|
|
||||||
|
|
||||||
long threadID = notifications.get(0).getThreadId();
|
|
||||||
|
|
||||||
ReplyMethod replyMethod = ReplyMethod.forRecipient(context, recipient);
|
ReplyMethod replyMethod = ReplyMethod.forRecipient(context, recipient);
|
||||||
|
|
||||||
boolean canReply = SessionMetaProtocol.canUserReplyToNotification(recipient);
|
boolean canReply = SessionMetaProtocol.canUserReplyToNotification(recipient);
|
||||||
|
@ -15,33 +15,38 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
import androidx.core.app.NotificationCompat.Action;
|
import androidx.core.app.NotificationCompat.Action;
|
||||||
import androidx.core.app.RemoteInput;
|
import androidx.core.app.RemoteInput;
|
||||||
|
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
|
||||||
import org.session.libsession.avatars.ContactColors;
|
import org.session.libsession.avatars.ContactColors;
|
||||||
import org.session.libsession.avatars.ContactPhoto;
|
import org.session.libsession.avatars.ContactPhoto;
|
||||||
import org.session.libsession.avatars.GeneratedContactPhoto;
|
import org.session.libsession.avatars.GeneratedContactPhoto;
|
||||||
import org.session.libsession.messaging.contacts.Contact;
|
import org.session.libsession.messaging.contacts.Contact;
|
||||||
|
import org.session.libsession.utilities.NotificationPrivacyPreference;
|
||||||
|
import org.session.libsession.utilities.TextSecurePreferences;
|
||||||
|
import org.session.libsession.utilities.Util;
|
||||||
|
import org.session.libsession.utilities.recipients.Recipient;
|
||||||
import org.session.libsignal.utilities.Log;
|
import org.session.libsignal.utilities.Log;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.SessionContactDatabase;
|
import org.thoughtcrime.securesms.database.SessionContactDatabase;
|
||||||
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator;
|
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
import org.session.libsession.utilities.NotificationPrivacyPreference;
|
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator;
|
||||||
import org.session.libsession.utilities.recipients.Recipient;
|
|
||||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||||
import org.session.libsession.utilities.TextSecurePreferences;
|
|
||||||
import org.session.libsession.utilities.Util;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
public class SingleRecipientNotificationBuilder extends AbstractNotificationBuilder {
|
public class SingleRecipientNotificationBuilder extends AbstractNotificationBuilder {
|
||||||
@ -58,6 +63,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
|
|||||||
{
|
{
|
||||||
super(context, privacy);
|
super(context, privacy);
|
||||||
|
|
||||||
|
|
||||||
setSmallIcon(R.drawable.ic_notification);
|
setSmallIcon(R.drawable.ic_notification);
|
||||||
setColor(context.getResources().getColor(R.color.textsecure_primary));
|
setColor(context.getResources().getColor(R.color.textsecure_primary));
|
||||||
setCategory(NotificationCompat.CATEGORY_MESSAGE);
|
setCategory(NotificationCompat.CATEGORY_MESSAGE);
|
||||||
@ -198,6 +204,10 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
|
|||||||
return R.string.MessageNotifier_reply;
|
return R.string.MessageNotifier_reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void putStringExtra(String key, String value) {
|
||||||
|
extras.putString(key,value);
|
||||||
|
}
|
||||||
|
|
||||||
public void addMessageBody(@NonNull Recipient threadRecipient,
|
public void addMessageBody(@NonNull Recipient threadRecipient,
|
||||||
@NonNull Recipient individualRecipient,
|
@NonNull Recipient individualRecipient,
|
||||||
@Nullable CharSequence messageBody)
|
@Nullable CharSequence messageBody)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user