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 36345d5b97..7f22a80a63 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 @@ -90,6 +90,16 @@ interface ChatMessageRepository : LifecycleAwareManager { referenceId: String ): Flow> + suspend fun resendChatMessage( + credentials: String, + url: String, + message: String, + displayName: String, + replyTo: Int, + sendWithoutNotification: Boolean, + referenceId: String + ): Flow> + suspend fun addTemporaryMessage( message: CharSequence, displayName: String, 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 48fb5bae46..7d3ec20cd4 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 @@ -124,8 +124,6 @@ class OfflineFirstChatRepository @Inject constructor( override fun loadInitialMessages(withNetworkParams: Bundle): Job = scope.launch { - sendTempChatMessages(credentials, urlForChatting) - Log.d(TAG, "---- loadInitialMessages ------------") newXChatLastCommonRead = conversationModel.lastCommonReadMessage @@ -197,6 +195,8 @@ class OfflineFirstChatRepository @Inject constructor( ) } + sendTempChatMessages(credentials, urlForChatting) + // delay is a dirty workaround to make sure messages are added to adapter on initial load before dealing // with them (otherwise there is a race condition). delay(DELAY_TO_ENSURE_MESSAGES_ARE_ADDED) @@ -843,6 +843,37 @@ class OfflineFirstChatRepository @Inject constructor( emit(Result.failure(e)) } + override suspend fun resendChatMessage( + credentials: String, + url: String, + message: String, + displayName: String, + replyTo: Int, + sendWithoutNotification: Boolean, + referenceId: String + ): Flow> { + val messageToResend = chatDao.getTempMessageForConversation(internalConversationId, referenceId).first() + messageToResend.sendingFailed = false + chatDao.updateChatMessage(messageToResend) + + val messageToResendModel = messageToResend.asModel() + _removeMessageFlow.emit(messageToResendModel) + + val tripleChatMessages = Triple(true, false, listOf(messageToResendModel)) + _messageFlow.emit(tripleChatMessages) + + return sendChatMessage( + credentials, + url, + message, + displayName, + replyTo, + sendWithoutNotification, + referenceId + ) + } + + override suspend fun editChatMessage( credentials: String, url: String, 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 098dec9740..e2ce780ad2 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 @@ -24,6 +24,7 @@ import com.nextcloud.talk.chat.data.model.ChatMessage import com.nextcloud.talk.chat.data.network.ChatNetworkDataSource import com.nextcloud.talk.conversationlist.data.OfflineConversationsRepository import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.extensions.toIntOrZero import com.nextcloud.talk.jobs.UploadAndShareFilesWorker import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.models.domain.ReactionAddedModel @@ -794,6 +795,29 @@ class ChatViewModel @Inject constructor( } } + fun resendMessage( + credentials: String, + urlForChat: String, + message: ChatMessage) { + viewModelScope.launch { + chatRepository.resendChatMessage( + credentials, + urlForChat, + message.message.orEmpty(), + message.actorDisplayName.orEmpty(), + message.parentMessageId?.toIntOrZero() ?: 0, + false, + message.referenceId.orEmpty() + ).collect { result -> + if (result.isSuccess) { + Log.d(TAG, "resend successful") + } else { + Log.e(TAG, "resend failed") + } + } + } + } + companion object { private val TAG = ChatViewModel::class.simpleName const val JOIN_ROOM_RETRY_COUNT: Long = 3 diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/TempMessageActionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/TempMessageActionsDialog.kt index 9085762d2a..cdebbfdf48 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/TempMessageActionsDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/TempMessageActionsDialog.kt @@ -68,6 +68,7 @@ class TempMessageActionsDialog( private fun initMenuItems() { this.lifecycleScope.launch { + initResendMessage(true) initMenuEditMessage(true) initMenuDeleteMessage(true) } @@ -80,6 +81,27 @@ class TempMessageActionsDialog( behavior.state = BottomSheetBehavior.STATE_COLLAPSED } + private fun initResendMessage(visible: Boolean) { + if (visible) { + binding.menuResendMessage.setOnClickListener { + + + chatActivity.chatViewModel.resendMessage( + chatActivity.conversationUser!!.getCredentials(), + ApiUtils.getUrlForChat( + chatActivity.chatApiVersion, + chatActivity.conversationUser!!.baseUrl!!, + chatActivity.roomToken + ), + message + ) + + dismiss() + } + } + binding.menuResendMessage.visibility = getVisibility(visible) + } + private fun initMenuDeleteMessage(visible: Boolean) { if (visible) { binding.menuDeleteMessage.setOnClickListener { diff --git a/app/src/main/res/layout/dialog_temp_message_actions.xml b/app/src/main/res/layout/dialog_temp_message_actions.xml index c377fafc86..98d51ba810 100644 --- a/app/src/main/res/layout/dialog_temp_message_actions.xml +++ b/app/src/main/res/layout/dialog_temp_message_actions.xml @@ -27,6 +27,39 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + + + + + + %1$s is out of office and might not respond %1$s is out of office today Replacement: + Resend