mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Add support for separate story view receipt control.
This reverts commit 1046265d23.
This commit is contained in:
committed by
Cody Henthorne
parent
2f2711c9a3
commit
ca36eaacce
@@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StoryResult;
|
||||
import org.thoughtcrime.securesms.database.model.StoryType;
|
||||
import org.thoughtcrime.securesms.database.model.StoryViewState;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExportState;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.ThreadMergeEvent;
|
||||
@@ -135,7 +136,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns,
|
||||
public abstract void markGiftRedemptionStarted(long messageId);
|
||||
public abstract void markGiftRedemptionFailed(long messageId);
|
||||
|
||||
public abstract Set<MessageUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType, boolean storiesOnly);
|
||||
public abstract Set<MessageUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType, @NonNull MessageQualifier messageType);
|
||||
|
||||
public abstract List<MarkedMessageInfo> setEntireThreadRead(long threadId);
|
||||
public abstract List<MarkedMessageInfo> setMessagesReadSince(long threadId, long timestamp);
|
||||
@@ -218,6 +219,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns,
|
||||
public abstract void deleteGroupStoryReplies(long parentStoryId);
|
||||
public abstract boolean isOutgoingStoryAlreadyInDatabase(@NonNull RecipientId recipientId, long sentTimestamp);
|
||||
public abstract @NonNull List<MarkedMessageInfo> setGroupStoryMessagesReadSince(long threadId, long groupStoryId, long sinceTimestamp);
|
||||
public abstract @NonNull List<StoryType> getStoryTypes(@NonNull List<MessageId> messageIds);
|
||||
|
||||
public abstract @NonNull StoryViewState getStoryViewState(@NonNull RecipientId recipientId);
|
||||
public abstract void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds);
|
||||
@@ -920,4 +922,23 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns,
|
||||
return dateReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes which messages to act on. This is used when incrementing receipts.
|
||||
* Specifically, this was added to support stories having separate viewed receipt settings.
|
||||
*/
|
||||
public enum MessageQualifier {
|
||||
/**
|
||||
* A normal database message (i.e. not a story)
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* A story message
|
||||
*/
|
||||
STORY,
|
||||
/**
|
||||
* Both normal and story message
|
||||
*/
|
||||
ALL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
@Override
|
||||
public @NonNull List<MarkedMessageInfo> getViewedIncomingMessages(long threadId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String[] columns = new String[]{ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, THREAD_ID};
|
||||
String[] columns = new String[]{ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, THREAD_ID, STORY_TYPE};
|
||||
String where = THREAD_ID + " = ? AND " + VIEWED_RECEIPT_COUNT + " > 0 AND " + MESSAGE_BOX + " & " + Types.BASE_INBOX_TYPE + " = " + Types.BASE_INBOX_TYPE;
|
||||
String[] args = SqlUtil.buildArgs(threadId);
|
||||
|
||||
@@ -395,6 +395,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
RecipientId recipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
|
||||
long dateSent = CursorUtil.requireLong(cursor, DATE_SENT);
|
||||
SyncMessageId syncMessageId = new SyncMessageId(recipientId, dateSent);
|
||||
StoryType storyType = StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE));
|
||||
|
||||
results.add(new MarkedMessageInfo(threadId, syncMessageId, new MessageId(messageId, true), null));
|
||||
}
|
||||
@@ -421,7 +422,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
}
|
||||
|
||||
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
|
||||
String[] columns = new String[]{ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, THREAD_ID};
|
||||
String[] columns = new String[]{ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, THREAD_ID, STORY_TYPE};
|
||||
String where = ID + " IN (" + Util.join(messageIds, ",") + ") AND " + VIEWED_RECEIPT_COUNT + " = 0";
|
||||
List<MarkedMessageInfo> results = new LinkedList<>();
|
||||
|
||||
@@ -435,6 +436,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
RecipientId recipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
|
||||
long dateSent = CursorUtil.requireLong(cursor, DATE_SENT);
|
||||
SyncMessageId syncMessageId = new SyncMessageId(recipientId, dateSent);
|
||||
StoryType storyType = StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE));
|
||||
|
||||
results.add(new MarkedMessageInfo(threadId, syncMessageId, new MessageId(messageId, true), null));
|
||||
|
||||
@@ -463,7 +465,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
@Override
|
||||
public @NonNull List<MarkedMessageInfo>
|
||||
setOutgoingGiftsRevealed(@NonNull List<Long> messageIds) {
|
||||
String[] projection = SqlUtil.buildArgs(ID, RECIPIENT_ID, DATE_SENT, THREAD_ID);
|
||||
String[] projection = SqlUtil.buildArgs(ID, RECIPIENT_ID, DATE_SENT, THREAD_ID, STORY_TYPE);
|
||||
String where = ID + " IN (" + Util.join(messageIds, ",") + ") AND (" + getOutgoingTypeClause() + ") AND (" + getTypeField() + " & " + Types.SPECIAL_TYPES_MASK + " = " + Types.SPECIAL_TYPE_GIFT_BADGE + ") AND " + VIEWED_RECEIPT_COUNT + " = 0";
|
||||
List<MarkedMessageInfo> results = new LinkedList<>();
|
||||
|
||||
@@ -475,6 +477,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
RecipientId recipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID));
|
||||
long dateSent = CursorUtil.requireLong(cursor, DATE_SENT);
|
||||
SyncMessageId syncMessageId = new SyncMessageId(recipientId, dateSent);
|
||||
StoryType storyType = StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE));
|
||||
|
||||
results.add(new MarkedMessageInfo(threadId, syncMessageId, new MessageId(messageId, true), null));
|
||||
|
||||
@@ -1122,13 +1125,28 @@ public class MmsDatabase extends MessageDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<MessageUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType, boolean storiesOnly) {
|
||||
public Set<MessageUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType, MessageQualifier messageQualifier) {
|
||||
SQLiteDatabase database = databaseHelper.getSignalWritableDatabase();
|
||||
Set<MessageUpdate> messageUpdates = new HashSet<>();
|
||||
|
||||
final String qualifierWhere;
|
||||
switch (messageQualifier) {
|
||||
case NORMAL:
|
||||
qualifierWhere = " AND NOT (" + IS_STORY_CLAUSE + ")";
|
||||
break;
|
||||
case STORY:
|
||||
qualifierWhere = " AND " + IS_STORY_CLAUSE;
|
||||
break;
|
||||
case ALL:
|
||||
qualifierWhere = "";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported qualifier: " + messageQualifier);
|
||||
}
|
||||
|
||||
try (Cursor cursor = SQLiteDatabaseExtensionsKt.select(database, ID, THREAD_ID, MESSAGE_BOX, RECIPIENT_ID, receiptType.getColumnName(), RECEIPT_TIMESTAMP)
|
||||
.from(TABLE_NAME)
|
||||
.where(DATE_SENT + " = ?" + (storiesOnly ? " AND " + IS_STORY_CLAUSE : ""), messageId.getTimetamp())
|
||||
.where(DATE_SENT + " = ?" + qualifierWhere, messageId.getTimetamp())
|
||||
.run())
|
||||
{
|
||||
while (cursor.moveToNext()) {
|
||||
@@ -1509,6 +1527,38 @@ public class MmsDatabase extends MessageDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull List<StoryType> getStoryTypes(@NonNull List<MessageId> messageIds) {
|
||||
List<Long> mmsMessages = messageIds.stream()
|
||||
.filter(MessageId::isMms)
|
||||
.map(MessageId::getId)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
|
||||
if (mmsMessages.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
String[] projection = SqlUtil.buildArgs(ID, STORY_TYPE);
|
||||
List<SqlUtil.Query> queries = SqlUtil.buildCollectionQuery(ID, mmsMessages);
|
||||
HashMap<Long, StoryType> storyTypes = new HashMap<>();
|
||||
|
||||
for (final SqlUtil.Query query : queries) {
|
||||
try (Cursor cursor = getWritableDatabase().query(TABLE_NAME, projection, query.getWhere(), query.getWhereArgs(), null, null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
storyTypes.put(CursorUtil.requireLong(cursor, ID), StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return messageIds.stream().map(id -> {
|
||||
if (id.isMms() && storyTypes.containsKey(id.getId())) {
|
||||
return storyTypes.get(id.getId());
|
||||
} else {
|
||||
return StoryType.NONE;
|
||||
}
|
||||
}).collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MarkedMessageInfo> setEntireThreadRead(long threadId) {
|
||||
return setMessagesRead(THREAD_ID + " = ? AND " + STORY_TYPE + " = 0 AND " + PARENT_STORY_ID + " <= 0", new String[] { String.valueOf(threadId)});
|
||||
@@ -1528,7 +1578,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
database.beginTransaction();
|
||||
|
||||
try {
|
||||
cursor = database.query(TABLE_NAME, new String[] {ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID }, where, arguments, null, null, null);
|
||||
cursor = database.query(TABLE_NAME, new String[] {ID, RECIPIENT_ID, DATE_SENT, MESSAGE_BOX, EXPIRES_IN, EXPIRE_STARTED, THREAD_ID, STORY_TYPE }, where, arguments, null, null, null);
|
||||
|
||||
while(cursor != null && cursor.moveToNext()) {
|
||||
if (Types.isSecureType(CursorUtil.requireLong(cursor, MESSAGE_BOX))) {
|
||||
@@ -1540,6 +1590,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
long expireStarted = CursorUtil.requireLong(cursor, EXPIRE_STARTED);
|
||||
SyncMessageId syncMessageId = new SyncMessageId(recipientId, dateSent);
|
||||
ExpirationInfo expirationInfo = new ExpirationInfo(messageId, expiresIn, expireStarted, true);
|
||||
StoryType storyType = StoryType.fromCode(CursorUtil.requireInt(cursor, STORY_TYPE));
|
||||
|
||||
if (!recipientId.equals(releaseChannelId)) {
|
||||
result.add(new MarkedMessageInfo(threadId, syncMessageId, new MessageId(messageId, true), expirationInfo));
|
||||
|
||||
@@ -493,6 +493,10 @@ public class MmsSmsDatabase extends Database {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, MessageDatabase.ReceiptType.VIEWED);
|
||||
}
|
||||
|
||||
public @NonNull Collection<SyncMessageId> incrementViewedNonStoryReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp) {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, MessageDatabase.ReceiptType.VIEWED, MessageDatabase.MessageQualifier.NORMAL);
|
||||
}
|
||||
|
||||
public boolean incrementViewedReceiptCount(SyncMessageId syncMessageId, long timestamp) {
|
||||
return incrementReceiptCount(syncMessageId, timestamp, MessageDatabase.ReceiptType.VIEWED);
|
||||
}
|
||||
@@ -505,7 +509,7 @@ public class MmsSmsDatabase extends Database {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (SyncMessageId id : syncMessageIds) {
|
||||
Set<MessageUpdate> updates = incrementStoryReceiptCountInternal(id, timestamp, MessageDatabase.ReceiptType.VIEWED);
|
||||
Set<MessageUpdate> updates = incrementReceiptCountInternal(id, timestamp, MessageDatabase.ReceiptType.VIEWED, MessageDatabase.MessageQualifier.STORY);
|
||||
|
||||
if (updates.size() > 0) {
|
||||
messageUpdates.addAll(updates);
|
||||
@@ -537,13 +541,17 @@ public class MmsSmsDatabase extends Database {
|
||||
* @return Whether or not some thread was updated.
|
||||
*/
|
||||
private boolean incrementReceiptCount(SyncMessageId syncMessageId, long timestamp, @NonNull MessageDatabase.ReceiptType receiptType) {
|
||||
return incrementReceiptCount(syncMessageId, timestamp, receiptType, MessageDatabase.MessageQualifier.ALL);
|
||||
}
|
||||
|
||||
private boolean incrementReceiptCount(SyncMessageId syncMessageId, long timestamp, @NonNull MessageDatabase.ReceiptType receiptType, @NonNull MessageDatabase.MessageQualifier messageQualifier) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
ThreadDatabase threadDatabase = SignalDatabase.threads();
|
||||
Set<MessageUpdate> messageUpdates = new HashSet<>();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
messageUpdates = incrementReceiptCountInternal(syncMessageId, timestamp, receiptType);
|
||||
messageUpdates = incrementReceiptCountInternal(syncMessageId, timestamp, receiptType, messageQualifier);
|
||||
|
||||
for (MessageUpdate messageUpdate : messageUpdates) {
|
||||
threadDatabase.update(messageUpdate.getThreadId(), false);
|
||||
@@ -567,6 +575,10 @@ public class MmsSmsDatabase extends Database {
|
||||
* @return All of the messages that didn't result in updates.
|
||||
*/
|
||||
private @NonNull Collection<SyncMessageId> incrementReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp, @NonNull MessageDatabase.ReceiptType receiptType) {
|
||||
return incrementReceiptCounts(syncMessageIds, timestamp, receiptType, MessageDatabase.MessageQualifier.ALL);
|
||||
}
|
||||
|
||||
private @NonNull Collection<SyncMessageId> incrementReceiptCounts(@NonNull List<SyncMessageId> syncMessageIds, long timestamp, @NonNull MessageDatabase.ReceiptType receiptType, @NonNull MessageDatabase.MessageQualifier messageQualifier) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
ThreadDatabase threadDatabase = SignalDatabase.threads();
|
||||
Set<MessageUpdate> messageUpdates = new HashSet<>();
|
||||
@@ -575,7 +587,7 @@ public class MmsSmsDatabase extends Database {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (SyncMessageId id : syncMessageIds) {
|
||||
Set<MessageUpdate> updates = incrementReceiptCountInternal(id, timestamp, receiptType);
|
||||
Set<MessageUpdate> updates = incrementReceiptCountInternal(id, timestamp, receiptType, messageQualifier);
|
||||
|
||||
if (updates.size() > 0) {
|
||||
messageUpdates.addAll(updates);
|
||||
@@ -609,22 +621,15 @@ public class MmsSmsDatabase extends Database {
|
||||
/**
|
||||
* Doesn't do any transactions or updates, so we can re-use the method safely.
|
||||
*/
|
||||
private @NonNull Set<MessageUpdate> incrementReceiptCountInternal(SyncMessageId syncMessageId, long timestamp, MessageDatabase.ReceiptType receiptType) {
|
||||
private @NonNull Set<MessageUpdate> incrementReceiptCountInternal(SyncMessageId syncMessageId, long timestamp, MessageDatabase.ReceiptType receiptType, @NonNull MessageDatabase.MessageQualifier messageQualifier) {
|
||||
Set<MessageUpdate> messageUpdates = new HashSet<>();
|
||||
|
||||
messageUpdates.addAll(SignalDatabase.sms().incrementReceiptCount(syncMessageId, timestamp, receiptType, false));
|
||||
messageUpdates.addAll(SignalDatabase.mms().incrementReceiptCount(syncMessageId, timestamp, receiptType, false));
|
||||
messageUpdates.addAll(SignalDatabase.sms().incrementReceiptCount(syncMessageId, timestamp, receiptType, messageQualifier));
|
||||
messageUpdates.addAll(SignalDatabase.mms().incrementReceiptCount(syncMessageId, timestamp, receiptType, messageQualifier));
|
||||
|
||||
return messageUpdates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Doesn't do any transactions or updates, so we can re-use the method safely.
|
||||
*/
|
||||
private @NonNull Set<MessageUpdate> incrementStoryReceiptCountInternal(@NonNull SyncMessageId syncMessageId, long timestamp, @NonNull MessageDatabase.ReceiptType receiptType) {
|
||||
return SignalDatabase.mms().incrementReceiptCount(syncMessageId, timestamp, receiptType, true);
|
||||
}
|
||||
|
||||
public void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds) {
|
||||
SignalDatabase.mms().updateViewedStories(syncMessageIds);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StoryResult;
|
||||
import org.thoughtcrime.securesms.database.model.StoryType;
|
||||
import org.thoughtcrime.securesms.database.model.StoryViewState;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.GroupCallUpdateDetails;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExportState;
|
||||
@@ -515,7 +516,11 @@ public class SmsDatabase extends MessageDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Set<MessageUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType, boolean storiesOnly) {
|
||||
public @NonNull Set<MessageUpdate> incrementReceiptCount(SyncMessageId messageId, long timestamp, @NonNull ReceiptType receiptType, @NonNull MessageQualifier messageQualifier) {
|
||||
if (messageQualifier == MessageQualifier.STORY) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
if (receiptType == ReceiptType.VIEWED) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
@@ -1567,6 +1572,11 @@ public class SmsDatabase extends MessageDatabase {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull List<StoryType> getStoryTypes(@NonNull List<MessageId> messageIds) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteGroupStoryReplies(long parentStoryId) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
Reference in New Issue
Block a user