mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-06 14:27:24 +00:00
support reactions for TextMessages (in+out) and VoiceMessages (in+out)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
f17e892acd
commit
36b786616a
@ -74,6 +74,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
|
||||
lateinit var message: ChatMessage
|
||||
|
||||
lateinit var voiceMessageInterface: VoiceMessageInterface
|
||||
lateinit var reactionsInterface: ReactionsInterface
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBind(message: ChatMessage) {
|
||||
@ -140,6 +141,12 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reaction().showReactions(message, binding.reactions, context!!)
|
||||
|
||||
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
|
||||
reactionsInterface.onClickReactions(message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateDownloadState(message: ChatMessage) {
|
||||
@ -306,6 +313,10 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
|
||||
this.voiceMessageInterface = voiceMessageInterface
|
||||
}
|
||||
|
||||
fun assignReactionInterface(reactionsInterface: ReactionsInterface) {
|
||||
this.reactionsInterface = reactionsInterface
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "VoiceInMessageView"
|
||||
private const val SEEKBAR_START: Int = 0
|
||||
|
@ -36,9 +36,6 @@ import android.text.SpannableString
|
||||
import android.text.TextUtils
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
@ -57,7 +54,6 @@ import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.nextcloud.talk.utils.TextMatchers
|
||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||
import com.stfalcon.chatkit.messages.MessageHolders
|
||||
import com.vanniktech.emoji.EmojiTextView
|
||||
import java.util.HashMap
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -126,44 +122,10 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
|
||||
|
||||
itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
|
||||
|
||||
binding.reactionsEmojiWrapper.removeAllViews()
|
||||
if (message.reactions != null && message.reactions.isNotEmpty()) {
|
||||
Reaction().showReactions(message, binding.reactions, context!!)
|
||||
|
||||
var remainingEmojisToDisplay = MAX_EMOJIS_TO_DISPLAY
|
||||
val showInfoAboutMoreEmojis = message.reactions.size > MAX_EMOJIS_TO_DISPLAY
|
||||
for ((emoji, amount) in message.reactions) {
|
||||
val reactionEmoji = EmojiTextView(context)
|
||||
reactionEmoji.text = emoji
|
||||
|
||||
val reactionAmount = TextView(context)
|
||||
reactionAmount.text = amount.toString()
|
||||
|
||||
val params = RelativeLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
params.setMargins(
|
||||
DisplayUtils.convertDpToPixel(EMOJI_START_MARGIN, context).toInt(),
|
||||
0,
|
||||
DisplayUtils.convertDpToPixel(EMOJI_END_MARGIN, context).toInt(),
|
||||
0
|
||||
)
|
||||
reactionAmount.layoutParams = params
|
||||
|
||||
binding.reactionsEmojiWrapper.addView(reactionEmoji)
|
||||
binding.reactionsEmojiWrapper.addView(reactionAmount)
|
||||
|
||||
remainingEmojisToDisplay--
|
||||
if (remainingEmojisToDisplay == 0 && showInfoAboutMoreEmojis) {
|
||||
val infoAboutMoreEmojis = TextView(context)
|
||||
infoAboutMoreEmojis.text = "..."
|
||||
binding.reactionsEmojiWrapper.addView(infoAboutMoreEmojis)
|
||||
break
|
||||
}
|
||||
}
|
||||
binding.reactionsEmojiWrapper.setOnClickListener {
|
||||
reactionsInterface.onClickReactions(message)
|
||||
}
|
||||
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
|
||||
reactionsInterface.onClickReactions(message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,14 +268,11 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
|
||||
return messageStringInternal
|
||||
}
|
||||
|
||||
fun assignAdapter(reactionsInterface: ReactionsInterface) {
|
||||
fun assignReactionInterface(reactionsInterface: ReactionsInterface) {
|
||||
this.reactionsInterface = reactionsInterface
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TEXT_SIZE_MULTIPLIER = 2.5
|
||||
const val MAX_EMOJIS_TO_DISPLAY = 4
|
||||
const val EMOJI_START_MARGIN: Float = 2F
|
||||
const val EMOJI_END_MARGIN: Float = 8F
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,8 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
||||
@Inject
|
||||
var context: Context? = null
|
||||
|
||||
lateinit var reactionsInterface: ReactionsInterface
|
||||
|
||||
override fun onBind(message: ChatMessage) {
|
||||
super.onBind(message)
|
||||
sharedApplication!!.componentApplication.inject(this)
|
||||
@ -118,6 +120,12 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
||||
binding.checkMark.setContentDescription(readStatusContentDescriptionString)
|
||||
|
||||
itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
|
||||
|
||||
Reaction().showReactions(message, binding.reactions, context!!)
|
||||
|
||||
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
|
||||
reactionsInterface.onClickReactions(message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun processParentMessage(message: ChatMessage) {
|
||||
@ -204,6 +212,10 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
|
||||
return messageString1
|
||||
}
|
||||
|
||||
fun assignReactionInterface(reactionsInterface: ReactionsInterface) {
|
||||
this.reactionsInterface = reactionsInterface
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TEXT_SIZE_MULTIPLIER = 2.5
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
||||
lateinit var handler: Handler
|
||||
|
||||
lateinit var voiceMessageInterface: VoiceMessageInterface
|
||||
lateinit var reactionsInterface: ReactionsInterface
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBind(message: ChatMessage) {
|
||||
@ -129,6 +130,12 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
||||
}
|
||||
|
||||
binding.checkMark.setContentDescription(readStatusContentDescriptionString)
|
||||
|
||||
Reaction().showReactions(message, binding.reactions, context!!)
|
||||
|
||||
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
|
||||
reactionsInterface.onClickReactions(message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleResetVoiceMessageState(message: ChatMessage) {
|
||||
@ -279,6 +286,10 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
|
||||
this.voiceMessageInterface = voiceMessageInterface
|
||||
}
|
||||
|
||||
fun assignReactionInterface(reactionsInterface: ReactionsInterface) {
|
||||
this.reactionsInterface = reactionsInterface
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "VoiceOutMessageView"
|
||||
private const val SEEKBAR_START: Int = 0
|
||||
|
@ -0,0 +1,58 @@
|
||||
package com.nextcloud.talk.adapters.messages
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding
|
||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
import com.vanniktech.emoji.EmojiTextView
|
||||
|
||||
class Reaction {
|
||||
fun showReactions(message: ChatMessage, binding: ReactionsInsideMessageBinding, context: Context) {
|
||||
binding.reactionsEmojiWrapper.removeAllViews()
|
||||
if (message.reactions != null && message.reactions.isNotEmpty()) {
|
||||
|
||||
var remainingEmojisToDisplay = MAX_EMOJIS_TO_DISPLAY
|
||||
val showInfoAboutMoreEmojis = message.reactions.size > MAX_EMOJIS_TO_DISPLAY
|
||||
for ((emoji, amount) in message.reactions) {
|
||||
val reactionEmoji = EmojiTextView(context)
|
||||
reactionEmoji.text = emoji
|
||||
|
||||
val reactionAmount = TextView(context)
|
||||
reactionAmount.text = amount.toString()
|
||||
|
||||
val params = RelativeLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
params.setMargins(
|
||||
DisplayUtils.convertDpToPixel(EMOJI_START_MARGIN, context).toInt(),
|
||||
0,
|
||||
DisplayUtils.convertDpToPixel(EMOJI_END_MARGIN, context).toInt(),
|
||||
0
|
||||
)
|
||||
reactionAmount.layoutParams = params
|
||||
|
||||
binding.reactionsEmojiWrapper.addView(reactionEmoji)
|
||||
binding.reactionsEmojiWrapper.addView(reactionAmount)
|
||||
|
||||
remainingEmojisToDisplay--
|
||||
if (remainingEmojisToDisplay == 0 && showInfoAboutMoreEmojis) {
|
||||
val infoAboutMoreEmojis = TextView(context)
|
||||
infoAboutMoreEmojis.text = EMOJI_MORE
|
||||
binding.reactionsEmojiWrapper.addView(infoAboutMoreEmojis)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_EMOJIS_TO_DISPLAY = 4
|
||||
const val EMOJI_START_MARGIN: Float = 2F
|
||||
const val EMOJI_END_MARGIN: Float = 8F
|
||||
const val EMOJI_MORE = "..."
|
||||
}
|
||||
}
|
@ -49,14 +49,16 @@ public class TalkMessagesListAdapter<M extends IMessage> extends MessagesListAda
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
super.onBindViewHolder(holder, position);
|
||||
|
||||
if (holder instanceof IncomingVoiceMessageViewHolder) {
|
||||
if (holder instanceof MagicIncomingTextMessageViewHolder) {
|
||||
((MagicIncomingTextMessageViewHolder) holder).assignReactionInterface(chatController);
|
||||
} else if (holder instanceof MagicOutcomingTextMessageViewHolder) {
|
||||
((MagicOutcomingTextMessageViewHolder) holder).assignReactionInterface(chatController);
|
||||
} else if (holder instanceof IncomingVoiceMessageViewHolder) {
|
||||
((IncomingVoiceMessageViewHolder) holder).assignAdapter(chatController);
|
||||
((IncomingVoiceMessageViewHolder) holder).assignReactionInterface(chatController);
|
||||
} else if (holder instanceof OutcomingVoiceMessageViewHolder) {
|
||||
((OutcomingVoiceMessageViewHolder) holder).assignAdapter(chatController);
|
||||
}
|
||||
|
||||
if (holder instanceof MagicIncomingTextMessageViewHolder) {
|
||||
((MagicIncomingTextMessageViewHolder) holder).assignAdapter(chatController);
|
||||
((OutcomingVoiceMessageViewHolder) holder).assignReactionInterface(chatController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,23 +86,9 @@
|
||||
android:textIsSelectable="false"
|
||||
app:layout_alignSelf="center" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/reactions_emoji_wrapper"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_wrapBefore="true"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="5dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="emojis">
|
||||
</TextView>
|
||||
</LinearLayout>
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
layout="@layout/reactions_inside_message" />
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -108,5 +108,9 @@
|
||||
app:layout_alignSelf="center"
|
||||
tools:text="12:38"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
layout="@layout/reactions_inside_message" />
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
</RelativeLayout>
|
||||
|
@ -76,5 +76,9 @@
|
||||
android:contentDescription="@null"
|
||||
app:layout_alignSelf="center" />
|
||||
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
layout="@layout/reactions_inside_message" />
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
</RelativeLayout>
|
||||
|
@ -104,5 +104,9 @@
|
||||
app:layout_alignSelf="center"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
layout="@layout/reactions_inside_message" />
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
</RelativeLayout>
|
||||
|
18
app/src/main/res/layout/reactions_inside_message.xml
Normal file
18
app/src/main/res/layout/reactions_inside_message.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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:id="@+id/reactions_emoji_wrapper"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_alignSelf="flex_start"
|
||||
app:layout_flexGrow="1"
|
||||
app:layout_wrapBefore="true">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="emojis">
|
||||
</TextView>
|
||||
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user