Merge pull request #1894 from nextcloud/feature/noid/movePopupMenuToBottomSheet

Move popup menu to custom bottom sheet
This commit is contained in:
Marcel Hibbe 2022-04-01 14:49:56 +02:00 committed by GitHub
commit 108a568f66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 585 additions and 261 deletions

View File

@ -30,6 +30,7 @@ import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity.RESULT_OK import android.app.Activity.RESULT_OK
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
@ -55,7 +56,6 @@ import android.text.TextUtils
import android.text.TextWatcher import android.text.TextWatcher
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
@ -67,10 +67,8 @@ import android.view.animation.LinearInterpolator
import android.widget.AbsListView import android.widget.AbsListView
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import android.widget.PopupMenu
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker
@ -140,6 +138,7 @@ import com.nextcloud.talk.models.json.mention.Mention
import com.nextcloud.talk.presenters.MentionAutocompletePresenter import com.nextcloud.talk.presenters.MentionAutocompletePresenter
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet
import com.nextcloud.talk.ui.dialog.AttachmentDialog import com.nextcloud.talk.ui.dialog.AttachmentDialog
import com.nextcloud.talk.ui.dialog.MessageActionsDialog
import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions
import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
@ -579,7 +578,7 @@ class ChatController(args: Bundle) :
object : MessageSwipeActions { object : MessageSwipeActions {
override fun showReplyUI(position: Int) { override fun showReplyUI(position: Int) {
val chatMessage = adapter?.items?.get(position)?.item as ChatMessage? val chatMessage = adapter?.items?.get(position)?.item as ChatMessage?
replyToMessage(chatMessage, chatMessage?.jsonMessageId) replyToMessage(chatMessage)
} }
} }
) )
@ -2400,51 +2399,59 @@ class ChatController(args: Bundle) :
} }
override fun onMessageViewLongClick(view: View?, message: IMessage?) { override fun onMessageViewLongClick(view: View?, message: IMessage?) {
PopupMenu( if (hasVisibleItems(message as ChatMessage)) {
ContextThemeWrapper(view?.context, R.style.appActionBarPopupMenu), activity?.let {
view, MessageActionsDialog(
if ( activity!!,
message?.user?.id == currentConversation?.actorType + "/" + currentConversation?.actorId this,
) Gravity.END else Gravity.START message,
).apply { conversationUser?.userId,
setOnMenuItemClickListener { item -> currentConversation,
when (item?.itemId) { isShowMessageDeletionButton(message)
).show()
R.id.action_copy_message -> {
val clipboardManager =
activity?.getSystemService(Context.CLIPBOARD_SERVICE) as android.content.ClipboardManager
val clipData = ClipData.newPlainText(
resources?.getString(R.string.nc_app_product_name),
message?.text
)
clipboardManager.setPrimaryClip(clipData)
true
} }
R.id.action_mark_as_unread -> { }
val chatMessage = message as ChatMessage? }
if (chatMessage!!.previousMessageId > NO_PREVIOUS_MESSAGE_ID) {
ncApi!!.setChatReadMarker( fun deleteMessage(message: IMessage?) {
var apiVersion = 1
// FIXME Fix API checking with guests?
if (conversationUser != null) {
apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
}
ncApi?.deleteChatMessage(
credentials, credentials,
ApiUtils.getUrlForSetChatReadMarker( ApiUtils.getUrlForChatMessage(
ApiUtils.getChatApiVersion(conversationUser, intArrayOf(ApiUtils.APIv1)), apiVersion,
conversationUser?.baseUrl, conversationUser?.baseUrl,
roomToken roomToken,
), message?.id
chatMessage.previousMessageId
) )
.subscribeOn(Schedulers.io()) )?.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) ?.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> { ?.subscribe(object : Observer<ChatOverallSingleMessage> {
override fun onSubscribe(d: Disposable) { override fun onSubscribe(d: Disposable) {
// unused atm // unused atm
} }
override fun onNext(t: GenericOverall) { override fun onNext(t: ChatOverallSingleMessage) {
// unused atm if (t.ocs.meta.statusCode == HttpURLConnection.HTTP_ACCEPTED) {
Toast.makeText(
context, R.string.nc_delete_message_leaked_to_matterbridge,
Toast.LENGTH_LONG
).show()
}
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
Log.e(TAG, e.message, e) Log.e(
TAG,
"Something went wrong when trying to delete message with id " +
message?.id,
e
)
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
} }
override fun onComplete() { override fun onComplete() {
@ -2452,26 +2459,8 @@ class ChatController(args: Bundle) :
} }
}) })
} }
true
} fun replyPrivately(message: IMessage?) {
R.id.action_forward_message -> {
val bundle = Bundle()
bundle.putBoolean(BundleKeys.KEY_FORWARD_MSG_FLAG, true)
bundle.putString(BundleKeys.KEY_FORWARD_MSG_TEXT, message?.text)
bundle.putString(BundleKeys.KEY_FORWARD_HIDE_SOURCE_ROOM, roomId)
router.pushController(
RouterTransaction.with(ConversationsListController(bundle))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
)
true
}
R.id.action_reply_to_message -> {
val chatMessage = message as ChatMessage?
replyToMessage(chatMessage, message?.jsonMessageId)
true
}
R.id.action_reply_privately -> {
val apiVersion = val apiVersion =
ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom( val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
@ -2543,81 +2532,81 @@ class ChatController(args: Bundle) :
// unused atm // unused atm
} }
}) })
true
}
R.id.action_delete_message -> {
var apiVersion = 1
// FIXME Fix API checking with guests?
if (conversationUser != null) {
apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
} }
ncApi?.deleteChatMessage( fun forwardMessage(message: IMessage?) {
credentials, val bundle = Bundle()
ApiUtils.getUrlForChatMessage( bundle.putBoolean(BundleKeys.KEY_FORWARD_MSG_FLAG, true)
apiVersion, bundle.putString(BundleKeys.KEY_FORWARD_MSG_TEXT, message?.text)
conversationUser?.baseUrl, bundle.putString(BundleKeys.KEY_FORWARD_HIDE_SOURCE_ROOM, roomId)
roomToken, router.pushController(
message?.id RouterTransaction.with(ConversationsListController(bundle))
.pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler())
) )
)?.subscribeOn(Schedulers.io()) }
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<ChatOverallSingleMessage> { fun markAsUnread(message: IMessage?) {
val chatMessage = message as ChatMessage?
if (chatMessage!!.previousMessageId > NO_PREVIOUS_MESSAGE_ID) {
ncApi!!.setChatReadMarker(
credentials,
ApiUtils.getUrlForSetChatReadMarker(
ApiUtils.getChatApiVersion(conversationUser, intArrayOf(ApiUtils.APIv1)),
conversationUser?.baseUrl,
roomToken
),
chatMessage.previousMessageId
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onSubscribe(d: Disposable) { override fun onSubscribe(d: Disposable) {
// unused atm // unused atm
} }
override fun onNext(t: ChatOverallSingleMessage) { override fun onNext(t: GenericOverall) {
if (t.ocs.meta.statusCode == HttpURLConnection.HTTP_ACCEPTED) { // unused atm
Toast.makeText(
context, R.string.nc_delete_message_leaked_to_matterbridge,
Toast.LENGTH_LONG
).show()
}
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
Log.e( Log.e(TAG, e.message, e)
TAG,
"Something went wrong when trying to delete message with id " +
message?.id,
e
)
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
} }
override fun onComplete() { override fun onComplete() {
// unused atm // unused atm
} }
}) })
true
}
else -> false
}
}
inflate(R.menu.chat_message_menu)
menu.findItem(R.id.action_copy_message).isVisible = !(message as ChatMessage).isDeleted
menu.findItem(R.id.action_reply_to_message).isVisible = message.replyable
menu.findItem(R.id.action_reply_privately).isVisible = message.replyable &&
conversationUser?.userId?.isNotEmpty() == true && conversationUser.userId != "?" &&
message.user.id.startsWith("users/") &&
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
menu.findItem(R.id.action_delete_message).isVisible = isShowMessageDeletionButton(message)
menu.findItem(R.id.action_forward_message).isVisible =
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType()
menu.findItem(R.id.action_mark_as_unread).isVisible = message.previousMessageId > NO_PREVIOUS_MESSAGE_ID &&
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getMessageType() && BuildConfig.DEBUG
if (menu.hasVisibleItems()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
setForceShowIcon(true)
}
show()
}
} }
} }
private fun replyToMessage(chatMessage: ChatMessage?, jsonMessageId: Int?) { fun copyMessage(message: IMessage?) {
val clipboardManager =
activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText(
resources?.getString(R.string.nc_app_product_name),
message?.text
)
clipboardManager.setPrimaryClip(clipData)
}
private fun hasVisibleItems(message: ChatMessage): Boolean {
return !message.isDeleted || // copy message
message.replyable || // reply to
message.replyable && // reply privately
conversationUser?.userId?.isNotEmpty() == true && conversationUser?.userId != "?" &&
message.user.id.startsWith("users/") &&
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
isShowMessageDeletionButton(message) || // delete
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType() || // forward
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID && // mark as unread
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getMessageType() &&
BuildConfig.DEBUG
}
fun replyToMessage(message: IMessage?) {
val chatMessage = message as ChatMessage?
chatMessage?.let { chatMessage?.let {
binding.messageInputView.findViewById<ImageButton>(R.id.attachmentButton)?.visibility = binding.messageInputView.findViewById<ImageButton>(R.id.attachmentButton)?.visibility =
View.GONE View.GONE
@ -2665,7 +2654,7 @@ class ChatController(args: Bundle) :
val quotedChatMessageView = binding val quotedChatMessageView = binding
.messageInputView .messageInputView
.findViewById<RelativeLayout>(R.id.quotedChatMessageView) .findViewById<RelativeLayout>(R.id.quotedChatMessageView)
quotedChatMessageView?.tag = jsonMessageId quotedChatMessageView?.tag = message?.jsonMessageId
quotedChatMessageView?.visibility = View.VISIBLE quotedChatMessageView?.visibility = View.VISIBLE
} }
} }

