From 105c2bddeddcecb5973e057f5ce6ca0973959267 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 17 Jan 2025 14:06:54 -0500 Subject: [PATCH] Add internal tool to jump to message by timestamp. --- .../app/internal/InternalSettingsFragment.kt | 51 +++++++++++++++++++ .../securesms/database/MessageTable.kt | 9 ++++ 2 files changed, 60 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index a77da4138d..98255c1d7f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -6,6 +6,7 @@ import android.content.Context import android.content.DialogInterface import android.os.Bundle import android.view.View +import android.widget.EditText import android.widget.Toast import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.findNavController @@ -28,6 +29,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.app.privacy.advanced.AdvancedPrivacySettingsRepository import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository import org.thoughtcrime.securesms.components.settings.configure +import org.thoughtcrime.securesms.conversation.ConversationIntents import org.thoughtcrime.securesms.database.JobDatabase import org.thoughtcrime.securesms.database.LocalMetricsDatabase import org.thoughtcrime.securesms.database.LogDatabase @@ -35,6 +37,7 @@ import org.thoughtcrime.securesms.database.MegaphoneDatabase import org.thoughtcrime.securesms.database.OneTimePreKeyTable import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord +import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.jobmanager.JobTracker import org.thoughtcrime.securesms.jobs.DownloadLatestEmojiDataJob @@ -52,6 +55,7 @@ import org.thoughtcrime.securesms.megaphone.MegaphoneRepository import org.thoughtcrime.securesms.megaphone.Megaphones import org.thoughtcrime.securesms.payments.DataExportUtil import org.thoughtcrime.securesms.recipients.Recipient +import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.storage.StorageSyncHelper import org.thoughtcrime.securesms.util.ConversationUtil import org.thoughtcrime.securesms.util.Util @@ -149,6 +153,14 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter onUnregisterClicked() } ) + + clickPref( + title = DSLSettingsText.from("Jump to message"), + summary = DSLSettingsText.from("Find and jump to a message via its sentTimestamp."), + onClick = { + promptUserForSentTimestamp() + } + ) dividerPref() sectionHeaderPref(DSLSettingsText.from("Playgrounds")) @@ -1033,4 +1045,43 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter Toast.makeText(requireContext(), "Dumped to logs", Toast.LENGTH_SHORT).show() } } + + private fun promptUserForSentTimestamp() { + val input = EditText(requireContext()).apply { + inputType = android.text.InputType.TYPE_CLASS_NUMBER + } + + MaterialAlertDialogBuilder(requireContext()) + .setTitle("Enter sentTimestamp") + .setView(input) + .setPositiveButton(android.R.string.ok) { _, _ -> + val number = input.text.toString().toLongOrNull() + if (number == null) { + Toast.makeText(requireContext(), "Failed to parse timestamp!", Toast.LENGTH_SHORT).show() + return@setPositiveButton + } + + val messages = SignalDatabase.messages.getMessagesBySentTimestamp(number) + if (messages.isEmpty()) { + Toast.makeText(requireContext(), "Could not find a message with that timestamp!", Toast.LENGTH_SHORT).show() + return@setPositiveButton + } + + if (messages.size > 1) { + Toast.makeText(requireContext(), "There's ${messages.size} messages with that timestamp! Go run SQL or something.", Toast.LENGTH_SHORT).show() + return@setPositiveButton + } + + val message: MessageRecord = messages[0] + val startingPosition = SignalDatabase.messages.getMessagePositionInConversation(message.threadId, message.dateReceived) + val intent = ConversationIntents + .createBuilderSync(requireContext(), RecipientId.UNKNOWN, message.threadId) + .withStartingPosition(startingPosition) + .build() + + startActivity(intent) + } + .setNegativeButton("Cancel", null) + .show() + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt index 6ccdd3ab64..39c3f7b523 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt @@ -627,6 +627,15 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat return rawQueryWithAttachments(where, null) } + fun getMessagesBySentTimestamp(sentTimestamp: Long): List { + return readableDatabase + .select(*MMS_PROJECTION) + .from(TABLE_NAME) + .where("$DATE_SENT = $sentTimestamp") + .run() + .readToList { MmsReader(it).getCurrent() } + } + fun getMessageCursor(messageId: Long): Cursor { return internalGetMessage(messageId) }