diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt index def88b685f..119e2971ac 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SignalDatabase.kt @@ -132,7 +132,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data executeStatements(db, GroupCallRingDatabase.CREATE_INDEXES) executeStatements(db, NotificationProfileDatabase.CREATE_INDEXES) executeStatements(db, DonationReceiptDatabase.CREATE_INDEXS) - db.execSQL(StorySendsDatabase.CREATE_INDEX) + executeStatements(db, StorySendsDatabase.CREATE_INDEXS) executeStatements(db, DistributionListDatabase.CREATE_INDEXES) executeStatements(db, PendingPniSignatureMessageDatabase.CREATE_INDEXES) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/StorySendsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/StorySendsDatabase.kt index 079c61534c..5ffdbf4ca3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/StorySendsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/StorySendsDatabase.kt @@ -5,6 +5,7 @@ import android.content.Context import androidx.core.content.contentValuesOf import org.signal.core.util.CursorUtil import org.signal.core.util.SqlUtil +import org.signal.core.util.readToList import org.signal.core.util.requireLong import org.signal.core.util.select import org.signal.core.util.toInt @@ -43,9 +44,10 @@ class StorySendsDatabase(context: Context, databaseHelper: SignalDatabase) : Dat ) """.trimIndent() - val CREATE_INDEX = """ - CREATE INDEX story_sends_recipient_id_sent_timestamp_allows_replies_index ON $TABLE_NAME ($RECIPIENT_ID, $SENT_TIMESTAMP, $ALLOWS_REPLIES) - """.trimIndent() + val CREATE_INDEXS = arrayOf( + "CREATE INDEX story_sends_recipient_id_sent_timestamp_allows_replies_index ON $TABLE_NAME ($RECIPIENT_ID, $SENT_TIMESTAMP, $ALLOWS_REPLIES)", + "CREATE INDEX story_sends_message_id_distribution_id_index ON $TABLE_NAME ($MESSAGE_ID, $DISTRIBUTION_ID)", + ) } fun insert(messageId: Long, recipientIds: Collection, sentTimestamp: Long, allowsReplies: Boolean, distributionId: DistributionId) { @@ -72,6 +74,18 @@ class StorySendsDatabase(context: Context, databaseHelper: SignalDatabase) : Dat } } + fun getRecipientsForDistributionId(messageId: Long, distributionId: DistributionId): Set { + return readableDatabase + .select(RECIPIENT_ID) + .from(TABLE_NAME) + .where("$MESSAGE_ID = ? AND $DISTRIBUTION_ID = ?", messageId, distributionId.toString()) + .run() + .readToList { cursor -> + RecipientId.from(cursor.requireLong(RECIPIENT_ID)) + } + .toSet() + } + fun getRecipientsToSendTo(messageId: Long, sentTimestamp: Long, allowsReplies: Boolean): List { val recipientIds = mutableListOf() diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt index 9407834430..17971f4c35 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt @@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V157_RecipeintHidde import org.thoughtcrime.securesms.database.helpers.migration.V158_GroupsLastForceUpdateTimestampMigration import org.thoughtcrime.securesms.database.helpers.migration.V159_ThreadUnreadSelfMentionCount import org.thoughtcrime.securesms.database.helpers.migration.V160_SmsMmsExportedIndexMigration +import org.thoughtcrime.securesms.database.helpers.migration.V161_StorySendMessageIdIndex /** * Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. @@ -72,6 +73,10 @@ object SignalDatabaseMigrations { if (oldVersion < 160) { V160_SmsMmsExportedIndexMigration.migrate(context, db, oldVersion, newVersion) } + + if (oldVersion < 161) { + V161_StorySendMessageIdIndex.migrate(context, db, oldVersion, newVersion) + } } @JvmStatic diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V161_StorySendMessageIdIndex.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V161_StorySendMessageIdIndex.kt new file mode 100644 index 0000000000..e872f4d850 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V161_StorySendMessageIdIndex.kt @@ -0,0 +1,13 @@ +package org.thoughtcrime.securesms.database.helpers.migration + +import android.app.Application +import net.zetetic.database.sqlcipher.SQLiteDatabase + +/** + * Adds an index to the story sends table to help with a new common query. + */ +object V161_StorySendMessageIdIndex : SignalDatabaseMigration { + override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + db.execSQL("CREATE INDEX story_sends_message_id_distribution_id_index ON story_sends (message_id, distribution_id)") + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java index d5d411b961..82b3cb2ef9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java @@ -23,9 +23,12 @@ import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; +import org.whispersystems.signalservice.api.push.DistributionId; import java.util.LinkedList; import java.util.List; +import java.util.Objects; +import java.util.Set; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.schedulers.Schedulers; @@ -100,8 +103,9 @@ public final class MessageDetailsRepository { getKeyMismatchFailure(messageRecord, recipient))); } } else if (receiptInfoList.isEmpty() && messageRecord.getRecipient().isDistributionList()) { - List distributionList = SignalDatabase.distributionLists().getMembers(messageRecord.getRecipient().requireDistributionListId()); - List resolved = Recipient.resolvedList(distributionList); + DistributionId distributionId = SignalDatabase.distributionLists().getDistributionId(messageRecord.getRecipient().requireDistributionListId()); + Set recipientIds = SignalDatabase.storySends().getRecipientsForDistributionId(messageRecord.getId(), Objects.requireNonNull(distributionId)); + List resolved = Recipient.resolvedList(recipientIds); for (Recipient recipient : resolved) { recipients.add(new RecipientDeliveryStatus(messageRecord, diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsRepository.kt index 94182642a5..d0c373ed51 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/views/StoryViewsRepository.kt @@ -8,9 +8,12 @@ import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.database.DatabaseObserver import org.thoughtcrime.securesms.database.GroupReceiptDatabase import org.thoughtcrime.securesms.database.SignalDatabase +import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.recipients.Recipient +import org.thoughtcrime.securesms.recipients.RecipientId +import org.whispersystems.signalservice.api.push.DistributionId class StoryViewsRepository { @@ -30,6 +33,10 @@ class StoryViewsRepository { fun getViews(storyId: Long): Observable> { return Observable.create> { emitter -> + val record: MessageRecord = SignalDatabase.mms.getMessageRecord(storyId) + val distributionId: DistributionId = SignalDatabase.distributionLists.getDistributionId(record.recipient.requireDistributionListId())!! + val recipientIds: Set = SignalDatabase.storySends.getRecipientsForDistributionId(storyId, distributionId) + fun refresh() { emitter.onNext( SignalDatabase.groupReceipts.getGroupReceiptInfo(storyId).filter { @@ -39,6 +46,8 @@ class StoryViewsRepository { recipient = Recipient.resolved(it.recipientId), timeViewedInMillis = it.timestamp ) + }.filter { + it.recipient.id in recipientIds } ) }