mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 11:39:42 +01:00
commit
af1219290d
@ -41,10 +41,13 @@ import com.nextcloud.talk.utils.ConversationUtils
|
|||||||
import com.nextcloud.talk.utils.DateConstants
|
import com.nextcloud.talk.utils.DateConstants
|
||||||
import com.nextcloud.talk.utils.DateUtils
|
import com.nextcloud.talk.utils.DateUtils
|
||||||
import com.nextcloud.talk.utils.SpreedFeatures
|
import com.nextcloud.talk.utils.SpreedFeatures
|
||||||
|
import com.vanniktech.emoji.Emoji
|
||||||
import com.vanniktech.emoji.EmojiPopup
|
import com.vanniktech.emoji.EmojiPopup
|
||||||
import com.vanniktech.emoji.EmojiTextView
|
import com.vanniktech.emoji.EmojiTextView
|
||||||
import com.vanniktech.emoji.installDisableKeyboardInput
|
import com.vanniktech.emoji.installDisableKeyboardInput
|
||||||
import com.vanniktech.emoji.installForceSingleEmoji
|
import com.vanniktech.emoji.installForceSingleEmoji
|
||||||
|
import com.vanniktech.emoji.recent.RecentEmojiManager
|
||||||
|
import com.vanniktech.emoji.search.SearchEmojiManager
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
@ -246,30 +249,35 @@ class MessageActionsDialog(
|
|||||||
isPermitted(hasChatPermission) &&
|
isPermitted(hasChatPermission) &&
|
||||||
isReactableMessageType(message)
|
isReactableMessageType(message)
|
||||||
) {
|
) {
|
||||||
checkAndSetEmojiSelfReaction(dialogMessageActionsBinding.emojiThumbsUp)
|
val recentEmojiManager = RecentEmojiManager(context, MAX_RECENTS)
|
||||||
dialogMessageActionsBinding.emojiThumbsUp.setOnClickListener {
|
val recentEmojis = recentEmojiManager.getRecentEmojis()
|
||||||
clickOnEmoji(message, dialogMessageActionsBinding.emojiThumbsUp.text.toString())
|
val searchEmojiManager = SearchEmojiManager()
|
||||||
|
|
||||||
|
val initialSearchKeywords = listOf(
|
||||||
|
"thumbsup",
|
||||||
|
"thumbsdown",
|
||||||
|
"heart",
|
||||||
|
"joy",
|
||||||
|
"confused",
|
||||||
|
"cry",
|
||||||
|
"pray",
|
||||||
|
"fire"
|
||||||
|
)
|
||||||
|
val initialEmojisFromSearch = mutableSetOf<Emoji>()
|
||||||
|
|
||||||
|
initialSearchKeywords.forEach { keyword ->
|
||||||
|
val searchResults = searchEmojiManager.search(keyword)
|
||||||
|
if (searchResults.isNotEmpty()) {
|
||||||
|
initialEmojisFromSearch.add(searchResults[ZERO_INDEX].component1())
|
||||||
|
recentEmojiManager.addEmoji(searchResults[ZERO_INDEX].component1())
|
||||||
}
|
}
|
||||||
checkAndSetEmojiSelfReaction(dialogMessageActionsBinding.emojiThumbsDown)
|
if (initialEmojisFromSearch.size >= MAX_RECENTS) {
|
||||||
dialogMessageActionsBinding.emojiThumbsDown.setOnClickListener {
|
return@forEach
|
||||||
clickOnEmoji(message, dialogMessageActionsBinding.emojiThumbsDown.text.toString())
|
|
||||||
}
|
}
|
||||||
checkAndSetEmojiSelfReaction(dialogMessageActionsBinding.emojiLaugh)
|
|
||||||
dialogMessageActionsBinding.emojiLaugh.setOnClickListener {
|
|
||||||
clickOnEmoji(message, dialogMessageActionsBinding.emojiLaugh.text.toString())
|
|
||||||
}
|
|
||||||
checkAndSetEmojiSelfReaction(dialogMessageActionsBinding.emojiHeart)
|
|
||||||
dialogMessageActionsBinding.emojiHeart.setOnClickListener {
|
|
||||||
clickOnEmoji(message, dialogMessageActionsBinding.emojiHeart.text.toString())
|
|
||||||
}
|
|
||||||
checkAndSetEmojiSelfReaction(dialogMessageActionsBinding.emojiConfused)
|
|
||||||
dialogMessageActionsBinding.emojiConfused.setOnClickListener {
|
|
||||||
clickOnEmoji(message, dialogMessageActionsBinding.emojiConfused.text.toString())
|
|
||||||
}
|
|
||||||
checkAndSetEmojiSelfReaction(dialogMessageActionsBinding.emojiSad)
|
|
||||||
dialogMessageActionsBinding.emojiSad.setOnClickListener {
|
|
||||||
clickOnEmoji(message, dialogMessageActionsBinding.emojiSad.text.toString())
|
|
||||||
}
|
}
|
||||||
|
val combinedEmojis = (recentEmojis + initialEmojisFromSearch).toList().distinct().take(MAX_RECENTS)
|
||||||
|
|
||||||
|
setupEmojiView(combinedEmojis, recentEmojiManager)
|
||||||
|
|
||||||
dialogMessageActionsBinding.emojiMore.setOnClickListener {
|
dialogMessageActionsBinding.emojiMore.setOnClickListener {
|
||||||
dismiss()
|
dismiss()
|
||||||
@ -281,6 +289,50 @@ class MessageActionsDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupEmojiView(combinedEmojis: List<Emoji>, recentEmojiManager: RecentEmojiManager) {
|
||||||
|
val emojiSearchKeywords = mapOf(
|
||||||
|
"👍" to "thumbsup",
|
||||||
|
"👎" to "thumbsdown",
|
||||||
|
"❤️" to "heart",
|
||||||
|
"😂" to "joy",
|
||||||
|
"😕" to "confused",
|
||||||
|
"😢" to "cry",
|
||||||
|
"🙏" to "pray",
|
||||||
|
"🔥" to "fire"
|
||||||
|
)
|
||||||
|
|
||||||
|
val emojiTextViews = listOf(
|
||||||
|
dialogMessageActionsBinding.emojiThumbsUp,
|
||||||
|
dialogMessageActionsBinding.emojiThumbsDown,
|
||||||
|
dialogMessageActionsBinding.emojiHeart,
|
||||||
|
dialogMessageActionsBinding.emojiLaugh,
|
||||||
|
dialogMessageActionsBinding.emojiConfused,
|
||||||
|
dialogMessageActionsBinding.emojiCry,
|
||||||
|
dialogMessageActionsBinding.emojiPray,
|
||||||
|
dialogMessageActionsBinding.emojiFire
|
||||||
|
)
|
||||||
|
|
||||||
|
emojiTextViews.forEachIndexed { index, textView ->
|
||||||
|
val emoji = combinedEmojis.getOrNull(index)?.unicode
|
||||||
|
if (emoji != null) {
|
||||||
|
textView.text = emoji
|
||||||
|
checkAndSetEmojiSelfReaction(textView)
|
||||||
|
textView.setOnClickListener {
|
||||||
|
clickOnEmoji(message, emoji)
|
||||||
|
val keyword = emojiSearchKeywords[emoji] ?: ""
|
||||||
|
val result = SearchEmojiManager().search(keyword)
|
||||||
|
if (result.isNotEmpty()) {
|
||||||
|
recentEmojiManager.addEmoji(result[ZERO_INDEX].component1())
|
||||||
|
recentEmojiManager.persist()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
textView.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
textView.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isPermitted(hasChatPermission: Boolean): Boolean {
|
private fun isPermitted(hasChatPermission: Boolean): Boolean {
|
||||||
return hasChatPermission && ConversationEnums.ConversationReadOnlyState.CONVERSATION_READ_ONLY !=
|
return hasChatPermission && ConversationEnums.ConversationReadOnlyState.CONVERSATION_READ_ONLY !=
|
||||||
currentConversation?.conversationReadOnlyState
|
currentConversation?.conversationReadOnlyState
|
||||||
@ -531,5 +583,7 @@ class MessageActionsDialog(
|
|||||||
private const val DELAY: Long = 200
|
private const val DELAY: Long = 200
|
||||||
private const val AGE_THRESHOLD_FOR_EDIT_MESSAGE: Long = 86400000
|
private const val AGE_THRESHOLD_FOR_EDIT_MESSAGE: Long = 86400000
|
||||||
private const val ACTOR_BOTS = "bots"
|
private const val ACTOR_BOTS = "bots"
|
||||||
|
private const val ZERO_INDEX = 0
|
||||||
|
private const val MAX_RECENTS = 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,15 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<HorizontalScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:scrollbars="none">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/emojiBar"
|
android:id="@+id/emojiBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/standard_quarter_margin"
|
android:layout_marginStart="@dimen/standard_quarter_margin"
|
||||||
android:layout_marginTop="@dimen/standard_half_margin"
|
android:layout_marginTop="@dimen/standard_half_margin"
|
||||||
@ -84,7 +90,7 @@
|
|||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
|
|
||||||
<com.vanniktech.emoji.EmojiTextView
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
android:id="@+id/emojiSad"
|
android:id="@+id/emojiCry"
|
||||||
android:layout_width="@dimen/reaction_bottom_sheet_layout_size"
|
android:layout_width="@dimen/reaction_bottom_sheet_layout_size"
|
||||||
android:layout_height="@dimen/reaction_bottom_sheet_layout_size"
|
android:layout_height="@dimen/reaction_bottom_sheet_layout_size"
|
||||||
android:layout_marginLeft="@dimen/standard_quarter_margin"
|
android:layout_marginLeft="@dimen/standard_quarter_margin"
|
||||||
@ -94,6 +100,28 @@
|
|||||||
android:text="@string/emoji_sad"
|
android:text="@string/emoji_sad"
|
||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
|
android:id="@+id/emojiPray"
|
||||||
|
android:layout_width="@dimen/reaction_bottom_sheet_layout_size"
|
||||||
|
android:layout_height="@dimen/reaction_bottom_sheet_layout_size"
|
||||||
|
android:layout_marginLeft="@dimen/standard_quarter_margin"
|
||||||
|
android:layout_marginRight="@dimen/standard_quarter_margin"
|
||||||
|
android:cursorVisible="false"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/emoji_pray"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
|
android:id="@+id/emojiFire"
|
||||||
|
android:layout_width="@dimen/reaction_bottom_sheet_layout_size"
|
||||||
|
android:layout_height="@dimen/reaction_bottom_sheet_layout_size"
|
||||||
|
android:layout_marginLeft="@dimen/standard_quarter_margin"
|
||||||
|
android:layout_marginRight="@dimen/standard_half_margin"
|
||||||
|
android:cursorVisible="false"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/emoji_fire"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
<com.vanniktech.emoji.EmojiEditText
|
<com.vanniktech.emoji.EmojiEditText
|
||||||
android:id="@+id/emojiMore"
|
android:id="@+id/emojiMore"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@ -106,6 +134,7 @@
|
|||||||
android:paddingStart="@dimen/zero"
|
android:paddingStart="@dimen/zero"
|
||||||
android:paddingEnd="@dimen/standard_padding" />
|
android:paddingEnd="@dimen/standard_padding" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -384,6 +384,8 @@ How to translate with transifex:
|
|||||||
<string name="emoji_heart" translatable="false">❤️</string>
|
<string name="emoji_heart" translatable="false">❤️</string>
|
||||||
<string name="emoji_confused" translatable="false">😯</string>
|
<string name="emoji_confused" translatable="false">😯</string>
|
||||||
<string name="emoji_sad" translatable="false">😢</string>
|
<string name="emoji_sad" translatable="false">😢</string>
|
||||||
|
<string name="emoji_pray" translatable="false">🙏</string>
|
||||||
|
<string name="emoji_fire" translatable="false">🔥</string>
|
||||||
<string name="emoji_more" translatable="false">More emojis</string>
|
<string name="emoji_more" translatable="false">More emojis</string>
|
||||||
<string name="dontClear">Don\'t clear</string>
|
<string name="dontClear">Don\'t clear</string>
|
||||||
<string name="today">Today</string>
|
<string name="today">Today</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user