From 683f924556567ffbe3f9cd9c96829d14a87aa35d Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Fri, 9 Feb 2024 10:03:57 +0100 Subject: [PATCH] Add editor name and message timestamp to MessageActionsDialog Signed-off-by: sowjanyakch --- .../messages/IncomingTextMessageViewHolder.kt | 14 +-- .../OutcomingTextMessageViewHolder.kt | 15 ++-- .../com/nextcloud/talk/chat/ChatActivity.kt | 90 ++++++++++++++++++- .../talk/models/json/chat/ChatMessage.kt | 12 +++ .../talk/ui/dialog/MessageActionsDialog.kt | 24 ++++- .../res/layout/dialog_message_actions.xml | 35 ++++++++ app/src/main/res/values/strings.xml | 3 +- 7 files changed, 175 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt index ae9d35fcb..961ddeb88 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt @@ -113,16 +113,14 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) : binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) binding.messageText.text = processedMessageText - if (message.parentMessage?.id != null && message.systemMessageType == ChatMessage.SystemMessageType - .MESSAGE_EDITED - ) { + if (message.lastEditTimestamp != 0L && !message.isDeleted) { binding.messageType.visibility = View.VISIBLE + binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.lastEditTimestamp) } else { binding.messageType.visibility = View.GONE + binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp) } - binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp) - // parent message handling if (!message.isDeleted && message.parentMessage != null) { processParentMessage(message) @@ -244,6 +242,12 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) : } } + fun updateMessage(message: ChatMessage) { + binding.messageText.text = message.message + binding.messageType.visibility = View.VISIBLE + binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.lastEditTimestamp) + } + fun assignCommonMessageInterface(commonMessageInterface: CommonMessageInterface) { this.commonMessageInterface = commonMessageInterface } diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt index 9142ee679..7d8f2947f 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt @@ -100,18 +100,17 @@ class OutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewH setBubbleOnChatMessage(message) binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) - if (message.parentMessage?.id != null && message.systemMessageType == ChatMessage.SystemMessageType - .MESSAGE_EDITED - ) { - binding.messageType.visibility = View.VISIBLE - } else { - binding.messageType.visibility = View.GONE - } binding.messageTime.layoutParams = layoutParams viewThemeUtils.platform.colorTextView(binding.messageText, ColorRole.ON_SURFACE_VARIANT) binding.messageText.text = processedMessageText - binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp) + if (message.lastEditTimestamp != 0L && !message.isDeleted) { + binding.messageType.visibility = View.VISIBLE + binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.lastEditTimestamp) + } else { + binding.messageType.visibility = View.GONE + binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp) + } // parent message handling if (!message.isDeleted && message.parentMessage != null) { 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 aaa3c5c56..499821afa 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -922,6 +922,13 @@ class ChatActivity : message.message = messageEdited.ocs?.data?.parentMessage?.text adapter?.update(message) adapter?.notifyDataSetChanged() + + // val inflater = LayoutInflater.from(context) + // val outgoingTextViewLayout = inflater.inflate(R.layout.item_custom_incoming_text_message, null) + // val messageType = outgoingTextViewLayout.findViewById(R.id.messageType) + // val messageTime = outgoingTextViewLayout.findViewById(R.id.messageTime) + // messageType.visibility = View.VISIBLE + // messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.lastEditTimestamp) clearEditUI() } @@ -2791,8 +2798,9 @@ class ChatActivity : } } - private fun uploadFile(fileUri: String, isVoiceMessage: Boolean, caption: String = "") { + 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") @@ -2807,11 +2815,13 @@ class ChatActivity : metaData = "{\"caption\":\"$caption\"}" } + if (token == "") room = roomToken else room = token + try { require(fileUri.isNotEmpty()) UploadAndShareFilesWorker.upload( fileUri, - roomToken, + room, currentConversation?.displayName!!, metaData ) @@ -4287,6 +4297,82 @@ class ChatActivity : } } + fun shareToNotes(message: ChatMessage, roomToken: String) { + val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1)) + val type = message.getCalculateMessageType() + var shareUri: Uri? = null + var data: HashMap? + var metaData: String = "" + var objectId: String = "" + if (message.hasFileAttachment()) { + val filename = message.selectedIndividualHashMap!!["name"] + path = applicationContext.cacheDir.absolutePath + "/" + filename + shareUri = FileProvider.getUriForFile( + this, + BuildConfig.APPLICATION_ID, + File(path) + ) + + this.grantUriPermission( + applicationContext.packageName, + shareUri, + Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION + ) + } else if (message.hasGeoLocation()) { + data = message.messageParameters?.get("object") + objectId = data?.get("id")!! + val name = data.get("name")!! + val lat = data.get("latitude")!! + val lon = data.get("longitude")!! + metaData = + "{\"type\":\"geo-location\",\"id\":\"geo:$lat,$lon\",\"latitude\":\"$lat\"," + + "\"longitude\":\"$lon\",\"name\":\"$name\"}" + } + + when (type) { + ChatMessage.MessageType.VOICE_MESSAGE -> { + uploadFile(shareUri.toString(), true, token = roomToken) + Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show() + } + ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE -> { + val caption = if (message.message != "{file}") message.message else "" + if (null != shareUri) { + try { + context.contentResolver.openInputStream(shareUri)?.close() + uploadFile(shareUri.toString(), false, caption!!, roomToken) + Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show() + } catch (e: java.lang.Exception) { + Log.w(TAG, "File corresponding to the uri does not exist " + shareUri.toString()) + downloadFileToCache(message, false) { + uploadFile(shareUri.toString(), false, caption!!, roomToken) + Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show() + } + } + } + } + ChatMessage.MessageType.SINGLE_NC_GEOLOCATION_MESSAGE -> { + chatViewModel.shareLocationToNotes( + credentials!!, + ApiUtils.getUrlToSendLocation(apiVersion, conversationUser!!.baseUrl, roomToken), + "geo-location", + objectId, + metaData + ) + Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show() + } + ChatMessage.MessageType.REGULAR_TEXT_MESSAGE -> { + chatViewModel.shareToNotes( + credentials!!, + ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl, roomToken), + message.message!!, + conversationUser!!.displayName!! + ) + Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show() + } + else -> {} + } + } + fun openInFilesApp(message: ChatMessage) { val keyID = message.selectedIndividualHashMap!![PreviewMessageViewHolder.KEY_ID] val link = message.selectedIndividualHashMap!!["link"] diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt index 3b6db4fd7..467549314 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt @@ -121,6 +121,18 @@ data class ChatMessage( @JsonField(name = ["markdown"]) var renderMarkdown: Boolean? = null, + @JsonField(name = ["lastEditActorDisplayName"]) + var lastEditActorDisplayName: String? = null, + + @JsonField(name = ["lastEditActorId"]) + var lastEditActorId: String? = null, + + @JsonField(name = ["lastEditActorType"]) + var lastEditActorType: String? = null, + + @JsonField(name = ["lastEditTimestamp"]) + var lastEditTimestamp: Long = 0, + var isDownloadingVoiceMessage: Boolean = false, var resetVoiceMessage: Boolean = false, diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt index 5f9847047..4431551ff 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt @@ -51,6 +51,7 @@ import com.nextcloud.talk.repositories.reactions.ReactionsRepository import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ConversationUtils +import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.vanniktech.emoji.EmojiPopup import com.vanniktech.emoji.EmojiTextView @@ -78,6 +79,9 @@ class MessageActionsDialog( @Inject lateinit var reactionsRepository: ReactionsRepository + @Inject + lateinit var dateUtils: DateUtils + private lateinit var dialogMessageActionsBinding: DialogMessageActionsBinding private lateinit var popup: EmojiPopup @@ -88,6 +92,11 @@ class MessageActionsDialog( private val messageHasRegularText = ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message .getCalculateMessageType() && !message.isDeleted + private val isMessageEditable = CapabilitiesUtilNew.hasSpreedFeatureCapability( + user, + "edit-messages" + ) && !message.isDeleted + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication?.componentApplication?.inject(this) @@ -129,6 +138,7 @@ class MessageActionsDialog( ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() && CapabilitiesUtilNew.isTranslationsSupported(user) ) + initMenuEditorDetails(message.lastEditTimestamp != 0L && isMessageEditable) initMenuReplyToMessage(message.replyable && hasChatPermission) initMenuReplyPrivately( message.replyable && @@ -136,7 +146,7 @@ class MessageActionsDialog( hasUserActorId(message) && currentConversation?.type != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ) - initMenuEditMessage(CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "edit-messages")) + initMenuEditMessage(isMessageEditable) initMenuDeleteMessage(showMessageDeletionButton) initMenuForwardMessage( ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() && @@ -318,13 +328,13 @@ class MessageActionsDialog( dismiss() } } - dialogMessageActionsBinding.menuDeleteMessage.visibility = getVisibility(visible) } private fun initMenuEditMessage(visible: Boolean) { dialogMessageActionsBinding.menuEditMessage.setOnClickListener { chatActivity.editMessage(message) + Log.d("EDIT MESSAGE", "$message") dismiss() } @@ -353,6 +363,16 @@ class MessageActionsDialog( dialogMessageActionsBinding.menuReplyToMessage.visibility = getVisibility(visible) } + private fun initMenuEditorDetails(showEditorDetails: Boolean) { + if (showEditorDetails) { + val editedTime = dateUtils.getLocalTimeStringFromTimestamp(message.lastEditTimestamp) + val editorName = "Edited by " + message.lastEditActorDisplayName + dialogMessageActionsBinding.editorName.setText(editorName) + dialogMessageActionsBinding.editedTime.setText(editedTime) + } + dialogMessageActionsBinding.menuMessageEditedInfo.visibility = getVisibility(showEditorDetails) + } + private fun initMenuItemCopy(visible: Boolean) { if (visible) { dialogMessageActionsBinding.menuCopyMessage.setOnClickListener { diff --git a/app/src/main/res/layout/dialog_message_actions.xml b/app/src/main/res/layout/dialog_message_actions.xml index db7d0fe2c..575a64129 100644 --- a/app/src/main/res/layout/dialog_message_actions.xml +++ b/app/src/main/res/layout/dialog_message_actions.xml @@ -127,6 +127,41 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + + + + + + Retrieval failed Languages could not be retrieved Edit Message Icon - Edit message + Edit Send Edit Message Clear Edit Message Cannot Edit Messages older than 24 hours @@ -796,4 +796,5 @@ How to translate with transifex: (edited) Conversation not found Add to Notes + Edited by admin