Forráskód Böngészése

handle special system messages in ChatRepo instead in UI

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 10 hónapja
szülő
commit
85f4d8cd92

+ 9 - 3
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')"
     ]
   }
 }

+ 9 - 33
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<ChatMessage>): List<ChatMessage> {
         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

+ 0 - 2
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

+ 9 - 24
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<ChatMessageJson>) {
         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 "<accountId>@<conversationId>@%"
                     chatDao.clearAllMessagesForUser(pattern)

+ 6 - 3
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
     )

+ 2 - 1
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"
 )

+ 3 - 5
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