mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-13 03:01:05 +00:00
Implement queued messages for offline support
Signed-off-by: rapterjet2004 <juliuslinus1@gmail.com>
This commit is contained in:
parent
3d2df9bb94
commit
569be55395
@ -73,6 +73,7 @@ import com.nextcloud.talk.utils.text.Spans
|
||||
import com.otaliastudios.autocomplete.Autocomplete
|
||||
import com.stfalcon.chatkit.commons.models.IMessage
|
||||
import com.vanniktech.emoji.EmojiPopup
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
@ -141,6 +142,11 @@ class MessageInputFragment : Fragment() {
|
||||
saveState()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
chatActivity.messageInputViewModel.restoreMessageQueue(chatActivity.roomToken)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
if (mentionAutocomplete != null && mentionAutocomplete!!.isPopupShowing) {
|
||||
@ -178,12 +184,19 @@ class MessageInputFragment : Fragment() {
|
||||
val connectionGained = (!wasOnline && isOnline)
|
||||
wasOnline = !binding.fragmentMessageInputView.isShown
|
||||
Log.d(TAG, "isOnline: $isOnline\nwasOnline: $wasOnline\nconnectionGained: $connectionGained")
|
||||
|
||||
// FIXME timeout exception - maybe something to do with the room?
|
||||
// handleMessageQueue(isOnline)
|
||||
delay(500)
|
||||
handleMessageQueue(isOnline)
|
||||
handleUI(isOnline, connectionGained)
|
||||
}.collect()
|
||||
}
|
||||
|
||||
chatActivity.messageInputViewModel.messageQueueSizeFlow.observe(viewLifecycleOwner) { size ->
|
||||
if (size > 0) {
|
||||
binding.fragmentConnectionLost.text = getString(R.string.connection_lost_queued, size)
|
||||
} else {
|
||||
binding.fragmentConnectionLost.text = getString(R.string.connection_lost_sent_messages_are_queued)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleUI(isOnline: Boolean, connectionGained: Boolean) {
|
||||
@ -220,12 +233,9 @@ class MessageInputFragment : Fragment() {
|
||||
binding.fragmentConnectionLost.clearAnimation()
|
||||
binding.fragmentConnectionLost.visibility = View.GONE
|
||||
binding.fragmentConnectionLost.setBackgroundColor(resources.getColor(R.color.hwSecurityRed))
|
||||
binding.fragmentConnectionLost.text =
|
||||
getString(R.string.connection_lost_sent_messages_are_queued)
|
||||
binding.fragmentConnectionLost.visibility = View.VISIBLE
|
||||
binding.fragmentMessageInputView.attachmentButton.isEnabled = false
|
||||
binding.fragmentMessageInputView.recordAudioButton.isEnabled = false
|
||||
binding.fragmentMessageInputView.messageInput.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import com.nextcloud.talk.chat.data.io.AudioFocusRequestManager
|
||||
import com.nextcloud.talk.chat.data.io.AudioRecorderManager
|
||||
import com.nextcloud.talk.chat.data.io.MediaPlayerManager
|
||||
@ -26,6 +27,8 @@ import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import javax.inject.Inject
|
||||
|
||||
class MessageInputViewModel @Inject constructor(
|
||||
@ -51,7 +54,7 @@ class MessageInputViewModel @Inject constructor(
|
||||
)
|
||||
|
||||
private var isQueueing: Boolean = false
|
||||
private val messageQueue: MutableList<QueuedMessage> = mutableListOf()
|
||||
private var messageQueue: MutableList<QueuedMessage> = mutableListOf()
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
@ -119,6 +122,10 @@ class MessageInputViewModel @Inject constructor(
|
||||
val isVoicePreviewPlaying: LiveData<Boolean>
|
||||
get() = _isVoicePreviewPlaying
|
||||
|
||||
private val _messageQueueSizeFlow = MutableStateFlow(messageQueue.size)
|
||||
val messageQueueSizeFlow: LiveData<Int>
|
||||
get() = _messageQueueSizeFlow.asLiveData()
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
fun sendChatMessage(
|
||||
roomToken: String,
|
||||
@ -132,6 +139,7 @@ class MessageInputViewModel @Inject constructor(
|
||||
if (isQueueing) {
|
||||
messageQueue.add(QueuedMessage(message, displayName, replyTo, sendWithoutNotification))
|
||||
dataStore.saveMessageQueue(roomToken, messageQueue)
|
||||
_messageQueueSizeFlow.update { messageQueue.size }
|
||||
return
|
||||
}
|
||||
|
||||
@ -259,4 +267,9 @@ class MessageInputViewModel @Inject constructor(
|
||||
fun switchToMessageQueue(shouldQueue: Boolean) {
|
||||
isQueueing = shouldQueue
|
||||
}
|
||||
|
||||
fun restoreMessageQueue(roomToken: String) {
|
||||
messageQueue = dataStore.getMessageQueue(roomToken)
|
||||
_messageQueueSizeFlow.tryEmit(messageQueue.size)
|
||||
}
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ class AppPreferencesImpl(val context: Context) : AppPreferences {
|
||||
var queueStr = ""
|
||||
queue?.let {
|
||||
for (msg in queue) {
|
||||
val msgStr = "[${msg.message},${msg.replyTo},${msg.displayName},${msg.sendWithoutNotification}]"
|
||||
val msgStr = "${msg.message},${msg.replyTo},${msg.displayName},${msg.sendWithoutNotification}^"
|
||||
queueStr += msgStr
|
||||
}
|
||||
}
|
||||
@ -500,18 +500,20 @@ class AppPreferencesImpl(val context: Context) : AppPreferences {
|
||||
val queue: MutableList<MessageInputViewModel.QueuedMessage> = mutableListOf()
|
||||
if (queueStr.isEmpty()) return queue
|
||||
|
||||
for (msgStr in queueStr.split("]")) {
|
||||
for (msgStr in queueStr.split("^")) {
|
||||
try {
|
||||
val msgArray = msgStr.replace("[", "").split(",")
|
||||
val message = msgArray[MESSAGE_INDEX]
|
||||
val replyTo = msgArray[REPLY_TO_INDEX].toInt()
|
||||
val displayName = msgArray[DISPLY_NAME_INDEX]
|
||||
val silent = msgArray[SILENT_INDEX].toBoolean()
|
||||
if (msgStr.isNotEmpty()) {
|
||||
val msgArray = msgStr.split(",")
|
||||
val message = msgArray[MESSAGE_INDEX]
|
||||
val replyTo = msgArray[REPLY_TO_INDEX].toInt()
|
||||
val displayName = msgArray[DISPLY_NAME_INDEX]
|
||||
val silent = msgArray[SILENT_INDEX].toBoolean()
|
||||
|
||||
val qMsg = MessageInputViewModel.QueuedMessage(message, displayName, replyTo, silent)
|
||||
queue.add(qMsg)
|
||||
val qMsg = MessageInputViewModel.QueuedMessage(message, displayName, replyTo, silent)
|
||||
queue.add(qMsg)
|
||||
}
|
||||
} catch (e: IndexOutOfBoundsException) {
|
||||
Log.e(TAG, "Message string: $msgStr\n $e")
|
||||
Log.e(TAG, "Message string: $msgStr\n Queue String: $queueStr \n$e")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -802,6 +802,7 @@ How to translate with transifex:
|
||||
<string name="show_banned_participants">Show banned participants</string>
|
||||
<string name="bans_list">Bans list</string>
|
||||
<string name="connection_lost_sent_messages_are_queued">Connection lost - Sent messages are queued</string>
|
||||
<string name="connection_lost_queued">Connection lost - %1$d are queued</string>
|
||||
<string name="connection_established">Connection established</string>
|
||||
<string name="message_deleted_by_you">Message deleted by you</string>
|
||||
<string name="unban">Unban</string>
|
||||
|
Loading…
Reference in New Issue
Block a user