fix: notifications deduplicate based on last message ID, ConversationActivityV2.kt updates notification by thread ID

This commit is contained in:
Harris 2021-07-21 13:58:07 +10:00
parent 7f047f1c2b
commit ff853e01b4
4 changed files with 67 additions and 41 deletions

View File

@ -24,7 +24,6 @@ import android.widget.Toast
import androidx.annotation.DimenRes
import androidx.appcompat.app.AlertDialog
import androidx.core.view.children
import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
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.signal.OutgoingMediaMessage
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.Quote.Companion.from
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
import org.session.libsession.messaging.sending_receiving.MessageSender
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.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.Companion.fromSerialized
import org.session.libsession.utilities.MediaTypes
@ -116,6 +111,23 @@ import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.util.*
import java.util.*
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.*
// 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 {
MarkReadReceiver.process(this, messages)
}
ApplicationContext.getInstance(this).messageNotifier.updateNotification(this)
ApplicationContext.getInstance(this).messageNotifier.updateNotification(this, threadID)
}
override fun inputBarHeightChanged(newValue: Int) {

View File

@ -4,18 +4,21 @@ import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
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.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient.*;
import org.session.libsession.utilities.TextSecurePreferences;
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 {
@ -26,10 +29,11 @@ public abstract class AbstractNotificationBuilder extends NotificationCompat.Bui
protected Context context;
protected NotificationPrivacyPreference privacy;
protected final Bundle extras;
public AbstractNotificationBuilder(Context context, NotificationPrivacyPreference privacy) {
super(context);
extras = new Bundle();
this.context = context;
this.privacy = privacy;
@ -97,4 +101,10 @@ public abstract class AbstractNotificationBuilder extends NotificationCompat.Bui
return text.length() <= MAX_DISPLAY_LENGTH ? text
: text.subSequence(0, MAX_DISPLAY_LENGTH);
}
@Override
public Notification build() {
addExtras(extras);
return super.build();
}
}

View File

@ -87,6 +87,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
private static final String TAG = DefaultMessageNotifier.class.getSimpleName();
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 SUMMARY_NOTIFICATION_ID = 1338;
@ -238,14 +239,6 @@ public class DefaultMessageNotifier implements MessageNotifier {
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) {
sendInThreadNotification(context, threads.getRecipientForThreadId(threadId));
} else if (!homeScreenVisible) {
@ -280,16 +273,9 @@ public class DefaultMessageNotifier implements MessageNotifier {
lastAudibleNotification = System.currentTimeMillis();
}
if (notificationState.hasMultipleThreads()) {
if (Build.VERSION.SDK_INT >= 23) {
boolean hasMultipleThreads = notificationState.hasMultipleThreads();
for (long threadId : notificationState.getThreads()) {
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), false, true);
}
}
sendMultipleThreadNotification(context, notificationState, signal);
} else if (notificationState.getMessageCount() > 0){
sendSingleThreadNotification(context, notificationState, signal, false);
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), signal, hasMultipleThreads);
}
cancelOrphanedNotifications(context, notificationState);
@ -320,7 +306,20 @@ public class DefaultMessageNotifier implements MessageNotifier {
List<NotificationItem> notifications = notificationState.getNotifications();
Recipient recipient = notifications.get(0).getRecipient();
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.setMessageCount(notificationState.getMessageCount());
@ -333,11 +332,6 @@ public class DefaultMessageNotifier implements MessageNotifier {
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY);
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);
boolean canReply = SessionMetaProtocol.canUserReplyToNotification(recipient);

View File

@ -15,33 +15,38 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.text.SpannableStringBuilder;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationCompat.Action;
import androidx.core.app.RemoteInput;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.session.libsession.avatars.ContactColors;
import org.session.libsession.avatars.ContactPhoto;
import org.session.libsession.avatars.GeneratedContactPhoto;
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.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.SessionContactDatabase;
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.session.libsession.utilities.NotificationPrivacyPreference;
import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator;
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.List;
import java.util.concurrent.ExecutionException;
import network.loki.messenger.R;
public class SingleRecipientNotificationBuilder extends AbstractNotificationBuilder {
@ -58,6 +63,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
{
super(context, privacy);
setSmallIcon(R.drawable.ic_notification);
setColor(context.getResources().getColor(R.color.textsecure_primary));
setCategory(NotificationCompat.CATEGORY_MESSAGE);
@ -198,6 +204,10 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
return R.string.MessageNotifier_reply;
}
public void putStringExtra(String key, String value) {
extras.putString(key,value);
}
public void addMessageBody(@NonNull Recipient threadRecipient,
@NonNull Recipient individualRecipient,
@Nullable CharSequence messageBody)