diff --git a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/10.json b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/10.json index 982fc60b2..cda6ebbce 100644 --- a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/10.json +++ b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/10.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 10, - "identityHash": "93ef64fac7a9a811c4a3c2f5a6406f87", + "identityHash": "234cdb754d42d9ebf2349763a58a4578", "entities": [ { "tableName": "User", @@ -438,7 +438,7 @@ }, { "tableName": "ChatMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER, `token` TEXT, `id` INTEGER NOT NULL, `internalConversationId` TEXT, `actorType` TEXT, `actorId` TEXT, `actorDisplayName` TEXT, `timestamp` INTEGER NOT NULL, `systemMessage` TEXT, `messageType` TEXT, `isReplyable` INTEGER NOT NULL, `message` TEXT, `messageParameters` TEXT, `expirationTimestamp` INTEGER NOT NULL, `parent` INTEGER, `reactions` TEXT, `reactionsSelf` TEXT, `markdown` INTEGER, `lastEditActorType` TEXT, `lastEditActorId` TEXT, `lastEditActorDisplayName` TEXT, `lastEditTimestamp` INTEGER, PRIMARY KEY(`internalId`), FOREIGN KEY(`internalConversationId`) REFERENCES `Conversations`(`internalId`) ON UPDATE CASCADE ON DELETE CASCADE )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER, `token` TEXT, `id` INTEGER NOT NULL, `internalConversationId` TEXT, `actorType` TEXT, `actorId` TEXT, `actorDisplayName` TEXT, `timestamp` INTEGER NOT NULL, `systemMessage` TEXT, `messageType` TEXT, `isReplyable` INTEGER NOT NULL, `message` TEXT, `messageParameters` TEXT, `expirationTimestamp` INTEGER NOT NULL, `parent` INTEGER, `reactions` TEXT, `reactionsSelf` TEXT, `markdown` INTEGER, `lastEditActorType` TEXT, `lastEditActorId` TEXT, `lastEditActorDisplayName` TEXT, `lastEditTimestamp` INTEGER, `deleted` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`internalConversationId`) REFERENCES `Conversations`(`internalId`) ON UPDATE CASCADE ON DELETE CASCADE )", "fields": [ { "fieldPath": "internalId", @@ -577,6 +577,12 @@ "columnName": "lastEditTimestamp", "affinity": "INTEGER", "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": true } ], "primaryKey": { @@ -667,7 +673,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '93ef64fac7a9a811c4a3c2f5a6406f87')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '234cdb754d42d9ebf2349763a58a4578')" ] } } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 7d934430a..ce35f217e 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -829,7 +829,7 @@ class ChatActivity : this.lifecycleScope.launch { chatViewModel.getUpdateMessageFlow .onEach { - updateAdapterForReaction(it) + updateMessageInsideAdapter(it) } .collect() } @@ -2923,42 +2923,17 @@ class ChatActivity : private fun handleSystemMessages(chatMessageList: List): List { val chatMessageMap = chatMessageList.map { it.id to it }.toMap().toMutableMap() + val chatMessageIterator = chatMessageMap.iterator() while (chatMessageIterator.hasNext()) { val currentMessage = chatMessageIterator.next() - // setDeletionFlagsAndRemoveInfomessages - if (isInfoMessageAboutDeletion(currentMessage)) { - if (!chatMessageMap.containsKey(currentMessage.value.parentMessageId.toString())) { - // if chatMessageMap doesn't contain message to delete (this happens when lookingIntoFuture), - // the message to delete has to be modified directly inside the adapter - - val id = currentMessage.value.parentMessageId.toString() - val index = adapter?.getMessagePositionById(id) ?: 0 - - if (index > 0) { - val message = adapter?.items?.get(index)?.item as ChatMessage - setMessageAsDeleted(message) - } - } else { - chatMessageMap[currentMessage.value.parentMessageId.toString()]!!.isDeleted = true - } - chatMessageIterator.remove() - } else if (isReactionsMessage(currentMessage)) { - // delete reactions system messages - if (!chatMessageMap.containsKey(currentMessage.value.parentMessageId.toString())) { - // updateAdapterForReaction(currentMessage.value.parentMessage) TODO - } - - chatMessageIterator.remove() - } else if (isPollVotedMessage(currentMessage)) { - // delete poll system messages - chatMessageIterator.remove() - } else if (isEditMessage(currentMessage)) { - if (!chatMessageMap.containsKey(currentMessage.value.parentMessageId.toString())) { - // setMessageAsEdited(currentMessage.value.parentMessage) TODO - } + if (isInfoMessageAboutDeletion(currentMessage) || + isReactionsMessage(currentMessage) || + isPollVotedMessage(currentMessage) || + isEditMessage(currentMessage) + ) { chatMessageIterator.remove() } } @@ -3401,10 +3376,11 @@ class ChatActivity : adapter?.update(messageTemp) } - private fun updateAdapterForReaction(message: IMessage?) { + private fun updateMessageInsideAdapter(message: IMessage?) { message?.let { val messageTemp = message as ChatMessage + // TODO is this needed? messageTemp.isOneToOneConversation = currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL messageTemp.activeUser = conversationUser diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/ChatMessageRepository.kt b/app/src/main/java/com/nextcloud/talk/chat/data/ChatMessageRepository.kt index 1b1696b16..6b2a43f15 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/data/ChatMessageRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/data/ChatMessageRepository.kt @@ -9,8 +9,6 @@ package com.nextcloud.talk.chat.data import android.os.Bundle import com.nextcloud.talk.chat.data.io.LifecycleAwareManager -import com.nextcloud.talk.models.json.chat.ChatMessageJson -import com.nextcloud.talk.data.sync.Syncable import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.models.domain.ConversationModel import kotlinx.coroutines.Job diff --git a/app/src/main/java/com/nextcloud/talk/chat/data/network/OfflineFirstChatRepository.kt b/app/src/main/java/com/nextcloud/talk/chat/data/network/OfflineFirstChatRepository.kt index 4790645da..a4a141151 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/data/network/OfflineFirstChatRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/data/network/OfflineFirstChatRepository.kt @@ -415,9 +415,7 @@ class OfflineFirstChatRepository @Inject constructor( if (result.second.isNotEmpty()) { val chatMessagesJson = result.second - if (lookIntoFuture) { - handleUpdateMessages(chatMessagesJson) - } + handleUpdateMessages(chatMessagesJson) chatMessagesFromSync = chatMessagesJson.map { it.asEntity(currentUser.id!!) @@ -467,7 +465,14 @@ class OfflineFirstChatRepository @Inject constructor( private suspend fun handleUpdateMessages(messagesJson: List) { messagesJson.forEach { messageJson -> when (messageJson.systemMessageType) { - ChatMessage.SystemMessageType.REACTION -> { + ChatMessage.SystemMessageType.REACTION, + ChatMessage.SystemMessageType.REACTION_REVOKED, + ChatMessage.SystemMessageType.REACTION_DELETED, + ChatMessage.SystemMessageType.MESSAGE_DELETED, + ChatMessage.SystemMessageType.POLL_VOTED, + ChatMessage.SystemMessageType.MESSAGE_EDITED -> { + // the parent message is always the newest state, no matter how old the system message is. + // that's why we can just take the parent, update it in DB and update the UI messageJson.parentMessage?.let { parentMessageJson -> val parentMessageEntity = parentMessageJson.asEntity(currentUser.id!!) chatDao.upsertChatMessage(parentMessageEntity) @@ -475,26 +480,6 @@ class OfflineFirstChatRepository @Inject constructor( } } - ChatMessage.SystemMessageType.REACTION_REVOKED -> { - // TODO - } - - ChatMessage.SystemMessageType.REACTION_DELETED -> { - // TODO - } - - ChatMessage.SystemMessageType.MESSAGE_DELETED -> { - // TODO - } - - ChatMessage.SystemMessageType.POLL_VOTED -> { - // TODO - } - - ChatMessage.SystemMessageType.MESSAGE_EDITED -> { - // TODO - } - ChatMessage.SystemMessageType.CLEARED_CHAT -> { val pattern = "$internalConversationId%" // LIKE "@@%" chatDao.clearAllMessagesForUser(pattern) diff --git a/app/src/main/java/com/nextcloud/talk/data/database/mappers/ChatMessageMapUtils.kt b/app/src/main/java/com/nextcloud/talk/data/database/mappers/ChatMessageMapUtils.kt index a8cbb4178..ca4a411b5 100644 --- a/app/src/main/java/com/nextcloud/talk/data/database/mappers/ChatMessageMapUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/data/database/mappers/ChatMessageMapUtils.kt @@ -38,7 +38,8 @@ fun ChatMessageJson.asEntity(accountId: Long) = lastEditActorDisplayName = lastEditActorDisplayName, lastEditActorId = lastEditActorId, lastEditActorType = lastEditActorType, - lastEditTimestamp = lastEditTimestamp + lastEditTimestamp = lastEditTimestamp, + deleted = deleted ) fun ChatMessageEntity.asModel() = @@ -62,7 +63,8 @@ fun ChatMessageEntity.asModel() = lastEditActorDisplayName = lastEditActorDisplayName, lastEditActorId = lastEditActorId, lastEditActorType = lastEditActorType, - lastEditTimestamp = lastEditTimestamp + lastEditTimestamp = lastEditTimestamp, + isDeleted = deleted ) fun ChatMessageJson.asModel() = @@ -86,5 +88,6 @@ fun ChatMessageJson.asModel() = lastEditActorDisplayName = lastEditActorDisplayName, lastEditActorId = lastEditActorId, lastEditActorType = lastEditActorType, - lastEditTimestamp = lastEditTimestamp + lastEditTimestamp = lastEditTimestamp, + isDeleted = deleted ) diff --git a/app/src/main/java/com/nextcloud/talk/data/database/model/ChatMessageEntity.kt b/app/src/main/java/com/nextcloud/talk/data/database/model/ChatMessageEntity.kt index b0c1d69b6..48e0f105b 100644 --- a/app/src/main/java/com/nextcloud/talk/data/database/model/ChatMessageEntity.kt +++ b/app/src/main/java/com/nextcloud/talk/data/database/model/ChatMessageEntity.kt @@ -58,6 +58,7 @@ data class ChatMessageEntity( @ColumnInfo(name = "lastEditActorType") var lastEditActorType: String? = null, @ColumnInfo(name = "lastEditActorId") var lastEditActorId: String? = null, @ColumnInfo(name = "lastEditActorDisplayName") var lastEditActorDisplayName: String? = null, - @ColumnInfo(name = "lastEditTimestamp") var lastEditTimestamp: Long? = 0 + @ColumnInfo(name = "lastEditTimestamp") var lastEditTimestamp: Long? = 0, + @ColumnInfo(name = "deleted") var deleted: Boolean = false, // TODO: add "silent" ) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessageJson.kt b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessageJson.kt index 1cbacea25..01a984c66 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessageJson.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessageJson.kt @@ -18,7 +18,7 @@ import kotlinx.parcelize.Parcelize @Parcelize @JsonObject data class ChatMessageJson( - @JsonField(name = ["id"]) override var id: Long = 0, + @JsonField(name = ["id"]) var id: Long = 0, @JsonField(name = ["token"]) var token: String? = null, @JsonField(name = ["actorType"]) var actorType: String? = null, @JsonField(name = ["actorId"]) var actorId: String? = null, @@ -43,7 +43,5 @@ data class ChatMessageJson( @JsonField(name = ["lastEditActorId"]) var lastEditActorId: String? = null, @JsonField(name = ["lastEditActorType"]) var lastEditActorType: String? = null, @JsonField(name = ["lastEditTimestamp"]) var lastEditTimestamp: Long? = 0, - - // override var markedForDeletion: Boolean = "comment_deleted" == messageType - override var markedForDeletion: Boolean = false -) : Parcelable, SyncableModel + @JsonField(name = ["deleted"]) var deleted: Boolean = false, +) : Parcelable