mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-25 17:37:57 +00:00
Improve mention notifications by only showing alerting notifications once.
This commit is contained in:
@@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
@@ -335,6 +336,20 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setNotifiedTimestamp(long timestamp, @NonNull List<Long> ids) {
|
||||
if (ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
SqlUtil.Query where = SqlUtil.buildCollectionQuery(ID, ids);
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(NOTIFIED_TIMESTAMP, timestamp);
|
||||
|
||||
db.update(getTableName(), values, where.getWhere(), where.getWhereArgs());
|
||||
}
|
||||
|
||||
public void addMismatchedIdentity(long messageId, @NonNull RecipientId recipientId, IdentityKey identityKey) {
|
||||
try {
|
||||
addToDocument(messageId, MISMATCHED_IDENTITIES,
|
||||
|
@@ -183,7 +183,8 @@ public class MmsDatabase extends MessageDatabase {
|
||||
REACTIONS_UNREAD + " INTEGER DEFAULT 0, " +
|
||||
REACTIONS_LAST_SEEN + " INTEGER DEFAULT -1, " +
|
||||
REMOTE_DELETED + " INTEGER DEFAULT 0, " +
|
||||
MENTIONS_SELF + " INTEGER DEFAULT 0);";
|
||||
MENTIONS_SELF + " INTEGER DEFAULT 0, " +
|
||||
NOTIFIED_TIMESTAMP + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");",
|
||||
@@ -208,7 +209,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, MISMATCHED_IDENTITIES, NETWORK_FAILURE, SUBSCRIPTION_ID,
|
||||
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT, QUOTE_MISSING, QUOTE_MENTIONS,
|
||||
SHARED_CONTACTS, LINK_PREVIEWS, UNIDENTIFIED, VIEW_ONCE, REACTIONS, REACTIONS_UNREAD, REACTIONS_LAST_SEEN,
|
||||
REMOTE_DELETED, MENTIONS_SELF,
|
||||
REMOTE_DELETED, MENTIONS_SELF, NOTIFIED_TIMESTAMP,
|
||||
"json_group_array(json_object(" +
|
||||
"'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " +
|
||||
"'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " +
|
||||
@@ -1794,7 +1795,8 @@ public class MmsDatabase extends MessageDatabase {
|
||||
false,
|
||||
Collections.emptyList(),
|
||||
false,
|
||||
false);
|
||||
false,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1892,6 +1894,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
boolean remoteDelete = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.REMOTE_DELETED)) == 1;
|
||||
List<ReactionRecord> reactions = parseReactions(cursor);
|
||||
boolean mentionsSelf = CursorUtil.requireBoolean(cursor, MENTIONS_SELF);
|
||||
long notifiedTimestamp = CursorUtil.requireLong(cursor, NOTIFIED_TIMESTAMP);
|
||||
|
||||
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
|
||||
readReceiptCount = 0;
|
||||
@@ -1913,7 +1916,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
threadId, body, slideDeck, partCount, box, mismatches,
|
||||
networkFailures, subscriptionId, expiresIn, expireStarted,
|
||||
isViewOnce, readReceiptCount, quote, contacts, previews, unidentified, reactions,
|
||||
remoteDelete, mentionsSelf);
|
||||
remoteDelete, mentionsSelf, notifiedTimestamp);
|
||||
}
|
||||
|
||||
private List<IdentityKeyMismatch> getMismatchedIdentities(String document) {
|
||||
|
@@ -20,6 +20,7 @@ public interface MmsSmsColumns {
|
||||
public static final String EXPIRES_IN = "expires_in";
|
||||
public static final String EXPIRE_STARTED = "expire_started";
|
||||
public static final String NOTIFIED = "notified";
|
||||
public static final String NOTIFIED_TIMESTAMP = "notified_timestamp";
|
||||
public static final String UNIDENTIFIED = "unidentified";
|
||||
public static final String REACTIONS = "reactions";
|
||||
public static final String REACTIONS_UNREAD = "reactions_unread";
|
||||
|
@@ -100,7 +100,8 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsSmsColumns.REACTIONS_UNREAD,
|
||||
MmsSmsColumns.REACTIONS_LAST_SEEN,
|
||||
MmsSmsColumns.REMOTE_DELETED,
|
||||
MmsDatabase.MENTIONS_SELF};
|
||||
MmsDatabase.MENTIONS_SELF,
|
||||
MmsSmsColumns.NOTIFIED_TIMESTAMP};
|
||||
|
||||
public MmsSmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
@@ -466,6 +467,11 @@ public class MmsSmsDatabase extends Database {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setNotifiedTimestamp(long timestamp, @NonNull List<Long> smsIds, @NonNull List<Long> mmsIds) {
|
||||
DatabaseFactory.getSmsDatabase(context).setNotifiedTimestamp(timestamp, smsIds);
|
||||
DatabaseFactory.getMmsDatabase(context).setNotifiedTimestamp(timestamp, mmsIds);
|
||||
}
|
||||
|
||||
public void deleteMessagesInThreadBeforeDate(long threadId, long trimBeforeDate) {
|
||||
Log.d(TAG, "deleteMessagesInThreadBeforeData(" + threadId + ", " + trimBeforeDate + ")");
|
||||
DatabaseFactory.getSmsDatabase(context).deleteMessagesInThreadBeforeDate(threadId, trimBeforeDate);
|
||||
@@ -539,7 +545,8 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsSmsColumns.REACTIONS_LAST_SEEN,
|
||||
MmsSmsColumns.DATE_SERVER,
|
||||
MmsSmsColumns.REMOTE_DELETED,
|
||||
MmsDatabase.MENTIONS_SELF };
|
||||
MmsDatabase.MENTIONS_SELF,
|
||||
MmsSmsColumns.NOTIFIED_TIMESTAMP };
|
||||
|
||||
String[] smsProjection = {SmsDatabase.DATE_SENT + " AS " + MmsSmsColumns.NORMALIZED_DATE_SENT,
|
||||
SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
|
||||
@@ -573,7 +580,8 @@ public class MmsSmsDatabase extends Database {
|
||||
MmsSmsColumns.REACTIONS_LAST_SEEN,
|
||||
MmsSmsColumns.DATE_SERVER,
|
||||
MmsSmsColumns.REMOTE_DELETED,
|
||||
MmsDatabase.MENTIONS_SELF };
|
||||
MmsDatabase.MENTIONS_SELF,
|
||||
MmsSmsColumns.NOTIFIED_TIMESTAMP };
|
||||
|
||||
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
|
||||
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
|
||||
@@ -628,6 +636,7 @@ public class MmsSmsDatabase extends Database {
|
||||
mmsColumnsPresent.add(MmsDatabase.REACTIONS_LAST_SEEN);
|
||||
mmsColumnsPresent.add(MmsDatabase.REMOTE_DELETED);
|
||||
mmsColumnsPresent.add(MmsDatabase.MENTIONS_SELF);
|
||||
mmsColumnsPresent.add(MmsSmsColumns.NOTIFIED_TIMESTAMP);
|
||||
|
||||
Set<String> smsColumnsPresent = new HashSet<>();
|
||||
smsColumnsPresent.add(MmsSmsColumns.ID);
|
||||
@@ -654,6 +663,7 @@ public class MmsSmsDatabase extends Database {
|
||||
smsColumnsPresent.add(SmsDatabase.REACTIONS_UNREAD);
|
||||
smsColumnsPresent.add(SmsDatabase.REACTIONS_LAST_SEEN);
|
||||
smsColumnsPresent.add(MmsDatabase.REMOTE_DELETED);
|
||||
smsColumnsPresent.add(MmsSmsColumns.NOTIFIED_TIMESTAMP);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(TRANSPORT, mmsProjection, mmsColumnsPresent, 4, MMS_TRANSPORT, selection, null, MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID, null);
|
||||
|
@@ -53,6 +53,7 @@ import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.tracing.Trace;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
@@ -118,7 +119,8 @@ public class SmsDatabase extends MessageDatabase {
|
||||
REACTIONS + " BLOB DEFAULT NULL, " +
|
||||
REACTIONS_UNREAD + " INTEGER DEFAULT 0, " +
|
||||
REACTIONS_LAST_SEEN + " INTEGER DEFAULT -1, " +
|
||||
REMOTE_DELETED + " INTEGER DEFAULT 0);";
|
||||
REMOTE_DELETED + " INTEGER DEFAULT 0, " +
|
||||
NOTIFIED_TIMESTAMP + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS sms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");",
|
||||
@@ -140,7 +142,7 @@ public class SmsDatabase extends MessageDatabase {
|
||||
REPLY_PATH_PRESENT, SUBJECT, BODY, SERVICE_CENTER, DELIVERY_RECEIPT_COUNT,
|
||||
MISMATCHED_IDENTITIES, SUBSCRIPTION_ID, EXPIRES_IN, EXPIRE_STARTED,
|
||||
NOTIFIED, READ_RECEIPT_COUNT, UNIDENTIFIED, REACTIONS, REACTIONS_UNREAD, REACTIONS_LAST_SEEN,
|
||||
REMOTE_DELETED
|
||||
REMOTE_DELETED, NOTIFIED_TIMESTAMP
|
||||
};
|
||||
|
||||
private final String OUTGOING_INSECURE_MESSAGE_CLAUSE = "(" + TYPE + " & " + Types.BASE_TYPE_MASK + ") = " + Types.BASE_SENT_TYPE + " AND NOT (" + TYPE + " & " + Types.SECURE_MESSAGE_BIT + ")";
|
||||
@@ -1271,7 +1273,8 @@ public class SmsDatabase extends MessageDatabase {
|
||||
0,
|
||||
false,
|
||||
Collections.emptyList(),
|
||||
false);
|
||||
false,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1317,6 +1320,7 @@ public class SmsDatabase extends MessageDatabase {
|
||||
boolean unidentified = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.UNIDENTIFIED)) == 1;
|
||||
boolean remoteDelete = cursor.getInt(cursor.getColumnIndexOrThrow(SmsDatabase.REMOTE_DELETED)) == 1;
|
||||
List<ReactionRecord> reactions = parseReactions(cursor);
|
||||
long notifiedTimestamp = CursorUtil.requireLong(cursor, NOTIFIED_TIMESTAMP);
|
||||
|
||||
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
|
||||
readReceiptCount = 0;
|
||||
@@ -1331,7 +1335,8 @@ public class SmsDatabase extends MessageDatabase {
|
||||
dateSent, dateReceived, dateServer, deliveryReceiptCount, type,
|
||||
threadId, status, mismatches, subscriptionId,
|
||||
expiresIn, expireStarted,
|
||||
readReceiptCount, unidentified, reactions, remoteDelete);
|
||||
readReceiptCount, unidentified, reactions, remoteDelete,
|
||||
notifiedTimestamp);
|
||||
}
|
||||
|
||||
private List<IdentityKeyMismatch> getMismatches(String document) {
|
||||
|
@@ -64,7 +64,6 @@ import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Triple;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
@@ -159,8 +158,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
private static final int REACTION_CLEANUP = 78;
|
||||
private static final int CAPABILITIES_REFACTOR = 79;
|
||||
private static final int GV1_MIGRATION = 80;
|
||||
private static final int NOTIFIED_TIMESTAMP = 81;
|
||||
|
||||
private static final int DATABASE_VERSION = 80;
|
||||
private static final int DATABASE_VERSION = 81;
|
||||
private static final String DATABASE_NAME = "signal.db";
|
||||
|
||||
private final Context context;
|
||||
@@ -1160,6 +1160,11 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
Log.i(TAG, "Updated " + count + " GV1 groups with expected GV2 IDs.");
|
||||
}
|
||||
|
||||
if (oldVersion < NOTIFIED_TIMESTAMP) {
|
||||
db.execSQL("ALTER TABLE sms ADD COLUMN notified_timestamp INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE mms ADD COLUMN notified_timestamp INTEGER DEFAULT 0");
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
@@ -73,12 +73,13 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
|
||||
boolean unidentified,
|
||||
@NonNull List<ReactionRecord> reactions,
|
||||
boolean remoteDelete,
|
||||
boolean mentionsSelf)
|
||||
boolean mentionsSelf,
|
||||
long notifiedTimestamp)
|
||||
{
|
||||
super(id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent,
|
||||
dateReceived, dateServer, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, mismatches, failures,
|
||||
subscriptionId, expiresIn, expireStarted, viewOnce, slideDeck,
|
||||
readReceiptCount, quote, contacts, linkPreviews, unidentified, reactions, remoteDelete);
|
||||
readReceiptCount, quote, contacts, linkPreviews, unidentified, reactions, remoteDelete, notifiedTimestamp);
|
||||
this.partCount = partCount;
|
||||
this.mentionsSelf = mentionsSelf;
|
||||
}
|
||||
|
@@ -80,6 +80,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
private final List<ReactionRecord> reactions;
|
||||
private final long serverTimestamp;
|
||||
private final boolean remoteDelete;
|
||||
private final long notifiedTimestamp;
|
||||
|
||||
MessageRecord(long id, String body, Recipient conversationRecipient,
|
||||
Recipient individualRecipient, int recipientDeviceId,
|
||||
@@ -89,7 +90,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
List<NetworkFailure> networkFailures,
|
||||
int subscriptionId, long expiresIn, long expireStarted,
|
||||
int readReceiptCount, boolean unidentified,
|
||||
@NonNull List<ReactionRecord> reactions, boolean remoteDelete)
|
||||
@NonNull List<ReactionRecord> reactions, boolean remoteDelete, long notifiedTimestamp)
|
||||
{
|
||||
super(body, conversationRecipient, dateSent, dateReceived,
|
||||
threadId, deliveryStatus, deliveryReceiptCount, type, readReceiptCount);
|
||||
@@ -105,6 +106,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
this.reactions = reactions;
|
||||
this.serverTimestamp = dateServer;
|
||||
this.remoteDelete = remoteDelete;
|
||||
this.notifiedTimestamp = notifiedTimestamp;
|
||||
}
|
||||
|
||||
public abstract boolean isMms();
|
||||
@@ -455,6 +457,10 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return false;
|
||||
}
|
||||
|
||||
public long getNotifiedTimestamp() {
|
||||
return notifiedTimestamp;
|
||||
}
|
||||
|
||||
public static final class InviteAddState {
|
||||
|
||||
private final boolean invited;
|
||||
|
@@ -33,9 +33,9 @@ public abstract class MmsMessageRecord extends MessageRecord {
|
||||
@NonNull SlideDeck slideDeck, int readReceiptCount,
|
||||
@Nullable Quote quote, @NonNull List<Contact> contacts,
|
||||
@NonNull List<LinkPreview> linkPreviews, boolean unidentified,
|
||||
@NonNull List<ReactionRecord> reactions, boolean remoteDelete)
|
||||
@NonNull List<ReactionRecord> reactions, boolean remoteDelete, long notifiedTimestamp)
|
||||
{
|
||||
super(id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, dateServer, threadId, deliveryStatus, deliveryReceiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete);
|
||||
super(id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, dateServer, threadId, deliveryStatus, deliveryReceiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete, notifiedTimestamp);
|
||||
|
||||
this.slideDeck = slideDeck;
|
||||
this.quote = quote;
|
||||
|
@@ -23,8 +23,6 @@ import android.text.SpannableString;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase.Status;
|
||||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
@@ -58,7 +56,7 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord {
|
||||
dateSent, dateReceived, -1, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox,
|
||||
new LinkedList<>(), new LinkedList<>(), subscriptionId,
|
||||
0, 0, false, slideDeck, readReceiptCount, null, Collections.emptyList(), Collections.emptyList(), false,
|
||||
Collections.emptyList(), false);
|
||||
Collections.emptyList(), false, 0);
|
||||
|
||||
this.contentLocation = contentLocation;
|
||||
this.messageSize = messageSize;
|
||||
|
@@ -49,12 +49,13 @@ public class SmsMessageRecord extends MessageRecord {
|
||||
int status, List<IdentityKeyMismatch> mismatches,
|
||||
int subscriptionId, long expiresIn, long expireStarted,
|
||||
int readReceiptCount, boolean unidentified,
|
||||
@NonNull List<ReactionRecord> reactions, boolean remoteDelete)
|
||||
@NonNull List<ReactionRecord> reactions, boolean remoteDelete,
|
||||
long notifiedTimestamp)
|
||||
{
|
||||
super(id, body, recipient, individualRecipient, recipientDeviceId,
|
||||
dateSent, dateReceived, dateServer, threadId, status, deliveryReceiptCount, type,
|
||||
mismatches, new LinkedList<>(), subscriptionId,
|
||||
expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete);
|
||||
expiresIn, expireStarted, readReceiptCount, unidentified, reactions, remoteDelete, notifiedTimestamp);
|
||||
}
|
||||
|
||||
public long getType() {
|
||||
|
@@ -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