Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.google.android.flexbox.JustifyContent
import network.loki.messenger.R
import network.loki.messenger.databinding.ViewEmojiReactionsBinding
import org.session.libsession.utilities.ThemeUtil
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.components.emoji.EmojiImageView
import org.thoughtcrime.securesms.components.emoji.EmojiUtil
Expand Down Expand Up @@ -68,7 +69,11 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener {
binding.layoutEmojiContainer.removeAllViews()
}

fun setReactions(messageId: MessageId, records: List<ReactionRecord>, outgoing: Boolean, delegate: VisibleMessageViewDelegate?) {
fun setReactions(messageId: MessageId,
threadRecipient: Recipient,
records: List<ReactionRecord>,
outgoing: Boolean,
delegate: VisibleMessageViewDelegate?) {
this.delegate = delegate
if (records == this.records) {
return
Expand All @@ -81,7 +86,7 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener {
extended = false
}
this.messageId = messageId
displayReactions(messageId, if (extended) Int.MAX_VALUE else DEFAULT_THRESHOLD)
displayReactions(messageId, threadRecipient, if (extended) Int.MAX_VALUE else DEFAULT_THRESHOLD)
}

override fun onTouch(v: View, event: MotionEvent): Boolean {
Expand All @@ -94,12 +99,18 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener {
return true
}

private fun displayReactions(messageId: MessageId, threshold: Int) {
private fun displayReactions(messageId: MessageId, threadRecipient: Recipient, threshold: Int) {
val userPublicKey = (context.applicationContext as ApplicationContext).loginStateRepository
.get()
.getLocalNumber()

val reactions = buildSortedReactionsList(messageId, records!!, userPublicKey, threshold)
val reactions = buildSortedReactionsList(
messageId = messageId,
threadRecipient = threadRecipient,
records = records!!,
userPublicKey = userPublicKey,
threshold = threshold
)
binding.layoutEmojiContainer.removeAllViews()
val overflowContainer = LinearLayout(context)
overflowContainer.orientation = LinearLayout.HORIZONTAL
Expand All @@ -116,7 +127,7 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener {
val pill = buildPill(context, this, reaction, true)
pill.setOnClickListener { v: View? ->
extended = true
displayReactions(messageId, Int.MAX_VALUE)
displayReactions(messageId, threadRecipient, Int.MAX_VALUE)
}
pill.findViewById<View>(R.id.reactions_pill_count).visibility = GONE
pill.findViewById<View>(R.id.reactions_pill_spacer).visibility = GONE
Expand Down Expand Up @@ -148,7 +159,7 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener {
for (id in binding.groupShowLess.referencedIds) {
findViewById<View>(id).setOnClickListener { view: View? ->
extended = false
displayReactions(messageId, DEFAULT_THRESHOLD)
displayReactions(messageId, threadRecipient, DEFAULT_THRESHOLD)
}
}
} else {
Expand All @@ -158,19 +169,23 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener {

private fun buildSortedReactionsList(
messageId: MessageId,
threadRecipient: Recipient,
records: List<ReactionRecord>,
userPublicKey: String?,
threshold: Int
): List<Reaction> {
val reactions = arrayListOf<Reaction>()

val accumulateReactionCount = !threadRecipient.isCommunityRecipient

// First go through reaction records and create a sorted list of reaction data based on emoji
for (record in records) {
val baseEmoji = EmojiUtil.getCanonicalRepresentation(record.emoji)
val index = reactions.binarySearchBy(baseEmoji) { it.emoji }
if (index >= 0) {
reactions[index].update(
count = record.count,
accumulateCount = accumulateReactionCount,
lastSeen = record.dateReceived,
userWasSender = record.author == userPublicKey
)
Expand Down Expand Up @@ -275,8 +290,13 @@ class EmojiReactionsView : ConstraintLayout, OnTouchListener {
var lastSeen: Long,
var userWasSender: Boolean,
) : Comparable<Reaction> {
fun update(count: Long, lastSeen: Long, userWasSender: Boolean) {
this.count = this.count.coerceAtLeast(count)
fun update(count: Long, accumulateCount: Boolean, lastSeen: Long, userWasSender: Boolean) {
if (accumulateCount) {
this.count += count
} else {
this.count = this.count.coerceAtLeast(count)
}

this.lastSeen = this.lastSeen.coerceAtLeast(lastSeen)
this.userWasSender = this.userWasSender || userWasSender
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,13 @@ class VisibleMessageView : FrameLayout {
val capabilities = (threadRecipient.address as? Address.Community)?.serverUrl?.let { lokiApiDb.getServerCapabilities(it) }
if (capabilities.isNullOrEmpty() || capabilities.contains(OpenGroupApi.Capability.REACTIONS.name.lowercase())) {
emojiReactionsBinding.value.root.let { root ->
root.setReactions(message.messageId, message.reactions, message.isOutgoing, delegate)
root.setReactions(
messageId = message.messageId,
threadRecipient = threadRecipient,
records = message.reactions,
outgoing = message.isOutgoing,
delegate = delegate
)
root.layoutParams = (root.layoutParams as ConstraintLayout.LayoutParams).apply {
horizontalBias = if (message.isOutgoing) 1f else 0f
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ data class ReactionRecord(
val emoji: String,
val serverId: String = "",
/**
* Count of this emoji per message. Note that this means that multiple rows with the same
* messageId and emoji will have the same count value (due to having different author).
*
* So you MUST NOT sum these counts across rows for one message.
* The meaning of count depends on the context:
* - When the message is from community, this count represents the total number of reactions of this type and
* it is the same across all ReactionRecords for the same emoji/messageId.
* - When the message is from a private chat, this count should be added up across all ReactionRecords for the
* same emoji/messageId to get the total number of reactions of this type.
*/
val count: Long = 0,
val sortId: Long = 0,
Expand Down