Deleting reactions when deleting a message

pull/1518/head
ThomasSession 6 months ago
parent 036fd4e8e2
commit 0391c52f77

@ -239,7 +239,7 @@ class ConversationViewModel(
//todo DELETION handle multi select scenarios
//todo DELETION reactions are still visible on "marked as deleted" messages
//todo DELETION seems I can't "delete for everyone" when a message is sent by me on another phone
viewModelScope.launch(Dispatchers.IO) {
val allSentByCurrentUser = messages.all { it.isOutgoing }

@ -159,7 +159,7 @@ class ReactionDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
)
}
private fun deleteReactions(messageId: MessageId, query: String, args: Array<String>, notifyUnread: Boolean) {
private fun deleteReactions(messageId: MessageId, query: String, args: Array<String>, notifyUnread: Boolean) {
writableDatabase.beginTransaction()
try {
writableDatabase.delete(TABLE_NAME, query, args)
@ -174,7 +174,54 @@ class ReactionDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
} finally {
writableDatabase.endTransaction()
}
}
}
fun deleteMessageReactions(messageIds: List<MessageId>) {
if (messageIds.isEmpty()) return // Early exit if the list is empty
val conditions = mutableListOf<String>()
val args = mutableListOf<String>()
for (messageId in messageIds) {
conditions.add("($MESSAGE_ID = ? AND $IS_MMS = ?)")
args.add(messageId.id.toString())
args.add(if (messageId.mms) "1" else "0")
}
val query = conditions.joinToString(" OR ")
deleteReactions(
messageIds = messageIds,
query = query,
args = args.toTypedArray(),
notifyUnread = false
)
}
private fun deleteReactions(messageIds: List<MessageId>, query: String, args: Array<String>, notifyUnread: Boolean) {
writableDatabase.beginTransaction()
try {
writableDatabase.delete(TABLE_NAME, query, args)
// Update unread status for each message
for (messageId in messageIds) {
val hasReaction = hasReactions(messageId)
if (messageId.mms) {
DatabaseComponent.get(context).mmsDatabase().updateReactionsUnread(
writableDatabase, messageId.id, hasReaction, true, notifyUnread
)
} else {
DatabaseComponent.get(context).smsDatabase().updateReactionsUnread(
writableDatabase, messageId.id, hasReaction, true, notifyUnread
)
}
}
writableDatabase.setTransactionSuccessful()
} finally {
writableDatabase.endTransaction()
}
}
private fun hasReactions(messageId: MessageId): Boolean {
val query = "$MESSAGE_ID = ? AND $IS_MMS = ?"

@ -1732,6 +1732,12 @@ open class Storage(
DatabaseComponent.get(context).reactionDatabase().deleteMessageReactions(MessageId(messageId, mms))
}
override fun deleteReactions(messageIds: List<Long>, mms: Boolean) {
DatabaseComponent.get(context).reactionDatabase().deleteMessageReactions(
messageIds.map { MessageId(it, mms) }
)
}
override fun setBlocked(recipients: Iterable<Recipient>, isBlocked: Boolean, fromConfigUpdate: Boolean) {
val recipientDb = DatabaseComponent.get(context).recipientDatabase()
recipientDb.setBlocked(recipients, isBlocked)

@ -1,16 +1,13 @@
package org.thoughtcrime.securesms.repository
import network.loki.messenger.libsession_util.util.ExpiryMode
import android.content.ContentResolver
import android.content.Context
import app.cash.copper.Query
import app.cash.copper.flow.observeQuery
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsession.database.MessageDataProvider
import org.session.libsession.messaging.messages.Destination
import org.session.libsession.messaging.messages.MarkAsDeletedMessage
@ -27,9 +24,6 @@ import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.get
import org.session.libsignal.utilities.toHexString
import org.thoughtcrime.securesms.database.DatabaseContentProviders
import org.thoughtcrime.securesms.database.DraftDatabase
import org.thoughtcrime.securesms.database.ExpirationConfigurationDatabase
@ -47,6 +41,8 @@ import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import javax.inject.Inject
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
interface ConversationRepository {
fun maybeGetRecipientForThreadId(threadId: Long): Recipient?
@ -212,6 +208,9 @@ class DefaultConversationRepository @Inject constructor(
isSms = false,
displayedMessage = displayedMessage
)
// delete reactions
storage.deleteReactions(messageIds = mms.map { it.id }, mms = true)
}
if(sms.isNotEmpty()){
@ -222,6 +221,9 @@ class DefaultConversationRepository @Inject constructor(
isSms = true,
displayedMessage = displayedMessage
)
// delete reactions
storage.deleteReactions(messageIds = sms.map { it.id }, mms = false)
}
}
@ -319,34 +321,6 @@ class DefaultConversationRepository @Inject constructor(
}
}
/* override suspend fun markAsDeletedForEveryone(
threadId: Long,
recipient: Recipient,
message: MessageRecord
): Result<Unit> = suspendCoroutine { continuation ->
buildUnsendRequest(recipient, message)?.let { unsendRequest ->
MessageSender.send(unsendRequest, recipient.address)
}
else // If this thread is NOT in a Community
{
messageDataProvider.deleteMessage(message.id, !message.isMms)
messageDataProvider.getServerHashForMessage(message.id, message.isMms)?.let { serverHash ->
var publicKey = recipient.address.serialize()
if (recipient.isClosedGroupRecipient) {
publicKey = GroupUtil.doubleDecodeGroupID(publicKey).toHexString()
}
SnodeAPI.deleteMessage(publicKey, listOf(serverHash))
.success {
continuation.resume(Result.success(Unit))
}.fail { error ->
Log.w("ConversationRepository", "Call to SnodeAPI.deleteMessage failed - attempting to resume..")
continuation.resume(Result.failure(error))
}
}
}
}*/
override fun buildUnsendRequest(recipient: Recipient, message: MessageRecord): UnsendRequest? {
if (recipient.isCommunityRecipient) return null
messageDataProvider.getServerHashForMessage(message.id, message.isMms) ?: return null

@ -227,6 +227,7 @@ interface StorageProtocol {
fun removeReaction(emoji: String, messageTimestamp: Long, author: String, notifyUnread: Boolean)
fun updateReactionIfNeeded(message: Message, sender: String, openGroupSentTimestamp: Long)
fun deleteReactions(messageId: Long, mms: Boolean)
fun deleteReactions(messageIds: List<Long>, mms: Boolean)
fun setBlocked(recipients: Iterable<Recipient>, isBlocked: Boolean, fromConfigUpdate: Boolean = false)
fun setRecipientHash(recipient: Recipient, recipientHash: String?)
fun blockedContacts(): List<Recipient>

@ -276,7 +276,6 @@ fun MessageReceiver.handleUnsendRequest(message: UnsendRequest): Long? {
val author = message.author ?: return null
val (messageIdToDelete, mms) = storage.getMessageIdInDatabase(timestamp, author) ?: return null
val messageType = storage.getMessageType(timestamp, author) ?: return null
Log.d("", "*** message type: $messageType")
// send a /delete rquest for 1on1 messages
if(messageType == MessageType.ONE_ON_ONE) {
@ -300,6 +299,9 @@ fun MessageReceiver.handleUnsendRequest(message: UnsendRequest): Long? {
author = author,
displayedMessage = context.getString(R.string.deleteMessageDeletedGlobally)
)
// delete reactions
storage.deleteReactions(messageId = messageIdToDelete, mms = mms)
}
if (!messageDataProvider.isOutgoingMessage(timestamp)) {

Loading…
Cancel
Save