Add support for smarter story downloads.

This commit is contained in:
Alex Hart
2022-04-21 17:29:02 -03:00
committed by Cody Henthorne
parent c4bc2162f2
commit 17111abc72
13 changed files with 125 additions and 15 deletions

View File

@@ -195,7 +195,10 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
public abstract @NonNull Cursor getStoryReplies(long parentStoryId);
public abstract @Nullable Long getOldestStorySendTimestamp();
public abstract int deleteStoriesOlderThan(long timestamp);
public abstract @NonNull MessageDatabase.Reader getUnreadStories(@NonNull RecipientId recipientId, int limit);
public abstract @NonNull StoryViewState getStoryViewState(@NonNull RecipientId recipientId);
public abstract void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds);
final @NonNull String getOutgoingTypeClause() {
List<String> segments = new ArrayList<>(Types.OUTGOING_MESSAGE_TYPES.length);

View File

@@ -590,6 +590,17 @@ public class MmsDatabase extends MessageDatabase {
return new Reader(cursor);
}
@Override
public @NonNull MessageDatabase.Reader getUnreadStories(@NonNull RecipientId recipientId, int limit) {
final String query = IS_STORY_CLAUSE +
" AND NOT (" + getOutgoingTypeClause() + ") " +
" AND " + RECIPIENT_ID + " = ?" +
" AND " + VIEWED_RECEIPT_COUNT + " = ?";
final String[] args = SqlUtil.buildArgs(recipientId, 0);
return new Reader(rawQuery(query, args, false, limit));
}
@Override
public @NonNull StoryViewState getStoryViewState(@NonNull RecipientId recipientId) {
if (!Stories.isFeatureEnabled()) {
@@ -601,6 +612,28 @@ public class MmsDatabase extends MessageDatabase {
return getStoryViewState(threadId);
}
/**
* Synchronizes whether we've viewed a recipient's story based on incoming sync messages.
*/
public void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds) {
final String timestamps = Util.join(syncMessageIds.stream().map(SyncMessageId::getTimetamp).collect(java.util.stream.Collectors.toList()), ",");
final String[] projection = SqlUtil.buildArgs(RECIPIENT_ID);
final String where = IS_STORY_CLAUSE + " AND " + NORMALIZED_DATE_SENT + " IN (" + timestamps + ") AND NOT (" + getOutgoingTypeClause() + ") AND " + VIEWED_RECEIPT_COUNT + " > 0";
try {
getWritableDatabase().beginTransaction();
try (Cursor cursor = getWritableDatabase().query(TABLE_NAME, projection, where, null, null, null, null)) {
while (cursor != null && cursor.moveToNext()) {
Recipient recipient = Recipient.resolved(RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID)));
SignalDatabase.recipients().updateLastStoryViewTimestamp(recipient.getId());
}
}
getWritableDatabase().setTransactionSuccessful();
} finally {
getWritableDatabase().endTransaction();
}
}
@VisibleForTesting
@NonNull StoryViewState getStoryViewState(long threadId) {
final String hasStoryQuery = "SELECT EXISTS(SELECT 1 FROM " + TABLE_NAME + " WHERE " + IS_STORY_CLAUSE + " AND " + THREAD_ID_WHERE + " LIMIT 1)";

View File

@@ -32,6 +32,7 @@ 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;
@@ -529,6 +530,9 @@ public class MmsSmsDatabase extends Database {
return SignalDatabase.mms().incrementReceiptCount(syncMessageId, timestamp, receiptType, true);
}
public void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds) {
SignalDatabase.mms().updateViewedStories(syncMessageIds);
}
public void setTimestampRead(@NonNull Recipient senderRecipient, @NonNull List<ReadMessage> readMessages, long proposedExpireStarted, @NonNull Map<Long, Long> threadToLatestRead) {
SQLiteDatabase db = getWritableDatabase();

View File

@@ -1964,6 +1964,10 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
StorageSyncHelper.scheduleSyncForDataChange()
}
fun updateLastStoryViewTimestamp(id: RecipientId) {
updateExtras(id) { it.setLastStoryView(System.currentTimeMillis()) }
}
fun clearUsernameIfExists(username: String) {
val existingUsername = getByUsername(username)
if (existingUsername.isPresent) {

View File

@@ -1451,11 +1451,21 @@ public class SmsDatabase extends MessageDatabase {
throw new UnsupportedOperationException();
}
@Override
public void updateViewedStories(@NonNull Set<SyncMessageId> syncMessageIds) {
throw new UnsupportedOperationException();
}
@Override
public int deleteStoriesOlderThan(long timestamp) {
throw new UnsupportedOperationException();
}
@Override
public @NonNull MessageDatabase.Reader getUnreadStories(@NonNull RecipientId recipientId, int limit) {
throw new UnsupportedOperationException();
}
@Override
public MessageRecord getMessageRecord(long messageId) throws NoSuchMessageException {
return getSmsMessage(messageId);