Implement group story notifications.

This commit is contained in:
Alex Hart
2022-05-12 15:37:28 -03:00
committed by Cody Henthorne
parent 01543dd52b
commit a03c49e12c
66 changed files with 865 additions and 473 deletions

View File

@@ -197,6 +197,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
public abstract @NonNull List<RecipientId> getUnreadStoryThreadRecipientIds();
public abstract boolean containsStories(long threadId);
public abstract boolean hasSelfReplyInStory(long parentStoryId);
public abstract boolean hasSelfReplyInGroupStory(long parentStoryId);
public abstract @NonNull Cursor getStoryReplies(long parentStoryId);
public abstract @Nullable Long getOldestStorySendTimestamp();
public abstract int deleteStoriesOlderThan(long timestamp);
@@ -204,6 +205,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
public abstract @Nullable ParentStoryId.GroupReply getParentStoryIdForGroupReply(long messageId);
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 StoryViewState getStoryViewState(@NonNull RecipientId recipientId);
public abstract void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds);

View File

@@ -801,7 +801,7 @@ public class MmsDatabase extends MessageDatabase {
String where = PARENT_STORY_ID + " = ?";
String[] whereArgs = SqlUtil.buildArgs(parentStoryId);
return rawQuery(where, whereArgs, true, 0);
return rawQuery(where, whereArgs, false, 0);
}
@Override
@@ -840,6 +840,18 @@ public class MmsDatabase extends MessageDatabase {
}
}
@Override
public boolean hasSelfReplyInGroupStory(long parentStoryId) {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
String[] columns = new String[]{"COUNT(*)"};
String where = PARENT_STORY_ID + " = ? AND (" + getOutgoingTypeClause() + ")";
String[] whereArgs = SqlUtil.buildArgs(parentStoryId);
try (Cursor cursor = db.query(TABLE_NAME, columns, where, whereArgs, null, null, null, null)) {
return cursor != null && cursor.moveToNext() && cursor.getInt(0) > 0;
}
}
@Override
public @Nullable Long getOldestStorySendTimestamp() {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
@@ -1381,6 +1393,15 @@ public class MmsDatabase extends MessageDatabase {
}
}
@Override
public @NonNull List<MarkedMessageInfo> setGroupStoryMessagesReadSince(long threadId, long groupStoryId, long sinceTimestamp) {
if (sinceTimestamp == -1) {
return setMessagesRead(THREAD_ID + " = ? AND " + STORY_TYPE + " = 0 AND " + PARENT_STORY_ID + " = ? AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND (" + getOutgoingTypeClause() + ")))", SqlUtil.buildArgs(threadId, groupStoryId));
} else {
return setMessagesRead(THREAD_ID + " = ? AND " + STORY_TYPE + " = 0 AND " + PARENT_STORY_ID + " = ? AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND ( " + getOutgoingTypeClause() + " ))) AND " + DATE_RECEIVED + " <= ?", SqlUtil.buildArgs(threadId, groupStoryId, sinceTimestamp));
}
}
@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)});

View File

