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 8e2e3f3ed..9fb11ab1b 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 @@ -64,6 +64,8 @@ interface ChatMessageRepository : LifecycleAwareManager { withNetworkParams: Bundle ): Job + suspend fun updateRoomMessages(internalConversationId: String, limit: Int) + /** * Long polls the server for any updates to the chat, if found, it synchronizes * the database with the server and emits the new messages to [messageFlow], 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 5dff18e90..6be6a0abf 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 @@ -10,6 +10,7 @@ package com.nextcloud.talk.chat.data.network import android.os.Bundle import android.util.Log +import androidx.core.os.bundleOf import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.chat.data.ChatMessageRepository import com.nextcloud.talk.chat.data.model.ChatMessage @@ -28,6 +29,8 @@ import com.nextcloud.talk.models.json.chat.ChatOverall import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage import com.nextcloud.talk.models.json.converters.EnumActorTypeConverter import com.nextcloud.talk.models.json.participants.Participant +import com.nextcloud.talk.utils.CapabilitiesUtil +import com.nextcloud.talk.utils.SpreedFeatures import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import com.nextcloud.talk.utils.message.SendMessageUtils @@ -292,6 +295,24 @@ class OfflineFirstChatRepository @Inject constructor( updateUiForLastCommonRead() } + override suspend fun updateRoomMessages(internalConversationId: String, limit: Int) { + val lastKnown = chatDao.getNewestMessageId(internalConversationId) + + Log.d(TAG, "---- updateRoomMessages ------------ with lastKnown: $lastKnown") + val fieldMap = getFieldMap( + lookIntoFuture = true, + timeout = 0, + includeLastKnown = false, + setReadMarker = false, + lastKnown = lastKnown.toInt(), + markNotificationAsRead = false + ) + + val networkParams = bundleOf() + networkParams.putSerializable(BundleKeys.KEY_FIELD_MAP, fieldMap) + sync(networkParams) + } + override fun initMessagePolling(initialMessageId: Long): Job = scope.launch { Log.d(TAG, "---- initMessagePolling ------------") @@ -430,7 +451,8 @@ class OfflineFirstChatRepository @Inject constructor( includeLastKnown: Boolean, setReadMarker: Boolean, lastKnown: Int?, - limit: Int = DEFAULT_MESSAGES_LIMIT + limit: Int = DEFAULT_MESSAGES_LIMIT, + markNotificationAsRead: Boolean = true ): HashMap { val fieldMap = HashMap() @@ -449,6 +471,11 @@ class OfflineFirstChatRepository @Inject constructor( fieldMap["lookIntoFuture"] = if (lookIntoFuture) 1 else 0 fieldMap["setReadMarker"] = if (setReadMarker) 1 else 0 + val spreedCapabilities = currentUser.capabilities?.spreedCapability!! + if (CapabilitiesUtil.hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.CHAT_KEEP_NOTIFICATIONS)) { + fieldMap["markNotificationsAsRead"] = if (markNotificationAsRead) 1 else 0 + } + return fieldMap } diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 2c5e7c940..b6cd59d3a 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -514,6 +514,9 @@ class ConversationsListActivity : } private fun setConversationList(list: List) { + // Refreshes conversation messages in the background asynchronously + conversationsListViewModel.updateRoomMessages(credentials!!, list) + // Update Conversations conversationItems.clear() conversationItemsWithHeader.clear() @@ -828,7 +831,7 @@ class ConversationsListActivity : if (!hasFilterEnabled()) filterableConversationItems = searchableConversationItems adapter!!.updateDataSet(filterableConversationItems, false) adapter!!.showAllHeaders() - binding.swipeRefreshLayoutView?.isEnabled = false + binding.swipeRefreshLayoutView.isEnabled = false searchBehaviorSubject.onNext(true) return true } @@ -2077,7 +2080,8 @@ class ConversationsListActivity : private fun onMessageSearchError(throwable: Throwable) { handleHttpExceptions(throwable) - binding.swipeRefreshLayoutView?.isRefreshing = false + binding.swipeRefreshLayoutView.isRefreshing = false + showErrorDialog() } fun updateFilterState(mention: Boolean, unread: Boolean) { diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/viewmodels/ConversationsListViewModel.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/viewmodels/ConversationsListViewModel.kt index 8ccda33e5..ed6c2860e 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/viewmodels/ConversationsListViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/viewmodels/ConversationsListViewModel.kt @@ -10,21 +10,28 @@ import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.nextcloud.talk.chat.data.ChatMessageRepository import com.nextcloud.talk.conversationlist.data.OfflineConversationsRepository import com.nextcloud.talk.invitation.data.InvitationsModel import com.nextcloud.talk.invitation.data.InvitationsRepository +import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.users.UserManager +import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import io.reactivex.Observer import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import javax.inject.Inject class ConversationsListViewModel @Inject constructor( private val repository: OfflineConversationsRepository, + private val chatRepository: ChatMessageRepository, var userManager: UserManager ) : ViewModel() { @@ -88,6 +95,30 @@ class ConversationsListViewModel @Inject constructor( repository.getRooms() } + fun updateRoomMessages( + credentials: String, + list: List + ) { + val current = list.associateWith { model -> + val unreadMessages = model.unreadMessages + unreadMessages + } + val baseUrl = userManager.currentUser.blockingGet().baseUrl!! + viewModelScope.launch(Dispatchers.IO) { + for ((model, unreadMessages) in current) { + if (unreadMessages > 0) { + updateRoomMessage(model, unreadMessages, credentials, baseUrl) + } + } + } + } + + private suspend fun updateRoomMessage(model: ConversationModel, limit: Int, credentials: String, baseUrl: String) { + val urlForChatting = ApiUtils.getUrlForChat(1, baseUrl, model.token) // FIXME v1? + chatRepository.setData(model, credentials, urlForChatting) + chatRepository.updateRoomMessages(model.internalId, limit) + } + inner class FederatedInvitationsObserver : Observer { override fun onSubscribe(d: Disposable) { // unused atm diff --git a/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt b/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt index 90fdbe322..79dcae21c 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt @@ -56,7 +56,8 @@ enum class SpreedFeatures(val value: String) { DELETE_MESSAGES_UNLIMITED("delete-messages-unlimited"), BAN_V1("ban-v1"), EDIT_MESSAGES_NOTE_TO_SELF("edit-messages-note-to-self"), - ARCHIVE_CONVERSATIONS("archived-conversations-v2") + ARCHIVE_CONVERSATIONS("archived-conversations-v2"), + CHAT_KEEP_NOTIFICATIONS("chat-keep-notifications") } @Suppress("TooManyFunctions")