mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Improve mention notifications by only showing alerting notifications once.
This commit is contained in:
@@ -39,6 +39,8 @@ import androidx.annotation.StringRes;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||
import org.thoughtcrime.securesms.contactshare.ContactUtil;
|
||||
@@ -71,6 +73,7 @@ import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
@@ -281,8 +284,9 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
boolean signal,
|
||||
int reminderCount)
|
||||
{
|
||||
Cursor telcoCursor = null;
|
||||
Cursor pushCursor = null;
|
||||
boolean isReminder = reminderCount > 0;
|
||||
Cursor telcoCursor = null;
|
||||
Cursor pushCursor = null;
|
||||
|
||||
try {
|
||||
telcoCursor = DatabaseFactory.getMmsSmsDatabase(context).getUnread();
|
||||
@@ -305,6 +309,8 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
lastAudibleNotification = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
boolean shouldScheduleReminder = signal;
|
||||
|
||||
if (notificationState.hasMultipleThreads()) {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
for (long threadId : notificationState.getThreads()) {
|
||||
@@ -312,14 +318,15 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
sendSingleThreadNotification(context,
|
||||
new NotificationState(notificationState.getNotificationsForThread(threadId)),
|
||||
signal && (threadId == targetThread),
|
||||
true);
|
||||
true,
|
||||
isReminder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendMultipleThreadNotification(context, notificationState, signal && (Build.VERSION.SDK_INT < 23));
|
||||
} else {
|
||||
sendSingleThreadNotification(context, notificationState, signal, false);
|
||||
shouldScheduleReminder = sendSingleThreadNotification(context, notificationState, signal, false, isReminder);
|
||||
|
||||
if (isDisplayingSummaryNotification(context)) {
|
||||
sendMultipleThreadNotification(context, notificationState, false);
|
||||
@@ -329,7 +336,18 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
cancelOrphanedNotifications(context, notificationState);
|
||||
updateBadge(context, notificationState.getMessageCount());
|
||||
|
||||
if (signal) {
|
||||
List<Long> smsIds = new LinkedList<>();
|
||||
List<Long> mmsIds = new LinkedList<>();
|
||||
for (NotificationItem item : notificationState.getNotifications()) {
|
||||
if (item.isMms()) {
|
||||
mmsIds.add(item.getId());
|
||||
} else {
|
||||
smsIds.add(item.getId());
|
||||
}
|
||||
}
|
||||
DatabaseFactory.getMmsSmsDatabase(context).setNotifiedTimestamp(System.currentTimeMillis(), smsIds, mmsIds);
|
||||
|
||||
if (shouldScheduleReminder) {
|
||||
scheduleReminder(context, reminderCount);
|
||||
}
|
||||
} finally {
|
||||
@@ -338,23 +356,25 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendSingleThreadNotification(@NonNull Context context,
|
||||
@NonNull NotificationState notificationState,
|
||||
boolean signal,
|
||||
boolean bundled)
|
||||
private static boolean sendSingleThreadNotification(@NonNull Context context,
|
||||
@NonNull NotificationState notificationState,
|
||||
boolean signal,
|
||||
boolean bundled,
|
||||
boolean isReminder)
|
||||
{
|
||||
Log.i(TAG, "sendSingleThreadNotification() signal: " + signal + " bundled: " + bundled);
|
||||
|
||||
if (notificationState.getNotifications().isEmpty()) {
|
||||
if (!bundled) cancelActiveNotifications(context);
|
||||
Log.i(TAG, "[sendSingleThreadNotification] Empty notification state. Skipping.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
NotificationPrivacyPreference notificationPrivacy = TextSecurePreferences.getNotificationPrivacy(context);
|
||||
SingleRecipientNotificationBuilder builder = new SingleRecipientNotificationBuilder(context, notificationPrivacy);
|
||||
List<NotificationItem> notifications = notificationState.getNotifications();
|
||||
Recipient recipient = notifications.get(0).getRecipient();
|
||||
boolean shouldAlert = signal && (isReminder || Stream.of(notifications).anyMatch(item -> item.getNotifiedTimestamp() == 0));
|
||||
int notificationId;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
@@ -369,7 +389,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
notifications.get(0).getText(), notifications.get(0).getSlideDeck());
|
||||
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
|
||||
builder.setDeleteIntent(notificationState.getDeleteIntent(context));
|
||||
builder.setOnlyAlertOnce(!signal);
|
||||
builder.setOnlyAlertOnce(!shouldAlert);
|
||||
builder.setSortKey(String.valueOf(Long.MAX_VALUE - notifications.get(0).getTimestamp()));
|
||||
|
||||
long timestamp = notifications.get(0).getTimestamp();
|
||||
@@ -418,6 +438,8 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
Notification notification = builder.build();
|
||||
NotificationManagerCompat.from(context).notify(notificationId, notification);
|
||||
Log.i(TAG, "Posted notification.");
|
||||
|
||||
return shouldAlert;
|
||||
}
|
||||
|
||||
private static void sendMultipleThreadNotification(@NonNull Context context,
|
||||
@@ -434,11 +456,12 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
NotificationPrivacyPreference notificationPrivacy = TextSecurePreferences.getNotificationPrivacy(context);
|
||||
MultipleRecipientNotificationBuilder builder = new MultipleRecipientNotificationBuilder(context, notificationPrivacy);
|
||||
List<NotificationItem> notifications = notificationState.getNotifications();
|
||||
boolean shouldAlert = signal && Stream.of(notifications).anyMatch(item -> item.getNotifiedTimestamp() == 0);
|
||||
|
||||
builder.setMessageCount(notificationState.getMessageCount(), notificationState.getThreadCount());
|
||||
builder.setMostRecentSender(notifications.get(0).getIndividualRecipient());
|
||||
builder.setDeleteIntent(notificationState.getDeleteIntent(context));
|
||||
builder.setOnlyAlertOnce(!signal);
|
||||
builder.setOnlyAlertOnce(!shouldAlert);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
builder.setGroup(NOTIFICATION_GROUP);
|
||||
@@ -531,6 +554,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
boolean isUnreadMessage = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.READ)) == 0;
|
||||
boolean hasUnreadReactions = cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.REACTIONS_UNREAD)) == 1;
|
||||
long lastReactionRead = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.REACTIONS_LAST_SEEN));
|
||||
long notifiedTimestamp = record.getNotifiedTimestamp();
|
||||
|
||||
if (threadId != -1) {
|
||||
threadRecipients = DatabaseFactory.getThreadDatabase(context).getRecipientForThreadId(threadId);
|
||||
@@ -564,7 +588,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
}
|
||||
|
||||
if (threadRecipients == null || includeMessage) {
|
||||
notificationState.addNotification(new NotificationItem(id, mms, recipient, conversationRecipient, threadRecipients, threadId, body, timestamp, receivedTimestamp, slideDeck, false, record.isJoined(), canReply));
|
||||
notificationState.addNotification(new NotificationItem(id, mms, recipient, conversationRecipient, threadRecipients, threadId, body, timestamp, receivedTimestamp, slideDeck, false, record.isJoined(), canReply, notifiedTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,7 +623,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
||||
}
|
||||
|
||||
if (threadRecipients == null || !threadRecipients.isMuted()) {
|
||||
notificationState.addNotification(new NotificationItem(id, mms, reactionSender, conversationRecipient, threadRecipients, threadId, body, reaction.getDateReceived(), receivedTimestamp, null, true, record.isJoined(), false));
|
||||
notificationState.addNotification(new NotificationItem(id, mms, reactionSender, conversationRecipient, threadRecipients, threadId, body, reaction.getDateReceived(), receivedTimestamp, null, true, record.isJoined(), false, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,13 @@ public class NotificationItem {
|
||||
@Nullable private final Recipient threadRecipient;
|
||||
private final long threadId;
|
||||
@Nullable private final CharSequence text;
|
||||
private final long notificationTimestamp;
|
||||
private final long timestamp;
|
||||
private final long messageReceivedTimestamp;
|
||||
@Nullable private final SlideDeck slideDeck;
|
||||
private final boolean jumpToMessage;
|
||||
private final boolean isJoin;
|
||||
private final boolean canReply;
|
||||
private final long notifiedTimestamp;
|
||||
|
||||
public NotificationItem(long id,
|
||||
boolean mms,
|
||||
@@ -37,12 +38,13 @@ public class NotificationItem {
|
||||
@Nullable Recipient threadRecipient,
|
||||
long threadId,
|
||||
@Nullable CharSequence text,
|
||||
long notificationTimestamp,
|
||||
long timestamp,
|
||||
long messageReceivedTimestamp,
|
||||
@Nullable SlideDeck slideDeck,
|
||||
boolean jumpToMessage,
|
||||
boolean isJoin,
|
||||
boolean canReply)
|
||||
boolean canReply,
|
||||
long notifiedTimestamp)
|
||||
{
|
||||
this.id = id;
|
||||
this.mms = mms;
|
||||
@@ -51,12 +53,13 @@ public class NotificationItem {
|
||||
this.threadRecipient = threadRecipient;
|
||||
this.text = text;
|
||||
this.threadId = threadId;
|
||||
this.notificationTimestamp = notificationTimestamp;
|
||||
this.timestamp = timestamp;
|
||||
this.messageReceivedTimestamp = messageReceivedTimestamp;
|
||||
this.slideDeck = slideDeck;
|
||||
this.jumpToMessage = jumpToMessage;
|
||||
this.isJoin = isJoin;
|
||||
this.canReply = canReply;
|
||||
this.notifiedTimestamp = notifiedTimestamp;
|
||||
}
|
||||
|
||||
public @NonNull Recipient getRecipient() {
|
||||
@@ -72,7 +75,7 @@ public class NotificationItem {
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return notificationTimestamp;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public long getThreadId() {
|
||||
@@ -119,4 +122,8 @@ public class NotificationItem {
|
||||
public boolean canReply() {
|
||||
return canReply;
|
||||
}
|
||||
|
||||
public long getNotifiedTimestamp() {
|
||||
return notifiedTimestamp;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user