@@ -32,7 +32,6 @@ import org.signal.libsignal.protocol.util.Pair;
import org.thoughtcrime.securesms.database.MessageDatabase.MessageUpdate;
import org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.StoryViewState;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.notifications.v2.MessageNotifierV2;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -259,12 +258,12 @@ public class MmsSmsDatabase extends Database {
}
stickyQuery.append("(")
.append(MmsSmsColumns.THREAD_ID + " = ")
.append(stickyThread.getNotificationThread().getThreadId())
.append(stickyThread.getConversationId().getThreadId())
.append(" AND ")
.append(MmsSmsColumns.NORMALIZED_DATE_RECEIVED)
.append(" >= ")
.append(stickyThread.getEarliestTimestamp())
.append(getStickyWherePartForParentStoryId(stickyThread.getNotificationThread().getGroupStoryId()))
.append(getStickyWherePartForParentStoryId(stickyThread.getConversationId().getGroupStoryId()))
.append(")");
}
@@ -654,6 +653,11 @@ public class MmsSmsDatabase extends Database {
return SignalDatabase.sms().hasReceivedAnyCallsSince(threadId, timestamp);
}
public int getMessagePositionInConversation(long threadId, long receivedTimestamp) {
return getMessagePositionInConversation(threadId, 0, receivedTimestamp);
}
/**
* Retrieves the position of the message with the provided timestamp in the query results you'd
* get from calling {@link #getConversation(long)}.
@@ -661,12 +665,24 @@ public class MmsSmsDatabase extends Database {
* Note: This could give back incorrect results in the situation where multiple messages have the
* same received timestamp. However, because this was designed to determine where to scroll to,
* you'll still wind up in about the right spot.
*
* @param groupStoryId Ignored if passed value is <= 0
*/
public int getMessagePositionInConversation(long threadId, long receivedTimestamp) {
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " > " + receivedTimestamp + " AND " +
MmsDatabase.STORY_TYPE + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " <= 0";
public int getMessagePositionInConversation(long threadId, long groupStoryId, long receivedTimestamp) {
final String order;
final String selection;
if (groupStoryId > 0) {
order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " < " + receivedTimestamp + " AND " +
MmsDatabase.STORY_TYPE + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " = " + groupStoryId;
} else {
order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " > " + receivedTimestamp + " AND " +
MmsDatabase.STORY_TYPE + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " <= 0";
}
try (Cursor cursor = queryTables(new String[]{ "COUNT(*)" }, selection, order, null, false)) {
if (cursor != null && cursor.moveToFirst()) {

View File

@@ -1446,6 +1446,11 @@ public class SmsDatabase extends MessageDatabase {
throw new UnsupportedOperationException();
}
@Override
public boolean hasSelfReplyInGroupStory(long parentStoryId) {
throw new UnsupportedOperationException();
}
@Override
public @NonNull Cursor getStoryReplies(long parentStoryId) {
throw new UnsupportedOperationException();
@@ -1481,6 +1486,11 @@ public class SmsDatabase extends MessageDatabase {
throw new UnsupportedOperationException();
}
@Override
public @NonNull List<MarkedMessageInfo> setGroupStoryMessagesReadSince(long threadId, long groupStoryId, long sinceTimestamp) {
throw new UnsupportedOperationException();
}
@Override
public void deleteGroupStoryReplies(long parentStoryId) {
throw new UnsupportedOperationException();

View File

@@ -31,6 +31,8 @@ import com.annimon.stream.Stream;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jsoup.helper.StringUtil;
import org.signal.core.util.CursorUtil;
import org.signal.core.util.SqlUtil;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
@@ -46,15 +48,14 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.mms.StickerSlide;
import org.thoughtcrime.securesms.notifications.v2.ConversationId;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientDetails;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
import org.thoughtcrime.securesms.util.ConversationUtil;
import org.signal.core.util.CursorUtil;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.signal.core.util.SqlUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.api.push.ServiceId;
@@ -402,6 +403,22 @@ public class ThreadDatabase extends Database {
return setReadSince(Collections.singletonMap(threadId, -1L), lastSeen);
}
public List<MarkedMessageInfo> setRead(@NonNull ConversationId conversationId, boolean lastSeen) {
if (conversationId.getGroupStoryId() == null) {
return setRead(conversationId.getThreadId(), lastSeen);
} else {
return setGroupStoryReadSince(conversationId.getThreadId(), conversationId.getGroupStoryId(), System.currentTimeMillis());
}
}
public List<MarkedMessageInfo> setReadSince(@NonNull ConversationId conversationId, boolean lastSeen, long sinceTimestamp) {
if (conversationId.getGroupStoryId() != null) {
return setGroupStoryReadSince(conversationId.getThreadId(), conversationId.getGroupStoryId(), sinceTimestamp);
} else {
return setReadSince(conversationId.getThreadId(), lastSeen, sinceTimestamp);
}
}
public List<MarkedMessageInfo> setReadSince(long threadId, boolean lastSeen, long sinceTimestamp) {
return setReadSince(Collections.singletonMap(threadId, sinceTimestamp), lastSeen);
}
@@ -410,6 +427,10 @@ public class ThreadDatabase extends Database {
return setReadSince(Stream.of(threadIds).collect(Collectors.toMap(t -> t, t -> -1L)), lastSeen);
}
public List<MarkedMessageInfo> setGroupStoryReadSince(long threadId, long groupStoryId, long sinceTimestamp) {
return SignalDatabase.mms().setGroupStoryMessagesReadSince(threadId, groupStoryId, sinceTimestamp);
}
public List<MarkedMessageInfo> setReadSince(Map<Long, Long> threadIdToSinceTimestamp, boolean lastSeen) {
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
@@ -1252,7 +1273,7 @@ public class ThreadDatabase extends Database {
pinnedPosition++;
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();