diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index e76fd7f71..80d44b838 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -194,6 +194,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -444,7 +445,7 @@ class ChatActivity : this.lifecycleScope.launch { delay(DELAY_TO_SHOW_PROGRESS_BAR) - if (adapter?.isEmpty == true) { + if (adapter?.isEmpty == true && networkMonitor.isOnline.first()) { binding.progressBar.visibility = View.VISIBLE } } @@ -939,6 +940,20 @@ class ChatActivity : .collect() } + this.lifecycleScope.launch { + chatViewModel.getGeneralUIFlow.onEach { key -> + when (key) { + NO_OFFLINE_MESSAGES_FOUND -> { + if (networkMonitor.isOnline.first().not()) { + binding.offline.root.visibility = View.VISIBLE + } + } + + else -> {} + } + }.collect() + } + chatViewModel.reactionDeletedViewState.observe(this) { state -> when (state) { is ChatViewModel.ReactionDeletedSuccessState -> { @@ -2810,14 +2825,10 @@ class ChatActivity : message1.timestamp ) val isLessThan5Min = timeDifference > FIVE_MINUTES_IN_SECONDS - if (isSameDayMessages(message2, message1) && + return isSameDayMessages(message2, message1) && (message2.actorId == message1.actorId) && (!isLessThan5Min) && (message2.lastEditTimestamp == 0L || message1.lastEditTimestamp == 0L) - ) { - return true - } - return false } private fun determinePreviousMessageIds(chatMessageList: List) { @@ -3848,5 +3859,6 @@ class ChatActivity : private const val DELAY_TO_SHOW_PROGRESS_BAR = 1000L private const val FIVE_MINUTES_IN_SECONDS: Long = 300 const val CONVERSATION_INTERNAL_ID = "CONVERSATION_INTERNAL_ID" + const val NO_OFFLINE_MESSAGES_FOUND = "NO_OFFLINE_MESSAGES_FOUND" } } 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 860da6c21..5cbf39efe 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 @@ -35,6 +35,12 @@ interface ChatMessageRepository : LifecycleAwareManager { val lastReadMessageFlow: Flow + /** + * Used for informing the user of the underlying processing behind offline support, [String] is the key + * which is handled in a switch statement in ChatActivity. + */ + val generalUIFlow: Flow + fun setData(conversationModel: ConversationModel, credentials: String, urlForChatting: String) fun loadInitialMessages(withNetworkParams: Bundle): Job 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 361f40ce0..e29628866 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 com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.chat.data.ChatMessageRepository import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.data.database.dao.ChatBlocksDao @@ -91,6 +92,11 @@ class OfflineFirstChatRepository @Inject constructor( private val _lastReadMessageFlow: MutableSharedFlow = MutableSharedFlow() + override val generalUIFlow: Flow + get() = _generalUIFlow + + private val _generalUIFlow: MutableSharedFlow = MutableSharedFlow() + private var newXChatLastCommonRead: Int? = null private var itIsPaused = false private val scope = CoroutineScope(Dispatchers.IO) @@ -133,6 +139,7 @@ class OfflineFirstChatRepository @Inject constructor( } else { if (!weAlreadyHaveSomeOfflineMessages) { Log.d(TAG, "An online request for newest 100 messages is made because offline chat is empty") + _generalUIFlow.emit(ChatActivity.NO_OFFLINE_MESSAGES_FOUND) } else { Log.d( TAG, diff --git a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt index 7ec377bc1..1798d7403 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt @@ -137,6 +137,8 @@ class ChatViewModel @Inject constructor( _getRoomViewState.value = GetRoomErrorState } + val getGeneralUIFlow = chatRepository.generalUIFlow + sealed interface ViewState object GetReminderStartState : ViewState diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index c6d5e791b..23e4c9de8 100644 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -98,6 +98,12 @@ android:layout_height="0dp" android:layout_weight="1"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0e5244921..700af1ab2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -834,6 +834,7 @@ How to translate with transifex: Archived Once a conversation is archived, it will be hidden by default. Select the filter \"Archived\" to view archived conversations. Direct mentions will still be received. Once a conversation is unarchived, it will be shown by default again. + No offline messages saved Previously set Failed to set conversation Read-only Status Reverted