Shows if no offline messages are saved

Signed-off-by: rapterjet2004 <juliuslinus1@gmail.com>
This commit is contained in:
rapterjet2004 2024-10-28 08:27:34 -05:00
parent 3908d0ce14
commit b0f404324c
No known key found for this signature in database
GPG key ID: 3AA5FDFED7944099
7 changed files with 81 additions and 6 deletions

View file

@ -114,6 +114,7 @@ import com.nextcloud.talk.chat.viewmodels.ChatViewModel
import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel
import com.nextcloud.talk.conversationinfo.ConversationInfoActivity import com.nextcloud.talk.conversationinfo.ConversationInfoActivity
import com.nextcloud.talk.conversationlist.ConversationsListActivity import com.nextcloud.talk.conversationlist.ConversationsListActivity
import com.nextcloud.talk.data.network.NetworkMonitor
import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivityChatBinding import com.nextcloud.talk.databinding.ActivityChatBinding
import com.nextcloud.talk.events.UserMentionClickEvent import com.nextcloud.talk.events.UserMentionClickEvent
@ -189,6 +190,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -236,6 +238,9 @@ class ChatActivity :
@Inject @Inject
lateinit var viewModelFactory: ViewModelProvider.Factory lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject
lateinit var networkMonitor: NetworkMonitor
lateinit var chatViewModel: ChatViewModel lateinit var chatViewModel: ChatViewModel
lateinit var messageInputViewModel: MessageInputViewModel lateinit var messageInputViewModel: MessageInputViewModel
@ -422,7 +427,7 @@ class ChatActivity :
this.lifecycleScope.launch { this.lifecycleScope.launch {
delay(DELAY_TO_SHOW_PROGRESS_BAR) delay(DELAY_TO_SHOW_PROGRESS_BAR)
if (adapter?.isEmpty == true) { if (adapter?.isEmpty == true && networkMonitor.isOnline.first()) {
binding.progressBar.visibility = View.VISIBLE binding.progressBar.visibility = View.VISIBLE
} }
} }
@ -919,6 +924,20 @@ class ChatActivity :
.collect() .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 -> chatViewModel.reactionDeletedViewState.observe(this) { state ->
when (state) { when (state) {
is ChatViewModel.ReactionDeletedSuccessState -> { is ChatViewModel.ReactionDeletedSuccessState -> {
@ -2757,14 +2776,10 @@ class ChatActivity :
message1.timestamp message1.timestamp
) )
val isLessThan5Min = timeDifference > FIVE_MINUTES_IN_SECONDS val isLessThan5Min = timeDifference > FIVE_MINUTES_IN_SECONDS
if (isSameDayMessages(message2, message1) && return isSameDayMessages(message2, message1) &&
(message2.actorId == message1.actorId) && (message2.actorId == message1.actorId) &&
(!isLessThan5Min) && (!isLessThan5Min) &&
(message2.lastEditTimestamp == 0L || message1.lastEditTimestamp == 0L) (message2.lastEditTimestamp == 0L || message1.lastEditTimestamp == 0L)
) {
return true
}
return false
} }
private fun determinePreviousMessageIds(chatMessageList: List<ChatMessage>) { private fun determinePreviousMessageIds(chatMessageList: List<ChatMessage>) {
@ -3795,5 +3810,6 @@ class ChatActivity :
private const val DELAY_TO_SHOW_PROGRESS_BAR = 1000L private const val DELAY_TO_SHOW_PROGRESS_BAR = 1000L
private const val FIVE_MINUTES_IN_SECONDS: Long = 300 private const val FIVE_MINUTES_IN_SECONDS: Long = 300
const val CONVERSATION_INTERNAL_ID = "CONVERSATION_INTERNAL_ID" const val CONVERSATION_INTERNAL_ID = "CONVERSATION_INTERNAL_ID"
const val NO_OFFLINE_MESSAGES_FOUND = "NO_OFFLINE_MESSAGES_FOUND"
} }
} }

View file

