Unverified Commit 2bee6cfb authored by Leonardo Aramaki's avatar Leonardo Aramaki Committed by GitHub

Merge pull request #1674 from RocketChat/new/reactions-with-custom-emojis

[NEW] Add support for custom emojis on reactions
parents 93d43d3b 2b14e9be
...@@ -65,7 +65,9 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>( ...@@ -65,7 +65,9 @@ abstract class BaseViewHolder<T : BaseUiModel<*>>(
val manager = FlexboxLayoutManager(context, FlexDirection.ROW) val manager = FlexboxLayoutManager(context, FlexDirection.ROW)
recyclerView.layoutManager = manager recyclerView.layoutManager = manager
recyclerView.adapter = adapter recyclerView.adapter = adapter
adapter.addReactions(it.reactions.filterNot { it.unicode.startsWith(":") }) adapter.addReactions(it.reactions.filterNot { reactionUiModel ->
reactionUiModel.unicode.startsWith(":") && reactionUiModel.url.isNullOrEmpty()
})
} }
} }
} }
......
...@@ -5,6 +5,7 @@ import android.view.View ...@@ -5,6 +5,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.ReactionUiModel import chat.rocket.android.chatroom.uimodel.ReactionUiModel
...@@ -13,15 +14,13 @@ import chat.rocket.android.emoji.Emoji ...@@ -13,15 +14,13 @@ import chat.rocket.android.emoji.Emoji
import chat.rocket.android.emoji.EmojiKeyboardListener import chat.rocket.android.emoji.EmojiKeyboardListener
import chat.rocket.android.emoji.EmojiPickerPopup import chat.rocket.android.emoji.EmojiPickerPopup
import chat.rocket.android.emoji.EmojiReactionListener import chat.rocket.android.emoji.EmojiReactionListener
import chat.rocket.android.emoji.internal.GlideApp
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import kotlinx.android.synthetic.main.item_reaction.view.*
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
import javax.inject.Inject import javax.inject.Inject
class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() { class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
private const val REACTION_VIEW_TYPE = 0
private const val ADD_REACTION_VIEW_TYPE = 1
}
private val reactions = CopyOnWriteArrayList<ReactionUiModel>() private val reactions = CopyOnWriteArrayList<ReactionUiModel>()
var listener: EmojiReactionListener? = null var listener: EmojiReactionListener? = null
...@@ -74,9 +73,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -74,9 +73,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
fun contains(reactionShortname: String) = fun contains(reactionShortname: String) =
reactions.firstOrNull { it.shortname == reactionShortname } != null reactions.firstOrNull { it.shortname == reactionShortname } != null
class SingleReactionViewHolder(view: View, class SingleReactionViewHolder(
private val listener: EmojiReactionListener?) view: View,
: RecyclerView.ViewHolder(view), View.OnClickListener { private val listener: EmojiReactionListener?
) : RecyclerView.ViewHolder(view), View.OnClickListener {
@Inject @Inject
lateinit var localRepository: LocalRepository lateinit var localRepository: LocalRepository
@Volatile @Volatile
...@@ -95,23 +96,33 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -95,23 +96,33 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
clickHandled = false clickHandled = false
this.reaction = reaction this.reaction = reaction
with(itemView) { with(itemView) {
val emojiTextView = findViewById<TextView>(R.id.text_emoji) if (reaction.url.isNullOrEmpty()) {
val countTextView = findViewById<TextView>(R.id.text_count) text_emoji.text = reaction.unicode
emojiTextView.text = reaction.unicode view_flipper_reaction.displayedChild = 0
countTextView.text = reaction.count.toString() } else {
view_flipper_reaction.displayedChild = 1
val glideRequest = if (reaction.url!!.endsWith("gif", true)) {
GlideApp.with(context).asGif()
} else {
GlideApp.with(context).asBitmap()
}
glideRequest.load(reaction.url).into(image_emoji)
}
text_count.text = reaction.count.toString()
val myself = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY) val myself = localRepository.get(LocalRepository.CURRENT_USERNAME_KEY)
if (reaction.usernames.contains(myself)) { if (reaction.usernames.contains(myself)) {
val context = itemView.context val context = itemView.context
val resources = context.resources text_count.setTextColor(ContextCompat.getColor(context, R.color.colorAccent))
countTextView.setTextColor(resources.getColor(R.color.colorAccent))
} }
emojiTextView.setOnClickListener(this@SingleReactionViewHolder) view_flipper_reaction.setOnClickListener(this@SingleReactionViewHolder)
countTextView.setOnClickListener(this@SingleReactionViewHolder) text_count.setOnClickListener(this@SingleReactionViewHolder)
} }
} }
override fun onClick(v: View?) { override fun onClick(v: View) {
synchronized(this) { synchronized(this) {
if (!clickHandled) { if (!clickHandled) {
clickHandled = true clickHandled = true
...@@ -121,8 +132,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -121,8 +132,11 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
} }
} }
class AddReactionViewHolder(view: View, class AddReactionViewHolder(
private val listener: EmojiReactionListener?) : RecyclerView.ViewHolder(view) { view: View,
private val listener: EmojiReactionListener?
) : RecyclerView.ViewHolder(view) {
fun bind(messageId: String) { fun bind(messageId: String) {
itemView as ImageView itemView as ImageView
itemView.setOnClickListener { itemView.setOnClickListener {
...@@ -136,4 +150,9 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() ...@@ -136,4 +150,9 @@ class MessageReactionsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>()
} }
} }
} }
}
\ No newline at end of file companion object {
private const val REACTION_VIEW_TYPE = 0
private const val ADD_REACTION_VIEW_TYPE = 1
}
}
...@@ -5,5 +5,6 @@ data class ReactionUiModel( ...@@ -5,5 +5,6 @@ data class ReactionUiModel(
val shortname: String, val shortname: String,
val unicode: CharSequence, val unicode: CharSequence,
val count: Int, val count: Int,
val usernames: List<String> = emptyList() val usernames: List<String> = emptyList(),
var url: String? = null
) )
\ No newline at end of file
...@@ -18,6 +18,7 @@ import chat.rocket.android.chatroom.domain.MessageReply ...@@ -18,6 +18,7 @@ import chat.rocket.android.chatroom.domain.MessageReply
import chat.rocket.android.dagger.scope.PerFragment import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.db.DatabaseManager import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.emoji.EmojiParser import chat.rocket.android.emoji.EmojiParser
import chat.rocket.android.emoji.EmojiRepository
import chat.rocket.android.helper.MessageHelper import chat.rocket.android.helper.MessageHelper
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
import chat.rocket.android.helper.UserHelper import chat.rocket.android.helper.UserHelper
...@@ -504,15 +505,18 @@ class UiModelMapper @Inject constructor( ...@@ -504,15 +505,18 @@ class UiModelMapper @Inject constructor(
private fun getReactions(message: Message): List<ReactionUiModel> { private fun getReactions(message: Message): List<ReactionUiModel> {
val reactions = message.reactions?.let { val reactions = message.reactions?.let {
val list = mutableListOf<ReactionUiModel>() val list = mutableListOf<ReactionUiModel>()
val customEmojis = EmojiRepository.getCustomEmojis()
it.getShortNames().forEach { shortname -> it.getShortNames().forEach { shortname ->
val usernames = it.getUsernames(shortname) ?: emptyList() val usernames = it.getUsernames(shortname) ?: emptyList()
val count = usernames.size val count = usernames.size
val custom = customEmojis.firstOrNull { emoji -> emoji.shortname == shortname }
list.add( list.add(
ReactionUiModel(messageId = message.id, ReactionUiModel(messageId = message.id,
shortname = shortname, shortname = shortname,
unicode = EmojiParser.parse(context, shortname), unicode = EmojiParser.parse(context, shortname),
count = count, count = count,
usernames = usernames) usernames = usernames,
url = custom?.url)
) )
} }
list list
......
...@@ -5,5 +5,5 @@ ...@@ -5,5 +5,5 @@
android:width="24dp" android:width="24dp"
android:height="24dp" /> android:height="24dp" />
<solid android:color="#efeeee" /> <solid android:color="#efeeee" />
<corners android:radius="4dp"/> <corners android:radius="4dp" />
</shape> </shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout 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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="2dp" android:layout_marginEnd="2dp"
android:layout_marginRight="2dp" android:background="@drawable/rounded_background">
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
android:descendantFocusability="beforeDescendants"
android:background="@drawable/rounded_background"
android:orientation="horizontal">
<TextView <ViewFlipper
android:id="@+id/text_emoji" android:id="@+id/view_flipper_reaction"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" app:layout_constraintBottom_toBottomOf="parent"
android:maxLines="1" app:layout_constraintEnd_toStartOf="@+id/text_count"
android:paddingLeft="4dp" app:layout_constraintStart_toStartOf="parent"
android:paddingStart="4dp" app:layout_constraintTop_toTopOf="parent">
android:textColor="#868585"
android:textSize="16sp" <TextView
tools:text=":)" /> android:id="@+id/text_emoji"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:textColor="#868585"
android:textSize="16sp"
tools:text=":)" />
<ImageView
android:id="@+id/image_emoji"
android:layout_width="@dimen/custom_emoji_small"
android:layout_height="@dimen/custom_emoji_small"
android:layout_gravity="center"
tools:src="@tools:sample/avatars" />
</ViewFlipper>
<TextView <TextView
android:id="@+id/text_count" android:id="@+id/text_count"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:paddingBottom="4dp"
android:paddingEnd="4dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingStart="4dp" android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="4dp" android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingRight="4dp"
android:paddingBottom="4dp"
android:textColor="#868585" android:textColor="#868585"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/view_flipper_reaction"
app:layout_constraintTop_toTopOf="parent"
tools:text="12" /> tools:text="12" />
</LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
...@@ -210,7 +210,7 @@ object EmojiRepository { ...@@ -210,7 +210,7 @@ object EmojiRepository {
} }
} }
internal fun getCustomEmojis(): List<Emoji> = customEmojis fun getCustomEmojis(): List<Emoji> = customEmojis
/** /**
* Get all recently used emojis ordered by usage count. * Get all recently used emojis ordered by usage count.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment