Fix issues with scheduled messages and quotes.

- Tapping quote in schedule view will jump to message in chat
- Scheduling a quote will not make the quoted message render as "isQuoted"
- Scheduled quotes will not appear in the quoted message's sheet of replies
- Fixes an off-by-N where N = # of scheduled messages when calculating location for jumping to a message
main
Cody Henthorne 2023-01-27 16:59:22 -05:00 zatwierdzone przez Greyson Parrelli
rodzic e7339af119
commit 30c33fdd77
8 zmienionych plików z 69 dodań i 41 usunięć

Wyświetl plik

@ -0,0 +1,12 @@
package org.thoughtcrime.securesms.conversation
import org.thoughtcrime.securesms.database.model.MessageRecord
/**
* Callback interface for bottom sheets that show conversation data in a conversation and
* want to manipulate the conversation view.
*/
interface ConversationBottomSheetCallback {
fun getConversationAdapterListener(): ConversationAdapter.ItemClickListener
fun jumpToMessage(messageRecord: MessageRecord)
}

Wyświetl plik

@ -207,7 +207,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import kotlin.Unit; import kotlin.Unit;
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
public class ConversationFragment extends LoggingFragment implements MultiselectForwardBottomSheet.Callback, MessageQuotesBottomSheet.Callback { public class ConversationFragment extends LoggingFragment implements MultiselectForwardBottomSheet.Callback, ConversationBottomSheetCallback {
private static final String TAG = Log.tag(ConversationFragment.class); private static final String TAG = Log.tag(ConversationFragment.class);
private static final int SCROLL_ANIMATION_THRESHOLD = 50; private static final int SCROLL_ANIMATION_THRESHOLD = 50;

Wyświetl plik

@ -20,7 +20,6 @@ import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@ -137,8 +136,6 @@ import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel;
import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView; import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView;
import org.thoughtcrime.securesms.components.location.SignalPlace; import org.thoughtcrime.securesms.components.location.SignalPlace;
import org.thoughtcrime.securesms.components.mention.MentionAnnotation; import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
import org.thoughtcrime.securesms.components.menu.ActionItem;
import org.thoughtcrime.securesms.components.menu.SignalContextMenu;
import org.thoughtcrime.securesms.components.reminder.BubbleOptOutReminder; import org.thoughtcrime.securesms.components.reminder.BubbleOptOutReminder;
import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder; import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder;
import org.thoughtcrime.securesms.components.reminder.GroupsV1MigrationSuggestionsReminder; import org.thoughtcrime.securesms.components.reminder.GroupsV1MigrationSuggestionsReminder;
@ -180,6 +177,7 @@ import org.thoughtcrime.securesms.database.RecipientTable.RegisteredState;
import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.ThreadTable; import org.thoughtcrime.securesms.database.ThreadTable;
import org.thoughtcrime.securesms.database.identity.IdentityRecordList; import org.thoughtcrime.securesms.database.identity.IdentityRecordList;
import org.thoughtcrime.securesms.database.model.GroupRecord;
import org.thoughtcrime.securesms.database.model.IdentityRecord; import org.thoughtcrime.securesms.database.model.IdentityRecord;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.Mention; import org.thoughtcrime.securesms.database.model.Mention;
@ -337,8 +335,6 @@ import kotlin.Unit;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import org.thoughtcrime.securesms.database.model.GroupRecord;
/** /**
* Fragment for displaying a message thread, as well as * Fragment for displaying a message thread, as well as
* composing/sending a new message into that thread. * composing/sending a new message into that thread.
@ -370,7 +366,7 @@ public class ConversationParentFragment extends Fragment
Material3OnScrollHelperBinder, Material3OnScrollHelperBinder,
MessageDetailsFragment.Callback, MessageDetailsFragment.Callback,
ScheduleMessageTimePickerBottomSheet.ScheduleCallback, ScheduleMessageTimePickerBottomSheet.ScheduleCallback,
ScheduledMessagesBottomSheet.Callback ConversationBottomSheetCallback
{ {
private static final int SHORTCUT_ICON_SIZE = Build.VERSION.SDK_INT >= 26 ? ViewUtil.dpToPx(72) : ViewUtil.dpToPx(48 + 16 * 2); private static final int SHORTCUT_ICON_SIZE = Build.VERSION.SDK_INT >= 26 ? ViewUtil.dpToPx(72) : ViewUtil.dpToPx(48 + 16 * 2);
@ -3677,10 +3673,16 @@ public class ConversationParentFragment extends Fragment
sendMessage(null, scheduledTime); sendMessage(null, scheduledTime);
} }
@Override
public @NonNull ConversationAdapter.ItemClickListener getConversationAdapterListener() { public @NonNull ConversationAdapter.ItemClickListener getConversationAdapterListener() {
return fragment.getConversationAdapterListener(); return fragment.getConversationAdapterListener();
} }
@Override
public void jumpToMessage(@NonNull MessageRecord messageRecord) {
fragment.jumpToMessage(messageRecord);
}
// Listeners // Listeners
private class RecordingSession implements SingleObserver<VoiceNoteDraft> { private class RecordingSession implements SingleObserver<VoiceNoteDraft> {

Wyświetl plik

@ -38,7 +38,6 @@ import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionPlayerHolder
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionRecycler import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionRecycler
import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange
import org.thoughtcrime.securesms.linkpreview.LinkPreview
import org.thoughtcrime.securesms.mms.GlideApp import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.PartAuthority import org.thoughtcrime.securesms.mms.PartAuthority
import org.thoughtcrime.securesms.mms.TextSlide import org.thoughtcrime.securesms.mms.TextSlide
@ -67,7 +66,7 @@ class ScheduledMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment
private var deleteDialog: AlertDialog? = null private var deleteDialog: AlertDialog? = null
private lateinit var messageAdapter: ConversationAdapter private lateinit var messageAdapter: ConversationAdapter
private lateinit var callback: Callback private lateinit var callback: ConversationBottomSheetCallback
private val viewModel: ScheduledMessagesViewModel by viewModels( private val viewModel: ScheduledMessagesViewModel by viewModels(
factoryProducer = { factoryProducer = {
@ -244,18 +243,25 @@ class ScheduledMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment
viewModel.rescheduleMessage(messageId, scheduledTime) viewModel.rescheduleMessage(messageId, scheduledTime)
} }
private fun getAdapterListener(): ConversationAdapter.ItemClickListener { private inner class ConversationAdapterListener : ConversationAdapter.ItemClickListener by callback.getConversationAdapterListener() {
return callback.getConversationAdapterListener() override fun onQuoteClicked(messageRecord: MmsMessageRecord) {
} dismissAllowingStateLoss()
callback.getConversationAdapterListener().onQuoteClicked(messageRecord)
}
override fun onScheduledIndicatorClicked(view: View, messageRecord: MessageRecord) {
showScheduledMessageContextMenu(view, messageRecord)
}
override fun onGroupMemberClicked(recipientId: RecipientId, groupId: GroupId) {
dismissAllowingStateLoss()
callback.getConversationAdapterListener().onGroupMemberClicked(recipientId, groupId)
}
private inner class ConversationAdapterListener : ConversationAdapter.ItemClickListener by getAdapterListener() {
override fun onItemClick(item: MultiselectPart) = Unit override fun onItemClick(item: MultiselectPart) = Unit
override fun onItemLongClick(itemView: View, item: MultiselectPart) = Unit override fun onItemLongClick(itemView: View, item: MultiselectPart) = Unit
override fun onQuoteClicked(messageRecord: MmsMessageRecord) = Unit
override fun onLinkPreviewClicked(linkPreview: LinkPreview) = Unit
override fun onQuotedIndicatorClicked(messageRecord: MessageRecord) = Unit override fun onQuotedIndicatorClicked(messageRecord: MessageRecord) = Unit
override fun onReactionClicked(multiselectPart: MultiselectPart, messageId: Long, isMms: Boolean) = Unit override fun onReactionClicked(multiselectPart: MultiselectPart, messageId: Long, isMms: Boolean) = Unit
override fun onGroupMemberClicked(recipientId: RecipientId, groupId: GroupId) = Unit
override fun onMessageWithRecaptchaNeededClicked(messageRecord: MessageRecord) = Unit override fun onMessageWithRecaptchaNeededClicked(messageRecord: MessageRecord) = Unit
override fun onGroupMigrationLearnMoreClicked(membershipChange: GroupMigrationMembershipChange) = Unit override fun onGroupMigrationLearnMoreClicked(membershipChange: GroupMigrationMembershipChange) = Unit
override fun onChatSessionRefreshLearnMoreClicked() = Unit override fun onChatSessionRefreshLearnMoreClicked() = Unit
@ -270,13 +276,6 @@ class ScheduledMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment
override fun onViewGiftBadgeClicked(messageRecord: MessageRecord) = Unit override fun onViewGiftBadgeClicked(messageRecord: MessageRecord) = Unit
override fun onActivatePaymentsClicked() = Unit override fun onActivatePaymentsClicked() = Unit
override fun onSendPaymentClicked(recipientId: RecipientId) = Unit override fun onSendPaymentClicked(recipientId: RecipientId) = Unit
override fun onScheduledIndicatorClicked(view: View, messageRecord: MessageRecord) {
showScheduledMessageContextMenu(view, messageRecord)
}
}
interface Callback {
fun getConversationAdapterListener(): ConversationAdapter.ItemClickListener
} }
companion object { companion object {

Wyświetl plik

@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager
import org.thoughtcrime.securesms.conversation.ConversationAdapter import org.thoughtcrime.securesms.conversation.ConversationAdapter
import org.thoughtcrime.securesms.conversation.ConversationBottomSheetCallback
import org.thoughtcrime.securesms.conversation.colors.Colorizer import org.thoughtcrime.securesms.conversation.colors.Colorizer
import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer import org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart
@ -137,8 +138,8 @@ class MessageQuotesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment() {
return callback return callback
} }
private fun getCallback(): Callback { private fun getCallback(): ConversationBottomSheetCallback {
return findListener<Callback>() ?: throw IllegalStateException("Parent must implement callback interface!") return findListener<ConversationBottomSheetCallback>() ?: throw IllegalStateException("Parent must implement callback interface!")
} }
private fun getAdapterListener(): ConversationAdapter.ItemClickListener { private fun getAdapterListener(): ConversationAdapter.ItemClickListener {
@ -251,11 +252,6 @@ class MessageQuotesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment() {
} }
} }
interface Callback {
fun getConversationAdapterListener(): ConversationAdapter.ItemClickListener
fun jumpToMessage(messageRecord: MessageRecord)
}
companion object { companion object {
private const val KEY_MESSAGE_ID = "message_id" private const val KEY_MESSAGE_ID = "message_id"
private const val KEY_CONVERSATION_RECIPIENT_ID = "conversation_recipient_id" private const val KEY_CONVERSATION_RECIPIENT_ID = "conversation_recipient_id"

Wyświetl plik

@ -252,7 +252,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
"CREATE INDEX IF NOT EXISTS mms_story_type_index ON " + TABLE_NAME + " (" + STORY_TYPE + ");", "CREATE INDEX IF NOT EXISTS mms_story_type_index ON " + TABLE_NAME + " (" + STORY_TYPE + ");",
"CREATE INDEX IF NOT EXISTS mms_parent_story_id_index ON " + TABLE_NAME + " (" + PARENT_STORY_ID + ");", "CREATE INDEX IF NOT EXISTS mms_parent_story_id_index ON " + TABLE_NAME + " (" + PARENT_STORY_ID + ");",
"CREATE INDEX IF NOT EXISTS " + INDEX_THREAD_STORY_SCHEDULED_DATE + " ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + "," + STORY_TYPE + "," + PARENT_STORY_ID + "," + SCHEDULED_DATE + ");", "CREATE INDEX IF NOT EXISTS " + INDEX_THREAD_STORY_SCHEDULED_DATE + " ON " + TABLE_NAME + " (" + THREAD_ID + ", " + DATE_RECEIVED + "," + STORY_TYPE + "," + PARENT_STORY_ID + "," + SCHEDULED_DATE + ");",
"CREATE INDEX IF NOT EXISTS mms_quote_id_quote_author_index ON " + TABLE_NAME + "(" + QUOTE_ID + ", " + QUOTE_AUTHOR + ");", "CREATE INDEX IF NOT EXISTS message_quote_id_quote_author_scheduled_date_index ON " + TABLE_NAME + " (" + QUOTE_ID + ", " + QUOTE_AUTHOR + ", " + SCHEDULED_DATE + ");",
"CREATE INDEX IF NOT EXISTS mms_exported_index ON " + TABLE_NAME + " (" + EXPORTED + ");", "CREATE INDEX IF NOT EXISTS mms_exported_index ON " + TABLE_NAME + " (" + EXPORTED + ");",
"CREATE INDEX IF NOT EXISTS mms_id_type_payment_transactions_index ON " + TABLE_NAME + " (" + ID + "," + TYPE + ") WHERE " + TYPE + " & " + MessageTypes.SPECIAL_TYPE_PAYMENTS_NOTIFICATION + " != 0;" "CREATE INDEX IF NOT EXISTS mms_id_type_payment_transactions_index ON " + TABLE_NAME + " (" + ID + "," + TYPE + ") WHERE " + TYPE + " & " + MessageTypes.SPECIAL_TYPE_PAYMENTS_NOTIFICATION + " != 0;"
}; };
@ -3844,8 +3844,8 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
RecipientId author = messageRecord.isOutgoing() ? Recipient.self().getId() : messageRecord.getRecipient().getId(); RecipientId author = messageRecord.isOutgoing() ? Recipient.self().getId() : messageRecord.getRecipient().getId();
long timestamp = messageRecord.getDateSent(); long timestamp = messageRecord.getDateSent();
String where = MessageTable.QUOTE_ID + " = ? AND " + MessageTable.QUOTE_AUTHOR + " = ?"; String where = MessageTable.QUOTE_ID + " = ? AND " + MessageTable.QUOTE_AUTHOR + " = ? AND " + SCHEDULED_DATE + " = ?";
String[] whereArgs = SqlUtil.buildArgs(timestamp, author); String[] whereArgs = SqlUtil.buildArgs(timestamp, author, -1);
try (Cursor cursor = getReadableDatabase().query(MessageTable.TABLE_NAME, new String[]{ "1" }, where, whereArgs, null, null, null, "1")) { try (Cursor cursor = getReadableDatabase().query(MessageTable.TABLE_NAME, new String[]{ "1" }, where, whereArgs, null, null, null, "1")) {
return cursor.moveToFirst(); return cursor.moveToFirst();
@ -3862,19 +3862,19 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
} }
Map<QuoteDescriptor, MessageRecord> byQuoteDescriptor = new HashMap<>(records.size()); Map<QuoteDescriptor, MessageRecord> byQuoteDescriptor = new HashMap<>(records.size());
List<String[]> args = new ArrayList<>(records.size()); List<String[]> args = new ArrayList<>(records.size());
for (MessageRecord record : records) { for (MessageRecord record : records) {
long timestamp = record.getDateSent(); long timestamp = record.getDateSent();
RecipientId author = record.isOutgoing() ? Recipient.self().getId() : record.getRecipient().getId(); RecipientId author = record.isOutgoing() ? Recipient.self().getId() : record.getRecipient().getId();
byQuoteDescriptor.put(new QuoteDescriptor(timestamp, author), record); byQuoteDescriptor.put(new QuoteDescriptor(timestamp, author), record);
args.add(SqlUtil.buildArgs(timestamp, author)); args.add(SqlUtil.buildArgs(timestamp, author, -1));
} }
String[] projection = new String[] { QUOTE_ID, QUOTE_AUTHOR }; String[] projection = new String[] { QUOTE_ID, QUOTE_AUTHOR };
List<SqlUtil.Query> queries = SqlUtil.buildCustomCollectionQuery(QUOTE_ID + " = ? AND " + QUOTE_AUTHOR + " = ?", args); List<SqlUtil.Query> queries = SqlUtil.buildCustomCollectionQuery(QUOTE_ID + " = ? AND " + QUOTE_AUTHOR + " = ? AND " + SCHEDULED_DATE + " = ?", args);
Set<Long> quotedIds = new HashSet<>(); Set<Long> quotedIds = new HashSet<>();
for (SqlUtil.Query query : queries) { for (SqlUtil.Query query : queries) {
@ -3930,7 +3930,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
} }
RecipientId author = targetMessage.isOutgoing() ? Recipient.self().getId() : targetMessage.getRecipient().getId(); RecipientId author = targetMessage.isOutgoing() ? Recipient.self().getId() : targetMessage.getRecipient().getId();
String query = QUOTE_ID + " = " + targetMessage.getDateSent() + " AND " + QUOTE_AUTHOR + " = " + author.serialize(); String query = QUOTE_ID + " = " + targetMessage.getDateSent() + " AND " + QUOTE_AUTHOR + " = " + author.serialize() + " AND " + SCHEDULED_DATE + " = -1";
String order = DATE_RECEIVED + " DESC"; String order = DATE_RECEIVED + " DESC";
List<MessageRecord> records = new ArrayList<>(); List<MessageRecord> records = new ArrayList<>();
@ -3959,7 +3959,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) { public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) {
String[] projection = new String[]{ DATE_SENT, RECIPIENT_ID, REMOTE_DELETED}; String[] projection = new String[]{ DATE_SENT, RECIPIENT_ID, REMOTE_DELETED};
String order = DATE_RECEIVED + " DESC"; String order = DATE_RECEIVED + " DESC";
String selection = THREAD_ID + " = " + threadId + " AND " + STORY_TYPE + " = 0" + " AND " + PARENT_STORY_ID + " <= 0"; String selection = THREAD_ID + " = " + threadId + " AND " + STORY_TYPE + " = 0" + " AND " + PARENT_STORY_ID + " <= 0 AND " + SCHEDULED_DATE + " = -1";
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, projection, selection, null, null, null, order)) { try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, projection, selection, null, null, null, order)) {
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf(); boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();
@ -3983,7 +3983,7 @@ public class MessageTable extends DatabaseTable implements MessageTypes, Recipie
public int getMessagePositionInConversation(long threadId, long receivedTimestamp, @NonNull RecipientId recipientId) { public int getMessagePositionInConversation(long threadId, long receivedTimestamp, @NonNull RecipientId recipientId) {
String[] projection = new String[]{ DATE_RECEIVED, RECIPIENT_ID, REMOTE_DELETED}; String[] projection = new String[]{ DATE_RECEIVED, RECIPIENT_ID, REMOTE_DELETED};
String order = DATE_RECEIVED + " DESC"; String order = DATE_RECEIVED + " DESC";
String selection = THREAD_ID + " = " + threadId + " AND " + STORY_TYPE + " = 0" + " AND " + PARENT_STORY_ID + " <= 0"; String selection = THREAD_ID + " = " + threadId + " AND " + STORY_TYPE + " = 0" + " AND " + PARENT_STORY_ID + " <= 0 AND " + SCHEDULED_DATE + " = -1";
try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, projection, selection, null, null, null, order)) { try (Cursor cursor = getReadableDatabase().query(TABLE_NAME, projection, selection, null, null, null, order)) {
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf(); boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();

Wyświetl plik

@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V172_GroupMembershi
import org.thoughtcrime.securesms.database.helpers.migration.V173_ScheduledMessagesMigration import org.thoughtcrime.securesms.database.helpers.migration.V173_ScheduledMessagesMigration
import org.thoughtcrime.securesms.database.helpers.migration.V174_ReactionForeignKeyMigration import org.thoughtcrime.securesms.database.helpers.migration.V174_ReactionForeignKeyMigration
import org.thoughtcrime.securesms.database.helpers.migration.V175_FixFullTextSearchLink import org.thoughtcrime.securesms.database.helpers.migration.V175_FixFullTextSearchLink
import org.thoughtcrime.securesms.database.helpers.migration.V176_AddScheduledDateToQuoteIndex
/** /**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. * Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
@ -39,7 +40,7 @@ object SignalDatabaseMigrations {
val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass) val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
const val DATABASE_VERSION = 175 const val DATABASE_VERSION = 176
@JvmStatic @JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@ -150,6 +151,10 @@ object SignalDatabaseMigrations {
if (oldVersion < 175) { if (oldVersion < 175) {
V175_FixFullTextSearchLink.migrate(context, db, oldVersion, newVersion) V175_FixFullTextSearchLink.migrate(context, db, oldVersion, newVersion)
} }
if (oldVersion < 176) {
V176_AddScheduledDateToQuoteIndex.migrate(context, db, oldVersion, newVersion)
}
} }
@JvmStatic @JvmStatic

Wyświetl plik

@ -0,0 +1,14 @@
package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import net.zetetic.database.sqlcipher.SQLiteDatabase
/**
* Expand quote index to included scheduled date so they can be excluded.
*/
object V176_AddScheduledDateToQuoteIndex : SignalDatabaseMigration {
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP INDEX IF EXISTS mms_quote_id_quote_author_index")
db.execSQL("CREATE INDEX IF NOT EXISTS message_quote_id_quote_author_scheduled_date_index ON message (quote_id, quote_author, scheduled_date);")
}
}