@ -35,6 +35,12 @@ interface ChatMessageRepository : LifecycleAwareManager {
val lastReadMessageFlow: Flow<Int> val lastReadMessageFlow: Flow<Int>
/**
* 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<String>
fun setData(conversationModel: ConversationModel, credentials: String, urlForChatting: String) fun setData(conversationModel: ConversationModel, credentials: String, urlForChatting: String)
fun loadInitialMessages(withNetworkParams: Bundle): Job fun loadInitialMessages(withNetworkParams: Bundle): Job

View file

@ -10,6 +10,7 @@ package com.nextcloud.talk.chat.data.network
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.chat.data.ChatMessageRepository import com.nextcloud.talk.chat.data.ChatMessageRepository
import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.data.database.dao.ChatBlocksDao import com.nextcloud.talk.data.database.dao.ChatBlocksDao
@ -91,6 +92,11 @@ class OfflineFirstChatRepository @Inject constructor(
private val _lastReadMessageFlow: private val _lastReadMessageFlow:
MutableSharedFlow<Int> = MutableSharedFlow() MutableSharedFlow<Int> = MutableSharedFlow()
override val generalUIFlow: Flow<String>
get() = _generalUIFlow
private val _generalUIFlow: MutableSharedFlow<String> = MutableSharedFlow()
private var newXChatLastCommonRead: Int? = null private var newXChatLastCommonRead: Int? = null
private var itIsPaused = false private var itIsPaused = false
private val scope = CoroutineScope(Dispatchers.IO) private val scope = CoroutineScope(Dispatchers.IO)
@ -133,6 +139,7 @@ class OfflineFirstChatRepository @Inject constructor(
} else { } else {
if (!weAlreadyHaveSomeOfflineMessages) { if (!weAlreadyHaveSomeOfflineMessages) {
Log.d(TAG, "An online request for newest 100 messages is made because offline chat is empty") 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 { } else {
Log.d( Log.d(
TAG, TAG,

View file

@ -131,6 +131,8 @@ class ChatViewModel @Inject constructor(
_getRoomViewState.value = GetRoomErrorState _getRoomViewState.value = GetRoomErrorState
} }
val getGeneralUIFlow = chatRepository.generalUIFlow
sealed interface ViewState sealed interface ViewState
object GetReminderStartState : ViewState object GetReminderStartState : ViewState

View file

@ -98,6 +98,12 @@
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1"> android:layout_weight="1">
<include
android:id="@+id/offline"
layout="@layout/no_saved_messages_view"
android:visibility="gone"
tools:visibility="visible" />
<include <include
android:id="@+id/lobby" android:id="@+id/lobby"
layout="@layout/lobby_view" layout="@layout/lobby_view"

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Nextcloud Talk - Android Client
~
~ SPDX-FileCopyrightText: 2024 Julius Linus <juliuslinus1@gmail.com>
~ SPDX-License-Identifier: GPL-3.0-or-later
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/lobby_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/lobby_image_view"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_above="@id/lobby_text_view"
android:layout_centerHorizontal="true"
android:layout_margin="@dimen/margin_between_elements"
android:contentDescription="@string/nc_lobby"
android:src="@drawable/ic_signal_wifi_off_white_24dp"
app:tint="@color/grey_600" />
<TextView
android:id="@+id/lobby_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="@dimen/standard_margin"
android:text="@string/no_offline_messages_saved"
android:textAlignment="center"
android:textColor="@color/grey_600"
android:textSize="16sp"
android:autoLink="web" />
</RelativeLayout>

View file

@ -825,4 +825,5 @@ How to translate with transifex:
<string name="archived">Archived</string> <string name="archived">Archived</string>
<string name="archive_hint">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.</string> <string name="archive_hint">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.</string>
<string name="unarchive_hint">Once a conversation is unarchived, it will be shown by default again.</string> <string name="unarchive_hint">Once a conversation is unarchived, it will be shown by default again.</string>
<string name="no_offline_messages_saved">No offline messages saved</string>
</resources> </resources>