mirror of
https://github.com/nextcloud/talk-android
synced 2025-08-05 02:55:28 +01:00
Merge pull request #5188 from nextcloud/feature/3074/answerWithFile
answer with files
This commit is contained in:
commit
1a4c4bed75
@ -182,7 +182,7 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) :
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -232,7 +232,15 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) :
|
||||
binding.messageQuote.quoteColoredView
|
||||
)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ class IncomingLinkPreviewMessageViewHolder(incomingView: View, payload: Any) :
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -207,7 +207,15 @@ class IncomingLinkPreviewMessageViewHolder(incomingView: View, payload: Any) :
|
||||
binding.messageQuote.quoteColoredView
|
||||
)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) :
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -192,7 +192,15 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) :
|
||||
binding.messageQuote.quoteColoredView
|
||||
)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) :
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -213,7 +213,15 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) :
|
||||
message,
|
||||
binding.messageQuote.quoteColoredView
|
||||
)
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -355,6 +355,16 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) :
|
||||
)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ class OutcomingDeckCardViewHolder(outcomingView: View) :
|
||||
commonMessageInterface.onClickReaction(chatMessage, emoji)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -220,7 +220,15 @@ class OutcomingDeckCardViewHolder(outcomingView: View) :
|
||||
binding.messageQuote.quoteColoredView
|
||||
)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ class OutcomingLinkPreviewMessageViewHolder(outcomingView: View, payload: Any) :
|
||||
commonMessageInterface.onClickReaction(chatMessage, emoji)
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -190,7 +190,15 @@ class OutcomingLinkPreviewMessageViewHolder(outcomingView: View, payload: Any) :
|
||||
viewThemeUtils.talk.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ class OutcomingLocationMessageViewHolder(incomingView: View) :
|
||||
})
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -240,7 +240,15 @@ class OutcomingLocationMessageViewHolder(incomingView: View) :
|
||||
viewThemeUtils.talk.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) :
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -202,7 +202,15 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) :
|
||||
viewThemeUtils.talk.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) :
|
||||
binding.progressBar.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.LongMethod")
|
||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||
if (message.parentMessageId != null && !message.isDeleted) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
@ -351,7 +351,15 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) :
|
||||
viewThemeUtils.talk.colorOutgoingQuoteAuthorText(binding.messageQuote.quotedMessageAuthor)
|
||||
viewThemeUtils.talk.colorOutgoingQuoteBackground(binding.messageQuote.quoteColoredView)
|
||||
|
||||
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
||||
binding.messageQuote.quotedChatMessageView.visibility =
|
||||
if (!message.isDeleted &&
|
||||
message.parentMessageId != null &&
|
||||
message.parentMessageId != chatActivity.conversationThreadId
|
||||
) {
|
||||
View.VISIBLE
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Error when processing parent message in view holder", e)
|
||||
}
|
||||
|
@ -227,6 +227,7 @@ import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.lang.Exception
|
||||
import java.net.HttpURLConnection
|
||||
import java.text.SimpleDateFormat
|
||||
import java.time.Instant
|
||||
@ -2339,11 +2340,26 @@ class ChatActivity :
|
||||
BuildConfig.APPLICATION_ID,
|
||||
File(file.absolutePath)
|
||||
)
|
||||
uploadFile(shareUri.toString(), false)
|
||||
uploadFile(
|
||||
fileUri = shareUri.toString(),
|
||||
isVoiceMessage = false,
|
||||
caption = "",
|
||||
roomToken = roomToken,
|
||||
replyToMessageId = getReplyToMessageId(),
|
||||
displayName = currentConversation?.displayName ?: ""
|
||||
)
|
||||
}
|
||||
cursor?.close()
|
||||
}
|
||||
|
||||
fun getReplyToMessageId(): Int {
|
||||
var replyMessageId = messageInputViewModel.getReplyChatMessage.value?.id?.toInt()
|
||||
if (replyMessageId == null || replyMessageId == 0) {
|
||||
replyMessageId = conversationThreadInfo?.thread?.id ?: 0
|
||||
}
|
||||
return replyMessageId
|
||||
}
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
private fun onPickCameraResult(intent: Intent?) {
|
||||
try {
|
||||
@ -2515,35 +2531,27 @@ class ChatActivity :
|
||||
private fun uploadFiles(files: MutableList<String>, caption: String = "") {
|
||||
for (i in 0 until files.size) {
|
||||
if (i == files.size - 1) {
|
||||
uploadFile(files[i], false, caption)
|
||||
uploadFile(
|
||||
fileUri = files[i],
|
||||
isVoiceMessage = false,
|
||||
caption = caption,
|
||||
roomToken = roomToken,
|
||||
replyToMessageId = getReplyToMessageId(),
|
||||
displayName = currentConversation?.displayName!!
|
||||
)
|
||||
} else {
|
||||
uploadFile(files[i], false)
|
||||
uploadFile(
|
||||
fileUri = files[i],
|
||||
isVoiceMessage = false,
|
||||
caption = "",
|
||||
roomToken = roomToken,
|
||||
replyToMessageId = getReplyToMessageId(),
|
||||
displayName = currentConversation?.displayName!!
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uploadFile(fileUri: String, isVoiceMessage: Boolean, caption: String = "", token: String = "") {
|
||||
var metaData = ""
|
||||
var room = ""
|
||||
|
||||
if (!participantPermissions.hasChatPermission()) {
|
||||
Log.w(TAG, "uploading file(s) is forbidden because of missing attendee permissions")
|
||||
return
|
||||
}
|
||||
|
||||
if (isVoiceMessage) {
|
||||
metaData = VOICE_MESSAGE_META_DATA
|
||||
}
|
||||
|
||||
if (caption != "") {
|
||||
metaData = "{\"caption\":\"$caption\"}"
|
||||
}
|
||||
|
||||
if (token == "") room = roomToken else room = token
|
||||
|
||||
chatViewModel.uploadFile(fileUri, room, currentConversation?.displayName!!, metaData)
|
||||
}
|
||||
|
||||
fun showGalleryPicker() {
|
||||
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))
|
||||
}
|
||||
@ -3872,7 +3880,14 @@ class ChatActivity :
|
||||
val type = message.getCalculateMessageType()
|
||||
when (type) {
|
||||
ChatMessage.MessageType.VOICE_MESSAGE -> {
|
||||
uploadFile(shareUri.toString(), true, token = roomToken)
|
||||
uploadFile(
|
||||
shareUri.toString(),
|
||||
true,
|
||||
roomToken = roomToken,
|
||||
caption = "",
|
||||
replyToMessageId = getReplyToMessageId(),
|
||||
displayName = currentConversation?.displayName ?: ""
|
||||
)
|
||||
showSnackBar(roomToken)
|
||||
}
|
||||
|
||||
@ -3881,12 +3896,26 @@ class ChatActivity :
|
||||
if (null != shareUri) {
|
||||
try {
|
||||
context.contentResolver.openInputStream(shareUri)?.close()
|
||||
uploadFile(shareUri.toString(), false, caption!!, roomToken)
|
||||
uploadFile(
|
||||
fileUri = shareUri.toString(),
|
||||
isVoiceMessage = false,
|
||||
caption = caption!!,
|
||||
roomToken = roomToken,
|
||||
replyToMessageId = getReplyToMessageId(),
|
||||
displayName = currentConversation?.displayName ?: ""
|
||||
)
|
||||
showSnackBar(roomToken)
|
||||
} catch (e: java.lang.Exception) {
|
||||
Log.w(TAG, "File corresponding to the uri does not exist $shareUri")
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "File corresponding to the uri does not exist $shareUri", e)
|
||||
downloadFileToCache(message, false) {
|
||||
uploadFile(shareUri.toString(), false, caption!!, roomToken)
|
||||
uploadFile(
|
||||
fileUri = shareUri.toString(),
|
||||
isVoiceMessage = false,
|
||||
caption = caption!!,
|
||||
roomToken = roomToken,
|
||||
replyToMessageId = getReplyToMessageId(),
|
||||
displayName = currentConversation?.displayName ?: ""
|
||||
)
|
||||
showSnackBar(roomToken)
|
||||
}
|
||||
}
|
||||
@ -4300,6 +4329,33 @@ class ChatActivity :
|
||||
)
|
||||
}
|
||||
|
||||
fun uploadFile(
|
||||
fileUri: String,
|
||||
isVoiceMessage: Boolean,
|
||||
caption: String = "",
|
||||
roomToken: String = "",
|
||||
replyToMessageId: Int? = null,
|
||||
displayName: String
|
||||
) {
|
||||
chatViewModel.uploadFile(
|
||||
fileUri,
|
||||
isVoiceMessage,
|
||||
caption,
|
||||
roomToken,
|
||||
replyToMessageId,
|
||||
displayName
|
||||
)
|
||||
cancelReply()
|
||||
}
|
||||
|
||||
fun cancelReply() {
|
||||
messageInputViewModel.reply(null)
|
||||
chatViewModel.messageDraft.quotedMessageText = null
|
||||
chatViewModel.messageDraft.quotedDisplayName = null
|
||||
chatViewModel.messageDraft.quotedImageUrl = null
|
||||
chatViewModel.messageDraft.quotedJsonId = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG = ChatActivity::class.simpleName
|
||||
private const val CONTENT_TYPE_CALL_STARTED: Byte = 1
|
||||
@ -4319,7 +4375,6 @@ class ChatActivity :
|
||||
private const val REQUEST_RECORD_AUDIO_PERMISSION = 222
|
||||
private const val REQUEST_READ_CONTACT_PERMISSION = 234
|
||||
private const val REQUEST_CAMERA_PERMISSION = 223
|
||||
private const val VOICE_MESSAGE_META_DATA = "{\"messageType\":\"voice-message\"}"
|
||||
private const val FILE_DATE_PATTERN = "yyyy-MM-dd HH-mm-ss"
|
||||
private const val VIDEO_SUFFIX = ".mp4"
|
||||
private const val FULLY_OPAQUE_INT: Int = 255
|
||||
|
@ -101,7 +101,6 @@ class MessageInputFragment : Fragment() {
|
||||
private const val TYPING_INTERVAL_TO_SEND_NEXT_TYPING_MESSAGE = 1000L
|
||||
private const val TYPING_STARTED_SIGNALING_MESSAGE_TYPE = "startedTyping"
|
||||
private const val TYPING_STOPPED_SIGNALING_MESSAGE_TYPE = "stoppedTyping"
|
||||
const val VOICE_MESSAGE_META_DATA = "{\"messageType\":\"voice-message\"}"
|
||||
private const val QUOTED_MESSAGE_IMAGE_MAX_HEIGHT = 96f
|
||||
private const val MENTION_AUTO_COMPLETE_ELEVATION = 6f
|
||||
private const val MINIMUM_VOICE_RECORD_DURATION: Int = 1000
|
||||
@ -178,13 +177,17 @@ class MessageInputFragment : Fragment() {
|
||||
private fun initObservers() {
|
||||
Log.d(TAG, "LifeCyclerOwner is: ${viewLifecycleOwner.lifecycle}")
|
||||
chatActivity.messageInputViewModel.getReplyChatMessage.observe(viewLifecycleOwner) { message ->
|
||||
(message as ChatMessage?)?.let {
|
||||
message?.let {
|
||||
chatActivity.chatViewModel.messageDraft.quotedMessageText = message.text
|
||||
chatActivity.chatViewModel.messageDraft.quotedDisplayName = message.actorDisplayName
|
||||
chatActivity.chatViewModel.messageDraft.quotedImageUrl = message.imageUrl
|
||||
chatActivity.chatViewModel.messageDraft.quotedJsonId = message.jsonMessageId
|
||||
replyToMessage(message.text, message.actorDisplayName, message.imageUrl, message.jsonMessageId)
|
||||
}
|
||||
replyToMessage(
|
||||
message.text,
|
||||
message.actorDisplayName,
|
||||
message.imageUrl
|
||||
)
|
||||
} ?: clearReplyUi()
|
||||
}
|
||||
|
||||
chatActivity.messageInputViewModel.getEditChatMessage.observe(viewLifecycleOwner) { message ->
|
||||
@ -315,8 +318,7 @@ class MessageInputFragment : Fragment() {
|
||||
replyToMessage(
|
||||
chatActivity.chatViewModel.messageDraft.quotedMessageText,
|
||||
chatActivity.chatViewModel.messageDraft.quotedDisplayName,
|
||||
chatActivity.chatViewModel.messageDraft.quotedImageUrl,
|
||||
chatActivity.chatViewModel.messageDraft.quotedJsonId ?: 0
|
||||
chatActivity.chatViewModel.messageDraft.quotedImageUrl
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -392,7 +394,14 @@ class MessageInputFragment : Fragment() {
|
||||
// See: https://developer.android.com/guide/topics/text/image-keyboard
|
||||
|
||||
(binding.fragmentMessageInputView.inputEditText as ImageEmojiEditText).onCommitContentListener = {
|
||||
uploadFile(it.toString(), false)
|
||||
chatActivity.chatViewModel.uploadFile(
|
||||
fileUri = it.toString(),
|
||||
isVoiceMessage = false,
|
||||
caption = "",
|
||||
roomToken = chatActivity.roomToken,
|
||||
replyToMessageId = chatActivity.getReplyToMessageId(),
|
||||
displayName = chatActivity.currentConversation?.displayName!!
|
||||
)
|
||||
}
|
||||
|
||||
if (chatActivity.sharedText.isNotEmpty()) {
|
||||
@ -462,6 +471,10 @@ class MessageInputFragment : Fragment() {
|
||||
binding.fragmentCallStarted.callStartedSecondaryText.visibility = if (collapsed) View.VISIBLE else View.GONE
|
||||
setDropDown(collapsed)
|
||||
}
|
||||
|
||||
binding.fragmentMessageInputView.findViewById<ImageButton>(R.id.cancelReplyButton)?.setOnClickListener {
|
||||
cancelReply()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setDropDown(collapsed: Boolean) {
|
||||
@ -564,9 +577,9 @@ class MessageInputFragment : Fragment() {
|
||||
return@setOnTouchListener false
|
||||
} else {
|
||||
chatActivity.chatViewModel.stopAndSendAudioRecording(
|
||||
chatActivity.roomToken,
|
||||
chatActivity.currentConversation!!.displayName,
|
||||
VOICE_MESSAGE_META_DATA
|
||||
roomToken = chatActivity.roomToken,
|
||||
replyToMessageId = chatActivity.getReplyToMessageId(),
|
||||
displayName = chatActivity.currentConversation!!.displayName
|
||||
)
|
||||
}
|
||||
resetSlider()
|
||||
@ -713,16 +726,9 @@ class MessageInputFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun replyToMessage(
|
||||
quotedMessageText: String?,
|
||||
quotedActorDisplayName: String?,
|
||||
quotedImageUrl: String?,
|
||||
quotedJsonId: Int
|
||||
) {
|
||||
private fun replyToMessage(quotedMessageText: String?, quotedActorDisplayName: String?, quotedImageUrl: String?) {
|
||||
Log.d(TAG, "Reply")
|
||||
val view = binding.fragmentMessageInputView
|
||||
view.findViewById<ImageButton>(R.id.attachmentButton)?.visibility =
|
||||
View.GONE
|
||||
view.findViewById<ImageButton>(R.id.cancelReplyButton)?.visibility =
|
||||
View.VISIBLE
|
||||
|
||||
@ -757,9 +763,7 @@ class MessageInputFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
val quotedChatMessageView =
|
||||
view.findViewById<RelativeLayout>(R.id.quotedChatMessageView)
|
||||
quotedChatMessageView?.tag = quotedJsonId
|
||||
val quotedChatMessageView = view.findViewById<RelativeLayout>(R.id.quotedChatMessageView)
|
||||
quotedChatMessageView?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
@ -827,28 +831,6 @@ class MessageInputFragment : Fragment() {
|
||||
private fun isTypingStatusEnabled(): Boolean =
|
||||
!CapabilitiesUtil.isTypingStatusPrivate(chatActivity.conversationUser!!)
|
||||
|
||||
private fun uploadFile(fileUri: String, isVoiceMessage: Boolean, caption: String = "", token: String = "") {
|
||||
var metaData = ""
|
||||
val room: String
|
||||
|
||||
if (!chatActivity.participantPermissions.hasChatPermission()) {
|
||||
Log.w(ChatActivity.TAG, "uploading file(s) is forbidden because of missing attendee permissions")
|
||||
return
|
||||
}
|
||||
|
||||
if (isVoiceMessage) {
|
||||
metaData = VOICE_MESSAGE_META_DATA
|
||||
}
|
||||
|
||||
if (caption != "") {
|
||||
metaData = "{\"caption\":\"$caption\"}"
|
||||
}
|
||||
|
||||
if (token == "") room = chatActivity.roomToken else room = token
|
||||
|
||||
chatActivity.chatViewModel.uploadFile(fileUri, room, chatActivity.currentConversation!!.displayName, metaData)
|
||||
}
|
||||
|
||||
private fun submitMessage(sendWithoutNotification: Boolean) {
|
||||
if (binding.fragmentMessageInputView.inputEditText != null) {
|
||||
val editable = binding.fragmentMessageInputView.inputEditText!!.editableText
|
||||
@ -856,23 +838,15 @@ class MessageInputFragment : Fragment() {
|
||||
binding.fragmentMessageInputView.inputEditText?.setText("")
|
||||
sendStopTypingMessage()
|
||||
|
||||
var replyMessageId = binding.fragmentMessageInputView
|
||||
.findViewById<RelativeLayout>(R.id.quotedChatMessageView)?.tag as Int? ?: 0
|
||||
|
||||
if (replyMessageId == 0) {
|
||||
replyMessageId = chatActivity.conversationThreadInfo?.thread?.id ?: 0
|
||||
}
|
||||
|
||||
sendMessage(
|
||||
editable.toString(),
|
||||
replyMessageId,
|
||||
sendWithoutNotification
|
||||
)
|
||||
cancelReply()
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendMessage(message: String, replyTo: Int?, sendWithoutNotification: Boolean) {
|
||||
private fun sendMessage(message: String, sendWithoutNotification: Boolean) {
|
||||
chatActivity.messageInputViewModel.sendChatMessage(
|
||||
chatActivity.conversationUser!!.getCredentials(),
|
||||
ApiUtils.getUrlForChat(
|
||||
@ -882,7 +856,7 @@ class MessageInputFragment : Fragment() {
|
||||
),
|
||||
message,
|
||||
chatActivity.conversationUser!!.displayName ?: "",
|
||||
replyTo ?: 0,
|
||||
chatActivity.getReplyToMessageId(),
|
||||
sendWithoutNotification
|
||||
)
|
||||
}
|
||||
@ -983,10 +957,6 @@ class MessageInputFragment : Fragment() {
|
||||
private fun themeMessageInputView() {
|
||||
binding.fragmentMessageInputView.button?.let { viewThemeUtils.platform.colorImageView(it, ColorRole.PRIMARY) }
|
||||
|
||||
binding.fragmentMessageInputView.findViewById<ImageButton>(R.id.cancelReplyButton)?.setOnClickListener {
|
||||
cancelReply()
|
||||
}
|
||||
|
||||
binding.fragmentMessageInputView.findViewById<ImageButton>(R.id.cancelReplyButton)?.let {
|
||||
viewThemeUtils.platform
|
||||
.themeImageButton(it)
|
||||
@ -1043,17 +1013,14 @@ class MessageInputFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun cancelReply() {
|
||||
val quote = binding.fragmentMessageInputView
|
||||
.findViewById<RelativeLayout>(R.id.quotedChatMessageView)
|
||||
quote.visibility = View.GONE
|
||||
quote.tag = null
|
||||
binding.fragmentMessageInputView.findViewById<ImageButton>(R.id.attachmentButton)?.visibility = View.VISIBLE
|
||||
chatActivity.messageInputViewModel.reply(null)
|
||||
chatActivity.cancelReply()
|
||||
clearReplyUi()
|
||||
}
|
||||
|
||||
chatActivity.chatViewModel.messageDraft.quotedMessageText = null
|
||||
chatActivity.chatViewModel.messageDraft.quotedDisplayName = null
|
||||
chatActivity.chatViewModel.messageDraft.quotedImageUrl = null
|
||||
chatActivity.chatViewModel.messageDraft.quotedJsonId = null
|
||||
private fun clearReplyUi() {
|
||||
val quote = binding.fragmentMessageInputView.findViewById<RelativeLayout>(R.id.quotedChatMessageView)
|
||||
quote.visibility = View.GONE
|
||||
binding.fragmentMessageInputView.findViewById<ImageButton>(R.id.attachmentButton)?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun isInReplyState(): Boolean {
|
||||
|
@ -114,9 +114,9 @@ class MessageInputVoiceRecordingFragment : Fragment() {
|
||||
|
||||
binding.sendVoiceRecording.setOnClickListener {
|
||||
chatActivity.chatViewModel.stopAndSendAudioRecording(
|
||||
chatActivity.roomToken,
|
||||
chatActivity.currentConversation!!.displayName,
|
||||
MessageInputFragment.VOICE_MESSAGE_META_DATA
|
||||
roomToken = chatActivity.roomToken,
|
||||
replyToMessageId = chatActivity.getReplyToMessageId(),
|
||||
displayName = chatActivity.currentConversation!!.displayName
|
||||
)
|
||||
clear()
|
||||
}
|
||||
|
@ -445,6 +445,7 @@ class OfflineFirstChatRepository @Inject constructor(
|
||||
return loadFromServer
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
private fun getFieldMap(
|
||||
lookIntoFuture: Boolean,
|
||||
timeout: Int,
|
||||
|
@ -17,6 +17,7 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.google.gson.Gson
|
||||
import com.nextcloud.talk.chat.data.ChatMessageRepository
|
||||
import com.nextcloud.talk.chat.data.io.AudioFocusRequestManager
|
||||
import com.nextcloud.talk.chat.data.io.MediaPlayerManager
|
||||
@ -43,6 +44,7 @@ import com.nextcloud.talk.models.json.userAbsence.UserAbsenceData
|
||||
import com.nextcloud.talk.repositories.reactions.ReactionsRepository
|
||||
import com.nextcloud.talk.threadsoverview.data.ThreadsRepository
|
||||
import com.nextcloud.talk.ui.PlaybackSpeed
|
||||
import com.nextcloud.talk.utils.ParticipantPermissions
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
|
||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||
@ -92,6 +94,7 @@ class ChatViewModel @Inject constructor(
|
||||
val mediaPlayerPosition = mediaPlayerManager.mediaPlayerPosition
|
||||
var chatRoomToken: String = ""
|
||||
var messageDraft: MessageDraft = MessageDraft()
|
||||
lateinit var participantPermissions: ParticipantPermissions
|
||||
|
||||
fun getChatRepository(): ChatMessageRepository = chatRepository
|
||||
|
||||
@ -316,6 +319,10 @@ class ChatViewModel @Inject constructor(
|
||||
} else {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesUpdateState(user.capabilities!!.spreedCapability!!)
|
||||
}
|
||||
participantPermissions = ParticipantPermissions(
|
||||
user.capabilities!!.spreedCapability!!,
|
||||
conversationModel
|
||||
)
|
||||
} else {
|
||||
chatNetworkDataSource.getCapabilities(user, token)
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -331,6 +338,10 @@ class ChatViewModel @Inject constructor(
|
||||
} else {
|
||||
_getCapabilitiesViewState.value = GetCapabilitiesUpdateState(spreedCapabilities)
|
||||
}
|
||||
participantPermissions = ParticipantPermissions(
|
||||
spreedCapabilities,
|
||||
conversationModel
|
||||
)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
@ -680,13 +691,20 @@ class ChatViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun stopAndSendAudioRecording(room: String, displayName: String, metaData: String) {
|
||||
fun stopAndSendAudioRecording(roomToken: String = "", replyToMessageId: Int? = null, displayName: String) {
|
||||
stopAudioRecording()
|
||||
|
||||
if (mediaRecorderManager.mediaRecorderState != MediaRecorderManager.MediaRecorderState.ERROR) {
|
||||
val uri = Uri.fromFile(File(mediaRecorderManager.currentVoiceRecordFile))
|
||||
Log.d(TAG, "File uploaded")
|
||||
uploadFile(uri.toString(), room, displayName, metaData)
|
||||
uploadFile(
|
||||
fileUri = uri.toString(),
|
||||
isVoiceMessage = true,
|
||||
caption = "",
|
||||
roomToken = roomToken,
|
||||
replyToMessageId = replyToMessageId,
|
||||
displayName = displayName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -699,7 +717,38 @@ class ChatViewModel @Inject constructor(
|
||||
|
||||
fun getCurrentVoiceRecordFile(): String = mediaRecorderManager.currentVoiceRecordFile
|
||||
|
||||
fun uploadFile(fileUri: String, room: String, displayName: String, metaData: String) {
|
||||
fun uploadFile(
|
||||
fileUri: String,
|
||||
isVoiceMessage: Boolean,
|
||||
caption: String = "",
|
||||
roomToken: String = "",
|
||||
replyToMessageId: Int? = null,
|
||||
displayName: String
|
||||
) {
|
||||
val metaDataMap = mutableMapOf<String, Any>()
|
||||
var room = ""
|
||||
|
||||
if (!participantPermissions.hasChatPermission()) {
|
||||
Log.w(TAG, "uploading file(s) is forbidden because of missing attendee permissions")
|
||||
return
|
||||
}
|
||||
|
||||
if (replyToMessageId != 0) {
|
||||
metaDataMap["replyTo"] = replyToMessageId.toString()
|
||||
}
|
||||
|
||||
if (isVoiceMessage) {
|
||||
metaDataMap["messageType"] = "voice-message"
|
||||
}
|
||||
|
||||
if (caption != "") {
|
||||
metaDataMap["caption"] = caption
|
||||
}
|
||||
|
||||
val metaData = Gson().toJson(metaDataMap)
|
||||
|
||||
room = if (roomToken == "") chatRoomToken else roomToken
|
||||
|
||||
try {
|
||||
require(fileUri.isNotEmpty())
|
||||
UploadAndShareFilesWorker.upload(
|
||||
|
@ -90,8 +90,8 @@ class MessageInputViewModel @Inject constructor(
|
||||
val getEditChatMessage: LiveData<IMessage?>
|
||||
get() = _getEditChatMessage
|
||||
|
||||
private val _getReplyChatMessage: MutableLiveData<IMessage?> = MutableLiveData()
|
||||
val getReplyChatMessage: LiveData<IMessage?>
|
||||
private val _getReplyChatMessage: MutableLiveData<ChatMessage?> = MutableLiveData()
|
||||
val getReplyChatMessage: LiveData<ChatMessage?>
|
||||
get() = _getReplyChatMessage
|
||||
|
||||
sealed interface ViewState
|
||||
@ -203,7 +203,7 @@ class MessageInputViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun reply(message: IMessage?) {
|
||||
fun reply(message: ChatMessage?) {
|
||||
_getReplyChatMessage.postValue(message)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user