mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-22 04:55:29 +03:00
implement lastCommonRead handling
contains one workaround for now, see TODO in updateUiForLastCommonRead method Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
5bccdada7c
commit
0390c93ed2
9 changed files with 65 additions and 23 deletions
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 10,
|
||||
"identityHash": "234cdb754d42d9ebf2349763a58a4578",
|
||||
"identityHash": "1b97b7e937102e4087f8534f1204fe94",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "User",
|
||||
|
@ -138,7 +138,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "Conversations",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER, `token` TEXT, `name` TEXT, `displayName` TEXT, `description` TEXT, `type` TEXT, `lastPing` INTEGER NOT NULL, `participantType` TEXT, `hasPassword` INTEGER NOT NULL, `sessionId` TEXT, `actorId` TEXT, `actorType` TEXT, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `unreadMention` INTEGER NOT NULL, `lastMessageJson` TEXT, `objectType` TEXT, `notificationLevel` TEXT, `readOnly` TEXT, `lobbyState` TEXT, `lobbyTimer` INTEGER, `lastReadMessage` INTEGER NOT NULL, `hasCall` INTEGER NOT NULL, `callFlag` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `canLeaveConversation` INTEGER, `canDeleteConversation` INTEGER, `unreadMentionDirect` INTEGER, `notificationCalls` INTEGER, `permissions` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `status` TEXT, `statusIcon` TEXT, `statusMessage` TEXT, `statusClearAt` INTEGER, `callRecording` INTEGER NOT NULL, `avatarVersion` TEXT, `isCustomAvatar` INTEGER, `callStartTime` INTEGER, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER, `token` TEXT, `name` TEXT, `displayName` TEXT, `description` TEXT, `type` TEXT, `lastPing` INTEGER NOT NULL, `participantType` TEXT, `hasPassword` INTEGER NOT NULL, `sessionId` TEXT, `actorId` TEXT, `actorType` TEXT, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `unreadMention` INTEGER NOT NULL, `lastMessageJson` TEXT, `objectType` TEXT, `notificationLevel` TEXT, `readOnly` TEXT, `lobbyState` TEXT, `lobbyTimer` INTEGER, `lastReadMessage` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `hasCall` INTEGER NOT NULL, `callFlag` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `canLeaveConversation` INTEGER, `canDeleteConversation` INTEGER, `unreadMentionDirect` INTEGER, `notificationCalls` INTEGER, `permissions` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `status` TEXT, `statusIcon` TEXT, `statusMessage` TEXT, `statusClearAt` INTEGER, `callRecording` INTEGER NOT NULL, `avatarVersion` TEXT, `isCustomAvatar` INTEGER, `callStartTime` INTEGER, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "internalId",
|
||||
|
@ -284,6 +284,12 @@
|
|||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastCommonReadMessage",
|
||||
"columnName": "lastCommonReadMessage",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "hasCall",
|
||||
"columnName": "hasCall",
|
||||
|
@ -673,7 +679,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, '234cdb754d42d9ebf2349763a58a4578')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1b97b7e937102e4087f8534f1204fe94')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -834,6 +834,14 @@ class ChatActivity :
|
|||
.collect()
|
||||
}
|
||||
|
||||
this.lifecycleScope.launch {
|
||||
chatViewModel.getLastCommonReadFlow
|
||||
.onEach {
|
||||
updateReadStatusOfAllMessages(it)
|
||||
}
|
||||
.collect()
|
||||
}
|
||||
|
||||
chatViewModel.reactionDeletedViewState.observe(this) { state ->
|
||||
when (state) {
|
||||
is ChatViewModel.ReactionDeletedSuccessState -> {
|
||||
|
@ -2526,6 +2534,7 @@ class ChatActivity :
|
|||
updateReadStatusOfMessage(message, it)
|
||||
}
|
||||
}
|
||||
adapter!!.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ interface ChatMessageRepository : LifecycleAwareManager {
|
|||
|
||||
val updateMessageFlow: Flow<ChatMessage>
|
||||
|
||||
val lastCommonReadFlow: Flow<Int>
|
||||
|
||||
fun setData(
|
||||
conversationModel: ConversationModel,
|
||||
credentials: String,
|
||||
|
|
|
@ -30,6 +30,7 @@ import io.reactivex.schedulers.Schedulers
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
@ -72,6 +73,13 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||
private val _updateMessageFlow:
|
||||
MutableSharedFlow<ChatMessage> = MutableSharedFlow()
|
||||
|
||||
override val lastCommonReadFlow:
|
||||
Flow<Int>
|
||||
get() = _lastCommonReadFlow
|
||||
|
||||
private val _lastCommonReadFlow:
|
||||
MutableSharedFlow<Int> = MutableSharedFlow()
|
||||
|
||||
private var newXChatLastCommonRead: Int? = null
|
||||
private var itIsPaused = false
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
|
@ -96,6 +104,8 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||
scope.launch {
|
||||
Log.d(TAG, "---- loadInitialMessages ------------")
|
||||
|
||||
newXChatLastCommonRead = conversationModel.lastCommonReadMessage
|
||||
|
||||
val fieldMap = getFieldMap(
|
||||
lookIntoFuture = false,
|
||||
includeLastKnown = true,
|
||||
|
@ -113,10 +123,24 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||
internalConversationId,
|
||||
chatDao.getNewestMessageId(internalConversationId)
|
||||
)
|
||||
updateUiForLastCommonRead()
|
||||
|
||||
initMessagePolling()
|
||||
}
|
||||
|
||||
private fun updateUiForLastCommonRead(){
|
||||
scope.launch {
|
||||
// TODO improve...
|
||||
// delay is a dirty workaround to make sure messages are added to adapter on initial load before setting
|
||||
// their read status.
|
||||
// This workaround causes that the checkmarks seem to switch whenever sending a message
|
||||
delay(200)
|
||||
newXChatLastCommonRead?.let {
|
||||
_lastCommonReadFlow.emit(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadMoreMessages(
|
||||
beforeMessageId: Long,
|
||||
roomToken: String,
|
||||
|
@ -141,6 +165,7 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||
}
|
||||
|
||||
showLast100MessagesBefore(internalConversationId, beforeMessageId)
|
||||
updateUiForLastCommonRead()
|
||||
}
|
||||
|
||||
override fun initMessagePolling(): Job =
|
||||
|
@ -174,6 +199,8 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||
_messageFlow.emit(pair)
|
||||
}
|
||||
|
||||
updateUiForLastCommonRead()
|
||||
|
||||
// Process read status if not null
|
||||
// val lastKnown = datastore.getLastKnownId(internalConversationId, 0)
|
||||
// list = list.map { chatMessage ->
|
||||
|
@ -245,9 +272,9 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||
fieldMap["lastKnownMessageId"] = lastKnown
|
||||
}
|
||||
|
||||
// newXChatLastCommonRead?.let {
|
||||
// fieldMap["lastCommonReadId"] = if (it > 0) it else lastKnown
|
||||
// }
|
||||
newXChatLastCommonRead?.let {
|
||||
fieldMap["lastCommonReadId"] = it
|
||||
}
|
||||
|
||||
fieldMap["timeout"] = if (lookIntoFuture) 30 else 0
|
||||
fieldMap["limit"] = 100
|
||||
|
@ -291,26 +318,13 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
// .timeout(3, TimeUnit.SECONDS)
|
||||
.map {
|
||||
.map { it ->
|
||||
when (it.code()) {
|
||||
HTTP_CODE_OK -> {
|
||||
Log.d(TAG, "getMessagesFromServer HTTP_CODE_OK")
|
||||
// newXChatLastCommonRead = it.headers()["X-Chat-Last-Common-Read"]?.let {
|
||||
// Integer.parseInt(it)
|
||||
// }
|
||||
//
|
||||
// val xChatLastGivenHeader: String? = it.headers()["X-Chat-Last-Given"]
|
||||
// val lastKnownId = if (it.headers().size > 0 &&
|
||||
// xChatLastGivenHeader?.isNotEmpty() == true
|
||||
// ) {
|
||||
// xChatLastGivenHeader.toInt()
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// // if (lastKnownId > 0) {
|
||||
// datastore.saveLastKnownId(internalConversationId, lastKnownId)
|
||||
// // }
|
||||
newXChatLastCommonRead = it.headers()["X-Chat-Last-Common-Read"]?.let {
|
||||
Integer.parseInt(it)
|
||||
}
|
||||
|
||||
return@map Pair(
|
||||
HTTP_CODE_OK,
|
||||
|
|
|
@ -120,6 +120,8 @@ class ChatViewModel @Inject constructor(
|
|||
|
||||
val getUpdateMessageFlow = chatRepository.updateMessageFlow
|
||||
|
||||
val getLastCommonReadFlow = chatRepository.lastCommonReadFlow
|
||||
|
||||
val getConversationFlow = conversationRepository.conversationFlow
|
||||
.onEach {
|
||||
_getRoomViewState.value = GetRoomSuccessState
|
||||
|
|
|
@ -38,6 +38,7 @@ fun ConversationModel.asEntity() =
|
|||
lobbyState = lobbyState,
|
||||
lobbyTimer = lobbyTimer,
|
||||
lastReadMessage = lastReadMessage,
|
||||
lastCommonReadMessage = lastCommonReadMessage,
|
||||
hasCall = hasCall,
|
||||
callFlag = callFlag,
|
||||
canStartCall = canStartCall,
|
||||
|
@ -86,6 +87,7 @@ fun ConversationEntity.asModel() =
|
|||
lobbyState = lobbyState,
|
||||
lobbyTimer = lobbyTimer,
|
||||
lastReadMessage = lastReadMessage,
|
||||
lastCommonReadMessage = lastCommonReadMessage,
|
||||
hasCall = hasCall,
|
||||
callFlag = callFlag,
|
||||
canStartCall = canStartCall,
|
||||
|
@ -134,6 +136,7 @@ fun Conversation.asEntity(accountId: Long) =
|
|||
lobbyState = lobbyState,
|
||||
lobbyTimer = lobbyTimer,
|
||||
lastReadMessage = lastReadMessage,
|
||||
lastCommonReadMessage = lastCommonReadMessage,
|
||||
hasCall = hasCall,
|
||||
callFlag = callFlag,
|
||||
canStartCall = canStartCall,
|
||||
|
|
|
@ -68,6 +68,7 @@ data class ConversationEntity(
|
|||
@ColumnInfo(name = "lobbyState") var lobbyState: ConversationEnums.LobbyState? = null,
|
||||
@ColumnInfo(name = "lobbyTimer") var lobbyTimer: Long? = null,
|
||||
@ColumnInfo(name = "lastReadMessage") var lastReadMessage: Int = 0,
|
||||
@ColumnInfo(name = "lastCommonReadMessage") var lastCommonReadMessage: Int = 0,
|
||||
@ColumnInfo(name = "hasCall") var hasCall: Boolean = false,
|
||||
@ColumnInfo(name = "callFlag") var callFlag: Int = 0,
|
||||
@ColumnInfo(name = "canStartCall") var canStartCall: Boolean = false,
|
||||
|
|
|
@ -41,6 +41,7 @@ class ConversationModel(
|
|||
var lobbyState: ConversationEnums.LobbyState? = null,
|
||||
var lobbyTimer: Long? = null,
|
||||
var lastReadMessage: Int = 0,
|
||||
var lastCommonReadMessage: Int = 0,
|
||||
var hasCall: Boolean = false,
|
||||
var callFlag: Int = 0,
|
||||
var canStartCall: Boolean = false,
|
||||
|
@ -101,6 +102,7 @@ class ConversationModel(
|
|||
lobbyState = conversation.lobbyState?.let { ConversationEnums.LobbyState.valueOf(it.name) },
|
||||
lobbyTimer = conversation.lobbyTimer,
|
||||
lastReadMessage = conversation.lastReadMessage,
|
||||
lastCommonReadMessage = conversation.lastCommonReadMessage,
|
||||
hasCall = conversation.hasCall,
|
||||
callFlag = conversation.callFlag,
|
||||
canStartCall = conversation.canStartCall,
|
||||
|
|
|
@ -90,6 +90,9 @@ data class Conversation(
|
|||
@JsonField(name = ["lastReadMessage"])
|
||||
var lastReadMessage: Int = 0,
|
||||
|
||||
@JsonField(name = ["lastCommonReadMessage"])
|
||||
var lastCommonReadMessage: Int = 0,
|
||||
|
||||
@JsonField(name = ["hasCall"])
|
||||
var hasCall: Boolean = false,
|
||||
|
||||
|
|
Loading…
Reference in a new issue