View File

@ -0,0 +1,157 @@
/*
* Nextcloud Talk application
*
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.ui.dialog
import android.app.Activity
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.nextcloud.talk.BuildConfig
import com.nextcloud.talk.R
import com.nextcloud.talk.controllers.ChatController
import com.nextcloud.talk.databinding.DialogMessageActionsBinding
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.conversations.Conversation
class MessageActionsDialog(
val activity: Activity,
private val chatController: ChatController,
private val message: ChatMessage,
private val userId: String?,
private val currentConversation: Conversation?,
private val showMessageDeletionButton: Boolean
) : BottomSheetDialog(activity) {
private lateinit var dialogMessageActionsBinding: DialogMessageActionsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dialogMessageActionsBinding = DialogMessageActionsBinding.inflate(layoutInflater)
setContentView(dialogMessageActionsBinding.root)
window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
initMenuItemCopy(!message.isDeleted)
initMenuReplyToMessage(message.replyable)
initMenuReplyPrivately(
message.replyable &&
userId?.isNotEmpty() == true &&
userId != "?" &&
message.user.id.startsWith("users/") &&
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
)
initMenuDeleteMessage(showMessageDeletionButton)
initMenuForwardMessage(ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType())
initMenuMarkAsUnread(
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID &&
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getMessageType() &&
BuildConfig.DEBUG
)
}
private fun initMenuMarkAsUnread(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuMarkAsUnread.setOnClickListener {
chatController.markAsUnread(message)
dismiss()
}
}
dialogMessageActionsBinding.menuMarkAsUnread.visibility = getVisibility(visible)
}
private fun initMenuForwardMessage(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuForwardMessage.setOnClickListener {
chatController.forwardMessage(message)
dismiss()
}
}
dialogMessageActionsBinding.menuForwardMessage.visibility = getVisibility(visible)
}
private fun initMenuDeleteMessage(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuDeleteMessage.setOnClickListener {
chatController.deleteMessage(message)
dismiss()
}
}
dialogMessageActionsBinding.menuDeleteMessage.visibility = getVisibility(visible)
}
private fun initMenuReplyPrivately(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuReplyPrivately.setOnClickListener {
chatController.replyPrivately(message)
dismiss()
}
}
dialogMessageActionsBinding.menuReplyPrivately.visibility = getVisibility(visible)
}
private fun initMenuReplyToMessage(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuReplyToMessage.setOnClickListener {
chatController.replyToMessage(message)
dismiss()
}
}
dialogMessageActionsBinding.menuReplyToMessage.visibility = getVisibility(visible)
}
private fun initMenuItemCopy(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuCopyMessage.setOnClickListener {
chatController.copyMessage(message)
dismiss()
}
}
dialogMessageActionsBinding.menuCopyMessage.visibility = getVisibility(visible)
}
override fun onStart() {
super.onStart()
val bottomSheet = findViewById<View>(R.id.design_bottom_sheet)
val behavior = BottomSheetBehavior.from(bottomSheet as View)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
private fun getVisibility(visible: Boolean): Int {
return if (visible) {
View.VISIBLE
} else {
View.GONE
}
}
companion object {
private const val ACTOR_LENGTH = 6
private const val NO_PREVIOUS_MESSAGE_ID: Int = -1
}
}

View File

@ -49,8 +49,8 @@
<ImageView <ImageView
android:id="@+id/audio_output_bluetooth_icon" android:id="@+id/audio_output_bluetooth_icon"
android:layout_width="wrap_content" android:layout_width="11dp"
android:layout_height="wrap_content" android:layout_height="12dp"
android:contentDescription="@null" android:contentDescription="@null"
android:src="@drawable/ic_baseline_bluetooth_audio_24" android:src="@drawable/ic_baseline_bluetooth_audio_24"
app:tint="@color/grey_600" /> app:tint="@color/grey_600" />

View File

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud Talk application
~
~ @author Andy Scherzinger
~ Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/bg_bottom_sheet"
android:orientation="vertical"
android:paddingStart="@dimen/standard_padding"
android:paddingEnd="@dimen/standard_padding"
android:paddingBottom="@dimen/standard_half_padding">
<LinearLayout
android:id="@+id/menu_copy_message"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_copy_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_content_copy"
app:tint="@color/grey_600" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_copy_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/nc_copy_message"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout
android:id="@+id/menu_mark_as_unread"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_mark_as_unread"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_eye_off"
app:tint="@color/grey_600" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_mark_as_unread"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/nc_mark_as_unread"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout
android:id="@+id/menu_forward_message"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_forward_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_share_action"
app:tint="@color/grey_600" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_forward_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/nc_forward_message"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout
android:id="@+id/menu_reply_to_message"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_reply_to_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_reply"
app:tint="@color/grey_600" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_reply_to_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/nc_reply"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout
android:id="@+id/menu_reply_privately"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_reply_privately"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_reply"
app:tint="@color/grey_600" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_reply_privately"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/nc_reply_privately"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout
android:id="@+id/menu_delete_message"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_delete_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/ic_delete"
app:tint="@color/grey_600" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_delete_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/zero"
android:text="@string/nc_delete_message"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
</LinearLayout>

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_copy_message"
android:icon="@drawable/ic_content_copy"
android:title="@string/nc_copy_message"
app:showAsAction="always" />
<item
android:id="@+id/action_mark_as_unread"
android:icon="@drawable/ic_eye_off"
android:title="@string/nc_mark_as_unread"
app:showAsAction="always" />
<item
android:id="@+id/action_forward_message"
android:icon="@drawable/ic_share_action"
android:title="@string/nc_forward_message"
app:showAsAction="always" />
<item
android:id="@+id/action_reply_to_message"
android:icon="@drawable/ic_reply"
android:title="@string/nc_reply"
app:showAsAction="always" />
<item
android:id="@+id/action_reply_privately"
android:icon="@drawable/ic_reply"
android:title="@string/nc_reply_privately"
app:showAsAction="always" />
<item
android:id="@+id/action_delete_message"
android:icon="@drawable/ic_delete"
android:title="@string/nc_delete_message"
app:showAsAction="always" />
</menu>