From 4b01fcec5e5564a4ced132a498e0838ca8041011 Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Mon, 21 Oct 2024 15:45:02 +1100 Subject: [PATCH] Fix/message deletion issues (#1697) * SES-2810 - Removing the screenshot privacy toggle * SES-2813 - clickable only when there is a 'follow settings' * SES-2815 - proper icon and spacing for deleted messages * Simplified deletion dialog to be reused for note to self and the rest as only the labels change * SES-2819 - Do not show a reaction on a deleted message * Fixing up deletion details Message view hides reactions completely if the message is marked as deleted All messages can now show the 'Delete' long press option Community messages should be removed completely not marked as deleted * Revert "SES-2819 - Do not show a reaction on a deleted message" This reverts commit 711e31a43a889187ec3be189ad4aa78f18c217d7. * Avoiding adding reactions if the message is marked as deleted * Removing uneeded icon * Deletion handled by VM so menu item is always visible * SES-2811 - Do not attempt to send a failed message marked as deleted * SES-2818 - Making sure we set the lastMessage in a thread properly, without using 'marked as deleted' messages * SES-2464 - changed the behaviour to finish the convo activity but instead refresh the sarch on resume * removing log --- .../attachments/DatabaseAttachmentProvider.kt | 6 +++++ .../conversation/v2/ConversationActivityV2.kt | 4 +-- .../menus/ConversationActionModeCallback.kt | 14 +---------- .../securesms/database/MmsDatabase.kt | 17 +++++++++++++ .../securesms/database/MmsSmsDatabase.java | 15 +++++++++++- .../securesms/database/SmsDatabase.java | 23 ++++++++++++++++++ .../securesms/home/HomeActivity.kt | 5 ++++ .../res/drawable-hdpi/ic_trash_filled_32.png | Bin 1492 -> 0 bytes .../res/drawable-mdpi/ic_trash_filled_32.png | Bin 835 -> 0 bytes .../res/drawable-xhdpi/ic_trash_filled_32.png | Bin 1782 -> 0 bytes .../drawable-xxhdpi/ic_trash_filled_32.png | Bin 3146 -> 0 bytes .../drawable-xxxhdpi/ic_trash_filled_32.png | Bin 4373 -> 0 bytes app/src/main/res/layout/image_editor_hud.xml | 3 ++- .../database/MessageDataProvider.kt | 1 + .../messaging/jobs/MessageSendJob.kt | 12 ++++++++- .../sending_receiving/MessageSender.kt | 8 +++++- 16 files changed, 89 insertions(+), 19 deletions(-) delete mode 100644 app/src/main/res/drawable-hdpi/ic_trash_filled_32.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_trash_filled_32.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_trash_filled_32.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_trash_filled_32.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_trash_filled_32.png diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt index d74174fecb..06e344a239 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt @@ -145,6 +145,12 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) return smsDatabase.isOutgoingMessage(timestamp) || mmsDatabase.isOutgoingMessage(timestamp) } + override fun isDeletedMessage(timestamp: Long): Boolean { + val smsDatabase = DatabaseComponent.get(context).smsDatabase() + val mmsDatabase = DatabaseComponent.get(context).mmsDatabase() + return smsDatabase.isDeletedMessage(timestamp) || mmsDatabase.isDeletedMessage(timestamp) + } + override fun handleSuccessfulAttachmentUpload(attachmentId: Long, attachmentStream: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: UploadResult) { val database = DatabaseComponent.get(context).attachmentDatabase() val databaseAttachment = getDatabaseAttachment(attachmentId) ?: return diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 9cdb76cf25..485fcaca5f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -851,8 +851,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe binding.messageRequestBar.visibility = View.GONE } if (!uiState.conversationExists && !isFinishing) { - // Conversation should be deleted now, go to homepage with a cleared stack - baseContext.startHomeActivity(isFromOnboarding = false, isNewAccount = false) + // Conversation should be deleted now + finish() } // show or hide the text input diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt index abadc06335..ea265bdbbf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationActionModeCallback.kt @@ -42,18 +42,6 @@ class ConversationActionModeCallback(private val adapter: ConversationAdapter, p val blindedPublicKey = openGroup?.publicKey?.let { SodiumUtilities.blindedKeyPair(it, edKeyPair)?.publicKey?.asBytes } ?.let { AccountId(IdPrefix.BLINDED, it) }?.hexString - // Embedded function - fun userCanDeleteSelectedItems(): Boolean { - // admin can delete all combinations - if(adapter.isAdmin) return true - - val allSentByCurrentUser = selectedItems.all { it.isOutgoing } - val allReceivedByCurrentUser = selectedItems.all { !it.isOutgoing } - if (openGroup == null) { return allSentByCurrentUser || allReceivedByCurrentUser } - if (allSentByCurrentUser) { return true } - return OpenGroupManager.isUserModerator(context, openGroup.groupId, userPublicKey, blindedPublicKey) - } - // Embedded function fun userCanBanSelectedUsers(): Boolean { if (openGroup == null) { return false } @@ -67,7 +55,7 @@ class ConversationActionModeCallback(private val adapter: ConversationAdapter, p // Delete message - menu.findItem(R.id.menu_context_delete_message).isVisible = userCanDeleteSelectedItems() + menu.findItem(R.id.menu_context_delete_message).isVisible = true // can always delete since delete logic will be handled by the VM // Ban user menu.findItem(R.id.menu_context_ban_user).isVisible = userCanBanSelectedUsers() // Ban and delete all diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt index 63460744f6..60c4de6883 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt @@ -106,6 +106,23 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa .any { MmsSmsColumns.Types.isOutgoingMessageType(it) } } + fun isDeletedMessage(timestamp: Long): Boolean = + databaseHelper.writableDatabase.query( + TABLE_NAME, + arrayOf(ID, THREAD_ID, MESSAGE_BOX, ADDRESS), + DATE_SENT + " = ?", + arrayOf(timestamp.toString()), + null, + null, + null, + null + ).use { cursor -> + cursor.asSequence() + .map { cursor.getColumnIndexOrThrow(MESSAGE_BOX) } + .map(cursor::getLong) + .any { MmsSmsColumns.Types.isDeletedMessage(it) } + } + fun incrementReceiptCount( messageId: SyncMessageId, timestamp: Long, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java index b737be855e..510272cfb8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsSmsDatabase.java @@ -17,6 +17,9 @@ package org.thoughtcrime.securesms.database; import static org.thoughtcrime.securesms.database.MmsDatabase.MESSAGE_BOX; +import static org.thoughtcrime.securesms.database.MmsSmsColumns.Types.BASE_DELETED_INCOMING_TYPE; +import static org.thoughtcrime.securesms.database.MmsSmsColumns.Types.BASE_DELETED_OUTGOING_TYPE; +import static org.thoughtcrime.securesms.database.MmsSmsColumns.Types.BASE_TYPE_MASK; import android.content.Context; import android.database.Cursor; @@ -96,6 +99,14 @@ public class MmsSmsDatabase extends Database { } } + public @Nullable MessageRecord getNonDeletedMessageForTimestamp(long timestamp) { + String selection = MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp; + try (Cursor cursor = queryTables(PROJECTION, selection, null, null)) { + MmsSmsDatabase.Reader reader = readerFor(cursor); + return reader.getNext(); + } + } + public @Nullable MessageRecord getMessageFor(long timestamp, String serializedAuthor) { return getMessageFor(timestamp, serializedAuthor, true); } @@ -323,7 +334,9 @@ public class MmsSmsDatabase extends Database { public long getLastMessageTimestamp(long threadId) { String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC"; - String selection = MmsSmsColumns.THREAD_ID + " = " + threadId; + // make sure the last message isn't marked as deleted + String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + + "(ifnull("+SmsDatabase.TYPE+", "+MmsDatabase.MESSAGE_BOX+") & "+BASE_TYPE_MASK+") NOT IN ("+BASE_DELETED_OUTGOING_TYPE+", "+BASE_DELETED_INCOMING_TYPE+")"; // this ugly line checks whether the type is deleted (incoming or outgoing) for either the sms table or the mms table try (Cursor cursor = queryTables(PROJECTION, selection, order, "1")) { if (cursor.moveToFirst()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index 5088b76d29..ed7945e8a3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -243,6 +243,7 @@ public class SmsDatabase extends MessagingDatabase { contentValues.put(READ, 1); contentValues.put(BODY, displayedMessage); contentValues.put(HAS_MENTION, 0); + contentValues.put(STATUS, Status.STATUS_NONE); database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {String.valueOf(messageId)}); updateTypeBitmask(messageId, Types.BASE_TYPE_MASK, @@ -299,6 +300,28 @@ public class SmsDatabase extends MessagingDatabase { return isOutgoing; } + public boolean isDeletedMessage(long timestamp) { + SQLiteDatabase database = databaseHelper.getWritableDatabase(); + Cursor cursor = null; + boolean isDeleted = false; + + try { + cursor = database.query(TABLE_NAME, new String[] { ID, THREAD_ID, ADDRESS, TYPE }, + DATE_SENT + " = ?", new String[] { String.valueOf(timestamp) }, + null, null, null, null); + + while (cursor.moveToNext()) { + if (Types.isDeletedMessage(cursor.getLong(cursor.getColumnIndexOrThrow(TYPE)))) { + isDeleted = true; + } + } + } finally { + if (cursor != null) cursor.close(); + } + + return isDeleted; + } + public void incrementReceiptCount(SyncMessageId messageId, boolean deliveryReceipt, boolean readReceipt) { SQLiteDatabase database = databaseHelper.getWritableDatabase(); Cursor cursor = null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index 5a19263cac..cfbd03bb57 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -372,6 +372,11 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), binding.seedReminderView.isVisible = false } + // refresh search on resume, in case we a conversation was deleted + if (binding.globalSearchRecycler.isVisible){ + globalSearchViewModel.refresh() + } + updateLegacyConfigView() // Sync config changes if there are any diff --git a/app/src/main/res/drawable-hdpi/ic_trash_filled_32.png b/app/src/main/res/drawable-hdpi/ic_trash_filled_32.png deleted file mode 100644 index 586af53d086740cd4ead752188a6570a3db0c1b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1492 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 Y0fFwsuOsDrQ~&?~07*qoM6N<$f;+cT3;+NC diff --git a/app/src/main/res/drawable-xxhdpi/ic_trash_filled_32.png b/app/src/main/res/drawable-xxhdpi/ic_trash_filled_32.png deleted file mode 100644 index 6a4ccab1b61c95ba2cd9e20ac4bf9b16d841902a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3146 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 O08KSr#5WbI7ykpOp+9T@ diff --git a/app/src/main/res/layout/image_editor_hud.xml b/app/src/main/res/layout/image_editor_hud.xml index d78afa6686..6a9538d603 100644 --- a/app/src/main/res/layout/image_editor_hud.xml +++ b/app/src/main/res/layout/image_editor_hud.xml @@ -31,7 +31,8 @@ android:layout_height="wrap_content" android:background="?attr/selectableItemBackgroundBorderless" android:padding="8dp" - android:src="@drawable/ic_trash_filled_32" /> + app:tint="@color/white" + android:src="@drawable/ic_delete" /> ? diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt index 52d56184cc..2010a58e61 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt @@ -37,6 +37,13 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { val message = message as? VisibleMessage val storage = MessagingModuleConfiguration.shared.storage + // do not attempt to send if the message is marked as deleted + message?.sentTimestamp?.let{ + if(messageDataProvider.isDeletedMessage(it)){ + return@execute + } + } + val sentTimestamp = this.message.sentTimestamp val sender = storage.getUserPublicKey() if (sentTimestamp != null && sender != null) { @@ -107,7 +114,10 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { Log.w(TAG, "Failed to send $message::class.simpleName.") val message = message as? VisibleMessage if (message != null) { - if (!MessagingModuleConfiguration.shared.messageDataProvider.isOutgoingMessage(message.sentTimestamp!!)) { + if ( + MessagingModuleConfiguration.shared.messageDataProvider.isDeletedMessage(message.sentTimestamp!!) || + !MessagingModuleConfiguration.shared.messageDataProvider.isOutgoingMessage(message.sentTimestamp!!) + ) { return // The message has been deleted } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 301648f97b..73073532b0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -469,9 +469,15 @@ object MessageSender { fun handleFailedMessageSend(message: Message, error: Exception, isSyncMessage: Boolean = false) { val storage = MessagingModuleConfiguration.shared.storage + val timestamp = message.sentTimestamp!! + + // no need to handle if message is marked as deleted + if(MessagingModuleConfiguration.shared.messageDataProvider.isDeletedMessage(message.sentTimestamp!!)){ + return + } + val userPublicKey = storage.getUserPublicKey()!! - val timestamp = message.sentTimestamp!! val author = message.sender ?: userPublicKey if (isSyncMessage) storage.markAsSyncFailed(timestamp, author, error)