Merge pull request #2007 from nextcloud/bugfix/2004/hideActionsReactionOnDeletedMessages

Hide actions reaction on deleted messages
This commit is contained in:
Andy Scherzinger 2022-05-09 17:44:11 +02:00 committed by GitHub
commit cd638591ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 157 additions and 55 deletions

View File

@ -49,68 +49,143 @@ class Reaction {
var remainingEmojisToDisplay = MAX_EMOJIS_TO_DISPLAY
val showInfoAboutMoreEmojis = message.reactions.size > MAX_EMOJIS_TO_DISPLAY
var textColor = ContextCompat.getColor(context, R.color.white)
if (!isOutgoingMessage) {
textColor = ContextCompat.getColor(binding.root.context, R.color.high_emphasis_text)
}
val textColor = getTextColor(context, isOutgoingMessage, binding)
val amountParams = getAmountLayoutParams(context)
val wrapperParams = getWrapperLayoutParams(context)
val amountParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
amountParams.marginStart = DisplayUtils.convertDpToPixel(AMOUNT_START_MARGIN, context).toInt()
val wrapperParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
wrapperParams.marginEnd = DisplayUtils.convertDpToPixel(EMOJI_END_MARGIN, context).toInt()
val paddingSide = DisplayUtils.convertDpToPixel(EMOJI_AND_AMOUNT_PADDING_SIDE, context).toInt()
val paddingTop = DisplayUtils.convertDpToPixel(WRAPPER_PADDING_TOP, context).toInt()
val paddingBottom = DisplayUtils.convertDpToPixel(WRAPPER_PADDING_BOTTOM, context).toInt()
for ((emoji, amount) in message.reactions) {
val emojiWithAmountWrapper = LinearLayout(context)
emojiWithAmountWrapper.orientation = LinearLayout.HORIZONTAL
val reactionEmoji = EmojiTextView(context)
reactionEmoji.text = emoji
emojiWithAmountWrapper.addView(reactionEmoji)
val reactionAmount = TextView(context)
reactionAmount.setTextColor(textColor)
reactionAmount.text = amount.toString()
reactionAmount.layoutParams = amountParams
emojiWithAmountWrapper.addView(reactionAmount)
emojiWithAmountWrapper.layoutParams = wrapperParams
val paddingSide = DisplayUtils.convertDpToPixel(EMOJI_AND_AMOUNT_PADDING_SIDE, context).toInt()
val paddingTop = DisplayUtils.convertDpToPixel(WRAPPER_PADDING_TOP, context).toInt()
val paddingBottom = DisplayUtils.convertDpToPixel(WRAPPER_PADDING_BOTTOM, context).toInt()
if (message.reactionsSelf != null &&
message.reactionsSelf.isNotEmpty() &&
message.reactionsSelf.contains(emoji)
) {
emojiWithAmountWrapper.background =
AppCompatResources.getDrawable(context, R.drawable.reaction_self_background)
emojiWithAmountWrapper.setPaddingRelative(paddingSide, paddingTop, paddingSide, paddingBottom)
} else {
emojiWithAmountWrapper.setPaddingRelative(0, paddingTop, paddingSide, paddingBottom)
}
val emojiWithAmountWrapper = getEmojiWithAmountWrapperLayout(
context,
message,
emoji,
amount,
EmojiWithAmountWrapperLayoutInfo(
textColor,
amountParams,
wrapperParams,
paddingSide,
paddingTop,
paddingBottom
),
)
binding.reactionsEmojiWrapper.addView(emojiWithAmountWrapper)
remainingEmojisToDisplay--
if (remainingEmojisToDisplay == 0 && showInfoAboutMoreEmojis) {
val infoAboutMoreEmojis = TextView(context)
infoAboutMoreEmojis.setTextColor(textColor)
infoAboutMoreEmojis.text = EMOJI_MORE
binding.reactionsEmojiWrapper.addView(infoAboutMoreEmojis)
binding.reactionsEmojiWrapper.addView(getMoreReactionsTextView(context, textColor))
break
}
}
}
}
private fun getEmojiWithAmountWrapperLayout(
context: Context,
message: ChatMessage,
emoji: String,
amount: Int,
layoutInfo: EmojiWithAmountWrapperLayoutInfo
): LinearLayout {
val emojiWithAmountWrapper = LinearLayout(context)
emojiWithAmountWrapper.orientation = LinearLayout.HORIZONTAL
emojiWithAmountWrapper.addView(getEmojiTextView(context, emoji))
emojiWithAmountWrapper.addView(getReactionCount(context, layoutInfo.textColor, amount, layoutInfo.amountParams))
emojiWithAmountWrapper.layoutParams = layoutInfo.wrapperParams
if (message.reactionsSelf != null &&
message.reactionsSelf.isNotEmpty() &&
message.reactionsSelf.contains(emoji)
) {
emojiWithAmountWrapper.background =
AppCompatResources.getDrawable(context, R.drawable.reaction_self_background)
emojiWithAmountWrapper.setPaddingRelative(
layoutInfo.paddingSide,
layoutInfo.paddingTop,
layoutInfo.paddingSide,
layoutInfo.paddingBottom
)
} else {
emojiWithAmountWrapper.setPaddingRelative(
0,
layoutInfo.paddingTop,
layoutInfo.paddingSide,
layoutInfo.paddingBottom
)
}
return emojiWithAmountWrapper
}
private fun getMoreReactionsTextView(context: Context, textColor: Int): TextView {
val infoAboutMoreEmojis = TextView(context)
infoAboutMoreEmojis.setTextColor(textColor)
infoAboutMoreEmojis.text = EMOJI_MORE
return infoAboutMoreEmojis
}
private fun getEmojiTextView(context: Context, emoji: String): EmojiTextView {
val reactionEmoji = EmojiTextView(context)
reactionEmoji.text = emoji
return reactionEmoji
}
private fun getReactionCount(
context: Context,
textColor: Int,
amount: Int,
amountParams: LinearLayout.LayoutParams
): TextView {
val reactionAmount = TextView(context)
reactionAmount.setTextColor(textColor)
reactionAmount.text = amount.toString()
reactionAmount.layoutParams = amountParams
return reactionAmount
}
private fun getWrapperLayoutParams(context: Context): LinearLayout.LayoutParams {
val wrapperParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
wrapperParams.marginEnd = DisplayUtils.convertDpToPixel(EMOJI_END_MARGIN, context).toInt()
return wrapperParams
}
private fun getAmountLayoutParams(context: Context): LinearLayout.LayoutParams {
val amountParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
amountParams.marginStart = DisplayUtils.convertDpToPixel(AMOUNT_START_MARGIN, context).toInt()
return amountParams
}
private fun getTextColor(
context: Context,
isOutgoingMessage: Boolean,
binding: ReactionsInsideMessageBinding
): Int {
var textColor = ContextCompat.getColor(context, R.color.white)
if (!isOutgoingMessage) {
textColor = ContextCompat.getColor(binding.root.context, R.color.high_emphasis_text)
}
return textColor
}
private data class EmojiWithAmountWrapperLayoutInfo(
val textColor: Int,
val amountParams: LinearLayout.LayoutParams,
val wrapperParams: LinearLayout.LayoutParams,
val paddingSide: Int,
val paddingTop: Int,
val paddingBottom: Int
)
companion object {
const val MAX_EMOJIS_TO_DISPLAY = 4
const val AMOUNT_START_MARGIN: Float = 2F

View File

@ -457,6 +457,7 @@ class ChatController(args: Bundle) :
currentConversation?.type == Conversation.ConversationType
.ROOM_TYPE_ONE_TO_ONE_CALL
@Suppress("Detekt.TooGenericExceptionCaught")
override fun onViewBound(view: View) {
Log.d(TAG, "onViewBound: " + System.identityHashCode(this).toString())
actionBar?.show()

View File

@ -336,6 +336,7 @@ class ProfileController : NewBaseController(R.layout.controller_profile) {
}
}
@Suppress("Detekt.TooGenericExceptionCaught")
private fun setErrorMessageForMultiList(headline: String, message: String, @DrawableRes errorResource: Int) {
if (activity == null) {
return

View File

@ -191,6 +191,7 @@ class ServerSelectionController :
}
@SuppressLint("LongLogTag")
@Suppress("Detekt.TooGenericExceptionCaught")
private fun checkServerAndProceed() {
dispose()
try {

View File

@ -182,6 +182,7 @@ class WebViewLoginController(args: Bundle? = null) : NewBaseController(
return false
}
@Suppress("Detekt.TooGenericExceptionCaught")
override fun onPageFinished(view: WebView, url: String) {
try {
loginStep++

View File

@ -617,6 +617,14 @@ public class ChatMessage implements MessageContentType, MessageContentType.Image
return "voice-message".equals(messageType);
}
public boolean isCommandMessage() {
return "command".equals(messageType);
}
public boolean isDeletedCommentMessage() {
return "comment_deleted".equals(messageType);
}
public enum MessageType {
REGULAR_TEXT_MESSAGE,
SYSTEM_MESSAGE,

View File

@ -76,14 +76,15 @@ class MessageActionsDialog(
initMenuReplyToMessage(message.replyable)
initMenuReplyPrivately(
message.replyable &&
user?.userId?.isNotEmpty() == true &&
user?.userId != "?" &&
message.user.id.startsWith("users/") &&
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
hasUserId(user) &&
hasUserActorId(message) &&
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
)
initMenuDeleteMessage(showMessageDeletionButton)
initMenuForwardMessage(ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType())
initMenuForwardMessage(
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType() &&
!(message.isDeletedCommentMessage || message.isDeleted)
)
initMenuMarkAsUnread(
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID &&
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getMessageType() &&
@ -98,6 +99,15 @@ class MessageActionsDialog(
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
private fun hasUserId(user: UserEntity?): Boolean {
return user?.userId?.isNotEmpty() == true && user?.userId != "?"
}
private fun hasUserActorId(message: ChatMessage): Boolean {
return message.user.id.startsWith("users/") &&
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId
}
@SuppressLint("ClickableViewAccessibility")
private fun initEmojiMore() {
dialogMessageActionsBinding.emojiMore.setOnTouchListener { v, event ->
@ -153,7 +163,8 @@ class MessageActionsDialog(
private fun initEmojiBar() {
if (CapabilitiesUtil.hasSpreedFeatureCapability(user, "reactions") &&
Conversation.ConversationReadOnlyState.CONVERSATION_READ_ONLY !=
currentConversation?.conversationReadOnlyState
currentConversation?.conversationReadOnlyState &&
isReactableMessageType(message)
) {
checkAndSetEmojiSelfReaction(dialogMessageActionsBinding.emojiThumbsUp)
dialogMessageActionsBinding.emojiThumbsUp.setOnClickListener {
@ -190,6 +201,10 @@ class MessageActionsDialog(
}
}
private fun isReactableMessageType(message: ChatMessage): Boolean {
return !(message.isCommandMessage || message.isDeletedCommentMessage || message.isDeleted)
}
private fun checkAndSetEmojiSelfReaction(emoji: EmojiTextView) {
if (emoji.text?.toString() != null && message.reactionsSelf?.contains(emoji.text?.toString()) == true) {
emoji.background = AppCompatResources.getDrawable(context, R.drawable.reaction_self_bottom_sheet_background)

View File

@ -1,5 +1,5 @@
build:
maxIssues: 95
maxIssues: 91
weights:
# complexity: 2
# LongParameterList: 1