mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-12-18 22:52:04 +03:00
update temp messages also for initial pull of messages
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
aff7845e83
commit
1efc219e73
4 changed files with 47 additions and 45 deletions
|
@ -918,8 +918,7 @@ class ChatActivity :
|
||||||
this.lifecycleScope.launch {
|
this.lifecycleScope.launch {
|
||||||
chatViewModel.getRemoveMessageFlow
|
chatViewModel.getRemoveMessageFlow
|
||||||
.onEach {
|
.onEach {
|
||||||
adapter!!.delete(it)
|
removeMessageById(it.id)
|
||||||
adapter!!.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -1065,9 +1064,15 @@ class ChatActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeUnreadMessagesMarker() {
|
private fun removeUnreadMessagesMarker() {
|
||||||
val index = adapter?.getMessagePositionById(UNREAD_MESSAGES_MARKER_ID.toString())
|
removeMessageById(UNREAD_MESSAGES_MARKER_ID.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not use adapter.deleteById() as it seems to contain a bug! Use this method instead!
|
||||||
|
private fun removeMessageById(idToDelete: String) {
|
||||||
|
val index = adapter?.getMessagePositionById(idToDelete)
|
||||||
if (index != null && index != -1) {
|
if (index != null && index != -1) {
|
||||||
adapter?.items?.removeAt(index)
|
adapter?.items?.removeAt(index)
|
||||||
|
adapter?.notifyItemRemoved(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,14 +178,19 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||||
if (newestMessageIdFromDb.toInt() != 0) {
|
if (newestMessageIdFromDb.toInt() != 0) {
|
||||||
val limit = getCappedMessagesAmountOfChatBlock(newestMessageIdFromDb)
|
val limit = getCappedMessagesAmountOfChatBlock(newestMessageIdFromDb)
|
||||||
|
|
||||||
// TODO: somewhere here also handle temp messages. updateUiMessages(chatMessages, showUnreadMessagesMarker)
|
|
||||||
|
|
||||||
|
val list = getMessagesBeforeAndEqual(
|
||||||
showMessagesBeforeAndEqual(
|
|
||||||
internalConversationId,
|
|
||||||
newestMessageIdFromDb,
|
newestMessageIdFromDb,
|
||||||
|
internalConversationId,
|
||||||
limit
|
limit
|
||||||
)
|
)
|
||||||
|
if (list.isNotEmpty()) {
|
||||||
|
updateUiMessages(
|
||||||
|
chatMessages = list,
|
||||||
|
lookIntoFuture = false,
|
||||||
|
showUnreadMessagesMarker = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// delay is a dirty workaround to make sure messages are added to adapter on initial load before dealing
|
// delay is a dirty workaround to make sure messages are added to adapter on initial load before dealing
|
||||||
// with them (otherwise there is a race condition).
|
// with them (otherwise there is a race condition).
|
||||||
|
@ -302,7 +307,11 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||||
val weHaveMessagesFromOurself = chatMessages.any { it.actorId == currentUser.userId }
|
val weHaveMessagesFromOurself = chatMessages.any { it.actorId == currentUser.userId }
|
||||||
showUnreadMessagesMarker = showUnreadMessagesMarker && !weHaveMessagesFromOurself
|
showUnreadMessagesMarker = showUnreadMessagesMarker && !weHaveMessagesFromOurself
|
||||||
|
|
||||||
updateUiMessages(chatMessages, showUnreadMessagesMarker)
|
updateUiMessages(
|
||||||
|
chatMessages = chatMessages,
|
||||||
|
lookIntoFuture = true,
|
||||||
|
showUnreadMessagesMarker = showUnreadMessagesMarker
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "resultsFromSync are null or empty")
|
Log.d(TAG, "resultsFromSync are null or empty")
|
||||||
}
|
}
|
||||||
|
@ -325,25 +334,30 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun updateUiMessages(chatMessages : List<ChatMessage>, showUnreadMessagesMarker: Boolean) {
|
private suspend fun updateUiMessages(
|
||||||
|
chatMessages : List<ChatMessage>,
|
||||||
|
lookIntoFuture: Boolean,
|
||||||
|
showUnreadMessagesMarker: Boolean
|
||||||
|
) {
|
||||||
|
// remove all temp messages from UI
|
||||||
val oldTempMessages = chatDao.getTempMessagesForConversation(internalConversationId)
|
val oldTempMessages = chatDao.getTempMessagesForConversation(internalConversationId)
|
||||||
.first()
|
.first()
|
||||||
.map(ChatMessageEntity::asModel)
|
.map(ChatMessageEntity::asModel)
|
||||||
|
|
||||||
oldTempMessages.forEach { _removeMessageFlow.emit(it) }
|
oldTempMessages.forEach { _removeMessageFlow.emit(it) }
|
||||||
|
|
||||||
val tripleChatMessages = Triple(true, showUnreadMessagesMarker, chatMessages)
|
// add new messages to UI
|
||||||
|
val tripleChatMessages = Triple(lookIntoFuture, showUnreadMessagesMarker, chatMessages)
|
||||||
_messageFlow.emit(tripleChatMessages)
|
_messageFlow.emit(tripleChatMessages)
|
||||||
|
|
||||||
|
// remove temp messages from DB that are now found in the new messages
|
||||||
val chatMessagesReferenceIds = chatMessages.mapTo(HashSet(chatMessages.size)) { it.referenceId }
|
val chatMessagesReferenceIds = chatMessages.mapTo(HashSet(chatMessages.size)) { it.referenceId }
|
||||||
val tempChatMessagesThatCanBeReplaced = oldTempMessages.filter { it.referenceId in chatMessagesReferenceIds }
|
val tempChatMessagesThatCanBeReplaced = oldTempMessages.filter { it.referenceId in chatMessagesReferenceIds }
|
||||||
|
|
||||||
chatDao.deleteTempChatMessages(
|
chatDao.deleteTempChatMessages(
|
||||||
internalConversationId,
|
internalConversationId,
|
||||||
tempChatMessagesThatCanBeReplaced.map { it.referenceId!! }
|
tempChatMessagesThatCanBeReplaced.map { it.referenceId!! }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// add the remaining temp messages to UI again
|
||||||
val remainingTempMessages = chatDao.getTempMessagesForConversation(internalConversationId)
|
val remainingTempMessages = chatDao.getTempMessagesForConversation(internalConversationId)
|
||||||
.first()
|
.first()
|
||||||
.map(ChatMessageEntity::asModel)
|
.map(ChatMessageEntity::asModel)
|
||||||
|
@ -706,7 +720,6 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun showMessagesBeforeAndEqual(internalConversationId: String, messageId: Long, limit: Int) {
|
|
||||||
suspend fun getMessagesBeforeAndEqual(
|
suspend fun getMessagesBeforeAndEqual(
|
||||||
messageId: Long,
|
messageId: Long,
|
||||||
internalConversationId: String,
|
internalConversationId: String,
|
||||||
|
@ -720,17 +733,6 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||||
it.map(ChatMessageEntity::asModel)
|
it.map(ChatMessageEntity::asModel)
|
||||||
}.first()
|
}.first()
|
||||||
|
|
||||||
val list = getMessagesBeforeAndEqual(
|
|
||||||
messageId,
|
|
||||||
internalConversationId,
|
|
||||||
limit
|
|
||||||
)
|
|
||||||
|
|
||||||
if (list.isNotEmpty()) {
|
|
||||||
val triple = Triple(false, false, list)
|
|
||||||
_messageFlow.emit(triple)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun showMessagesBefore(internalConversationId: String, messageId: Long, limit: Int) {
|
private suspend fun showMessagesBefore(internalConversationId: String, messageId: Long, limit: Int) {
|
||||||
suspend fun getMessagesBefore(
|
suspend fun getMessagesBefore(
|
||||||
|
@ -835,9 +837,6 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||||
message.toString(),
|
message.toString(),
|
||||||
referenceId
|
referenceId
|
||||||
)
|
)
|
||||||
// accessing internalConversationId creates UninitializedPropertyException because ChatViewModel and
|
|
||||||
// MessageInputViewModel use different instances of ChatRepository for now
|
|
||||||
|
|
||||||
|
|
||||||
chatDao.upsertChatMessage(tempChatMessageEntity)
|
chatDao.upsertChatMessage(tempChatMessageEntity)
|
||||||
|
|
||||||
|
@ -847,9 +846,6 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||||
|
|
||||||
val triple = Triple(true, false, listOf(tempChatMessageModel))
|
val triple = Triple(true, false, listOf(tempChatMessageModel))
|
||||||
_messageFlow.emit(triple)
|
_messageFlow.emit(triple)
|
||||||
|
|
||||||
// emit()
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Something went wrong when adding temporary message", e)
|
Log.e(TAG, "Something went wrong when adding temporary message", e)
|
||||||
emit(Result.failure(e))
|
emit(Result.failure(e))
|
||||||
|
|
|
@ -151,8 +151,6 @@ class MessageInputViewModel @Inject constructor(
|
||||||
replyTo: Int,
|
replyTo: Int,
|
||||||
sendWithoutNotification: Boolean
|
sendWithoutNotification: Boolean
|
||||||
) {
|
) {
|
||||||
// TODO: add temporary message with ref id
|
|
||||||
|
|
||||||
val referenceId = SendMessageUtils().generateReferenceId()
|
val referenceId = SendMessageUtils().generateReferenceId()
|
||||||
Log.d(TAG, "Random SHA-256 Hash: $referenceId")
|
Log.d(TAG, "Random SHA-256 Hash: $referenceId")
|
||||||
|
|
||||||
|
@ -173,7 +171,6 @@ class MessageInputViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isQueueing) {
|
if (isQueueing) {
|
||||||
val tempID = System.currentTimeMillis().toInt()
|
val tempID = System.currentTimeMillis().toInt()
|
||||||
val qMsg = QueuedMessage(tempID, message, displayName, replyTo, sendWithoutNotification)
|
val qMsg = QueuedMessage(tempID, message, displayName, replyTo, sendWithoutNotification)
|
||||||
|
|
|
@ -99,6 +99,7 @@ interface ChatMessagesDao {
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM ChatMessages
|
FROM ChatMessages
|
||||||
WHERE internalConversationId = :internalConversationId AND id >= :messageId
|
WHERE internalConversationId = :internalConversationId AND id >= :messageId
|
||||||
|
AND isTemporary = 0
|
||||||
ORDER BY timestamp ASC, id ASC
|
ORDER BY timestamp ASC, id ASC
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@ -109,6 +110,7 @@ interface ChatMessagesDao {
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM ChatMessages
|
FROM ChatMessages
|
||||||
WHERE internalConversationId = :internalConversationId
|
WHERE internalConversationId = :internalConversationId
|
||||||
|
AND isTemporary = 0
|
||||||
AND id < :messageId
|
AND id < :messageId
|
||||||
ORDER BY timestamp DESC, id DESC
|
ORDER BY timestamp DESC, id DESC
|
||||||
LIMIT :limit
|
LIMIT :limit
|
||||||
|
@ -125,6 +127,7 @@ interface ChatMessagesDao {
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM ChatMessages
|
FROM ChatMessages
|
||||||
WHERE internalConversationId = :internalConversationId
|
WHERE internalConversationId = :internalConversationId
|
||||||
|
AND isTemporary = 0
|
||||||
AND id <= :messageId
|
AND id <= :messageId
|
||||||
ORDER BY timestamp DESC, id DESC
|
ORDER BY timestamp DESC, id DESC
|
||||||
LIMIT :limit
|
LIMIT :limit
|
||||||
|
@ -141,6 +144,7 @@ interface ChatMessagesDao {
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM ChatMessages
|
FROM ChatMessages
|
||||||
WHERE internalConversationId = :internalConversationId
|
WHERE internalConversationId = :internalConversationId
|
||||||
|
AND isTemporary = 0
|
||||||
AND id BETWEEN :newestMessageId AND :oldestMessageId
|
AND id BETWEEN :newestMessageId AND :oldestMessageId
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue