handle special system messages in ChatRepo instead in UI
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Родитель
db8d7b91d4
Коммит
85f4d8cd92
|
@ -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')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче