From a0f02dbb08d74809e815b008170047f53448e4e8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 31 May 2021 17:22:37 +0200 Subject: [PATCH] Improved chat message long press popup --- .../chat/adapters/ChatMessagesListAdapter.kt | 101 ++++++++++-------- .../org/linphone/utils/AudioRouteUtils.kt | 2 +- .../main/res/drawable-xhdpi/menu_delete.png | Bin 0 -> 9869 bytes .../layout/chat_message_long_press_menu.xml | 100 +++++++++++++++++ app/src/main/res/menu/chat_message_menu.xml | 34 ------ app/src/main/res/values/dimen.xml | 4 +- app/src/main/res/values/styles.xml | 8 ++ 7 files changed, 167 insertions(+), 82 deletions(-) create mode 100644 app/src/main/res/drawable-xhdpi/menu_delete.png create mode 100644 app/src/main/res/layout/chat_message_long_press_menu.xml delete mode 100644 app/src/main/res/menu/chat_message_menu.xml diff --git a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt index f41b3e13c..4ba10d3cb 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt @@ -22,12 +22,10 @@ package org.linphone.activities.main.chat.adapters import android.content.ClipData import android.content.ClipboardManager import android.content.Context +import android.view.Gravity import android.view.LayoutInflater -import android.view.MenuInflater -import android.view.MenuItem import android.view.ViewGroup -import androidx.appcompat.view.menu.MenuBuilder -import androidx.appcompat.view.menu.MenuPopupHelper +import android.widget.PopupWindow import androidx.databinding.DataBindingUtil import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData @@ -46,6 +44,8 @@ import org.linphone.core.Content import org.linphone.core.EventLog import org.linphone.databinding.ChatEventListCellBinding import org.linphone.databinding.ChatMessageListCellBinding +import org.linphone.databinding.ChatMessageLongPressMenuBindingImpl +import org.linphone.utils.AppUtils import org.linphone.utils.Event class ChatMessagesListAdapter( @@ -194,60 +194,69 @@ class ChatMessagesListAdapter( if (contextMenuDisabled) return setContextMenuClickListener { - val builder = MenuBuilder(root.context) - val popupMenu = MenuPopupHelper(root.context, builder, background) - popupMenu.setForceShowIcon(true) - MenuInflater(root.context).inflate(R.menu.chat_message_menu, builder) + val popupView: ChatMessageLongPressMenuBindingImpl = DataBindingUtil.inflate( + LayoutInflater.from(root.context), + R.layout.chat_message_long_press_menu, null, false + ) + val itemSize = AppUtils.getDimension(R.dimen.chat_message_popup_item_height).toInt() + var totalSize = itemSize * 6 if (chatMessage.chatRoom.hasCapability(ChatRoomCapabilities.OneToOne.toInt()) || - chatMessage.state == ChatMessage.State.NotDelivered) { // No message id - builder.removeItem(R.id.chat_message_menu_imdn_infos) + chatMessage.state == ChatMessage.State.NotDelivered) { // No message id + popupView.imdnHidden = true + totalSize -= itemSize } if (chatMessage.state != ChatMessage.State.NotDelivered) { - builder.removeItem(R.id.chat_message_menu_resend) + popupView.resendHidden = true + totalSize -= itemSize } if (chatMessage.contents.find { content -> content.isText } == null) { - builder.removeItem(R.id.chat_message_menu_copy_text) + popupView.copyTextHidden = true + totalSize -= itemSize } if (chatMessage.isOutgoing || chatMessageViewModel.contact.value != null) { - builder.removeItem(R.id.chat_message_menu_add_to_contacts) + popupView.addToContactsHidden = true + totalSize -= itemSize } - builder.setCallback(object : MenuBuilder.Callback { - override fun onMenuModeChange(menu: MenuBuilder) {} + // When using WRAP_CONTENT instead of real size, fails to place the + // popup window above if not enough space is available below + val popupWindow = PopupWindow(popupView.root, + AppUtils.getDimension(R.dimen.chat_message_popup_width).toInt(), + totalSize, + true + ) + // Elevation is for showing a shadow around the popup + popupWindow.elevation = 20f - override fun onMenuItemSelected(menu: MenuBuilder, item: MenuItem): Boolean { - return when (item.itemId) { - R.id.chat_message_menu_imdn_infos -> { - showImdnDeliveryFragment() - true - } - R.id.chat_message_menu_resend -> { - resendMessage() - true - } - R.id.chat_message_menu_copy_text -> { - copyTextToClipboard() - true - } - R.id.chat_message_forward_message -> { - forwardMessage() - true - } - R.id.chat_message_menu_delete_message -> { - deleteMessage() - true - } - R.id.chat_message_menu_add_to_contacts -> { - addSenderToContacts() - true - } - else -> false - } - } - }) + popupView.setResendClickListener { + resendMessage() + popupWindow.dismiss() + } + popupView.setCopyTextClickListener { + copyTextToClipboard() + popupWindow.dismiss() + } + popupView.setForwardClickListener { + forwardMessage() + popupWindow.dismiss() + } + popupView.setImdnClickListener { + showImdnDeliveryFragment() + popupWindow.dismiss() + } + popupView.setAddToContactsClickListener { + addSenderToContacts() + popupWindow.dismiss() + } + popupView.setDeleteClickListener { + deleteMessage() + popupWindow.dismiss() + } + + val gravity = if (chatMessage.isOutgoing) Gravity.END else Gravity.START + popupWindow.showAsDropDown(background, 0, 0, gravity or Gravity.TOP) - popupMenu.show() true } } diff --git a/app/src/main/java/org/linphone/utils/AudioRouteUtils.kt b/app/src/main/java/org/linphone/utils/AudioRouteUtils.kt index 047923c49..8ab500bf1 100644 --- a/app/src/main/java/org/linphone/utils/AudioRouteUtils.kt +++ b/app/src/main/java/org/linphone/utils/AudioRouteUtils.kt @@ -26,7 +26,7 @@ import org.linphone.core.tools.Log class AudioRouteUtils { companion object { - private fun routeAudioTo(types : List, call: Call? = null) { + private fun routeAudioTo(types: List, call: Call? = null) { val listSize = types.size val stringBuilder = StringBuilder() var index = 0 diff --git a/app/src/main/res/drawable-xhdpi/menu_delete.png b/app/src/main/res/drawable-xhdpi/menu_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..65d612aae0e598aa867f64a31184b487d2456a73 GIT binary patch literal 9869 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 Sx_thHqpfbBR(ah%;(q}1FC4`H literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/chat_message_long_press_menu.xml b/app/src/main/res/layout/chat_message_long_press_menu.xml new file mode 100644 index 000000000..e781acbe3 --- /dev/null +++ b/app/src/main/res/layout/chat_message_long_press_menu.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/chat_message_menu.xml b/app/src/main/res/menu/chat_message_menu.xml deleted file mode 100644 index 491a0ef2c..000000000 --- a/app/src/main/res/menu/chat_message_menu.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index f94b98273..987cdabb8 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -11,7 +11,7 @@ 30dp 600dp 200dp - 50dp + 45dp 60dp 60dp 40dp @@ -24,4 +24,6 @@ 20dp 3dp 60dp + 250dp + 50dp \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 89f0bb18b..145af9234 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -169,6 +169,14 @@ 8.3sp + +