Commit e286abc5 authored by Leonardo Aramaki's avatar Leonardo Aramaki

Let emojis to be rendered on the composer

parent e2c4ebf6
...@@ -72,7 +72,7 @@ class MessageViewHolder( ...@@ -72,7 +72,7 @@ class MessageViewHolder(
text_content.setTextColor( text_content.setTextColor(
if (data.isTemporary) Color.GRAY else Color.BLACK if (data.isTemporary) Color.GRAY else Color.BLACK
) )
data.message.let { data.message.let {
text_edit_indicator.isVisible = !it.isSystemMessage() && it.editedBy != null text_edit_indicator.isVisible = !it.isSystemMessage() && it.editedBy != null
image_star_indicator.isVisible = it.starred?.isNotEmpty() ?: false image_star_indicator.isVisible = it.starred?.isNotEmpty() ?: false
......
...@@ -6,21 +6,24 @@ import android.content.ClipData ...@@ -6,21 +6,24 @@ import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.SystemClock
import android.text.Spannable
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.style.ImageSpan
import android.view.KeyEvent import android.view.KeyEvent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Button import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.TextView
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.core.text.bold import androidx.core.text.bold
import androidx.core.view.isVisible import androidx.core.view.isVisible
...@@ -53,10 +56,11 @@ import chat.rocket.android.emoji.EmojiParser ...@@ -53,10 +56,11 @@ import chat.rocket.android.emoji.EmojiParser
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.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.circularRevealOrUnreveal import chat.rocket.android.util.extensions.circularRevealOrUnreveal
import chat.rocket.android.util.extensions.fadeIn import chat.rocket.android.util.extensions.fadeIn
import chat.rocket.android.util.extensions.fadeOut import chat.rocket.android.util.extensions.fadeOut
...@@ -70,6 +74,7 @@ import chat.rocket.common.model.RoomType ...@@ -70,6 +74,7 @@ import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.internal.realtime.socket.model.State import chat.rocket.core.internal.realtime.socket.model.State
import chat.rocket.core.model.ChatRoom import chat.rocket.core.model.ChatRoom
import com.bumptech.glide.load.resource.gif.GifDrawable
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
...@@ -78,6 +83,8 @@ import kotlinx.android.synthetic.main.fragment_chat_room.* ...@@ -78,6 +83,8 @@ import kotlinx.android.synthetic.main.fragment_chat_room.*
import kotlinx.android.synthetic.main.message_attachment_options.* import kotlinx.android.synthetic.main.message_attachment_options.*
import kotlinx.android.synthetic.main.message_composer.* import kotlinx.android.synthetic.main.message_composer.*
import kotlinx.android.synthetic.main.message_list.* import kotlinx.android.synthetic.main.message_list.*
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Inject import javax.inject.Inject
...@@ -127,7 +134,9 @@ internal const val MENU_ACTION_PINNED_MESSAGES = 4 ...@@ -127,7 +134,9 @@ internal const val MENU_ACTION_PINNED_MESSAGES = 4
internal const val MENU_ACTION_FAVORITE_MESSAGES = 5 internal const val MENU_ACTION_FAVORITE_MESSAGES = 5
internal const val MENU_ACTION_FILES = 6 internal const val MENU_ACTION_FILES = 6
class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener { class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener,
Drawable.Callback {
@Inject @Inject
lateinit var presenter: ChatRoomPresenter lateinit var presenter: ChatRoomPresenter
@Inject @Inject
...@@ -428,7 +437,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -428,7 +437,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} else { } else {
if (dy < 0 && !button_fab.isVisible) { if (dy < 0 && !button_fab.isVisible) {
button_fab.show() button_fab.show()
if (newMessageCount !=0) text_count.isVisible = true if (newMessageCount != 0) text_count.isVisible = true
} }
} }
} }
...@@ -487,14 +496,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -487,14 +496,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
if (isMessageReceived && button_fab.isVisible) { if (isMessageReceived && button_fab.isVisible) {
newMessageCount++ newMessageCount++
if (newMessageCount <= 99) if (newMessageCount <= 99)
text_count.text = newMessageCount.toString() text_count.text = newMessageCount.toString()
else else
text_count.text = "99+" text_count.text = "99+"
text_count.isVisible = true text_count.isVisible = true
} } else if (!button_fab.isVisible)
else if (!button_fab.isVisible)
recycler_view.scrollToPosition(0) recycler_view.scrollToPosition(0)
verticalScrollOffset.set(0) verticalScrollOffset.set(0)
empty_chat_view.isVisible = adapter.itemCount == 0 empty_chat_view.isVisible = adapter.itemCount == 0
...@@ -618,8 +626,29 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -618,8 +626,29 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun onEmojiAdded(emoji: Emoji) { override fun onEmojiAdded(emoji: Emoji) {
val cursorPosition = text_message.selectionStart val cursorPosition = text_message.selectionStart
if (cursorPosition > -1) { if (cursorPosition > -1) {
text_message.text?.insert(cursorPosition, EmojiParser.parse(context!!, emoji.shortname)) context?.let { ctx ->
text_message.setSelection(cursorPosition + emoji.unicode.length) launch(UI) {
val parsedText = EmojiParser.parseAsync(ctx, emoji.shortname).await()
if (parsedText is Spannable) {
val spans = parsedText.getSpans(0, parsedText.length, ImageSpan::class.java)
spans.forEach {
if (it.drawable is GifDrawable) {
it.drawable.callback = this@ChatRoomFragment
(it.drawable as GifDrawable).start()
}
}
text_message.text?.insert(text_message.selectionStart, parsedText)
text_message.text?.insert(text_message.selectionStart, " ")
}
// If it has no url then it's not a custom emoji.
if (emoji.url == null) {
text_message.setSelection(cursorPosition + emoji.unicode.length)
}
}
}
} }
} }
...@@ -750,9 +779,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -750,9 +779,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
button_send.isVisible = false button_send.isVisible = false
button_show_attachment_options.alpha = 1f button_show_attachment_options.alpha = 1f
button_show_attachment_options.isVisible = true button_show_attachment_options.isVisible = true
activity?.supportFragmentManager?.addOnBackStackChangedListener { activity?.supportFragmentManager?.addOnBackStackChangedListener {
println("attach") println("attach")
} }
activity?.supportFragmentManager?.registerFragmentLifecycleCallbacks( activity?.supportFragmentManager?.registerFragmentLifecycleCallbacks(
object : FragmentManager.FragmentLifecycleCallbacks() { object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) { override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) {
...@@ -764,6 +795,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -764,6 +795,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}, },
true true
) )
subscribeComposeTextMessage() subscribeComposeTextMessage()
emojiKeyboardPopup = emojiKeyboardPopup =
EmojiKeyboardPopup(activity!!, activity!!.findViewById(R.id.fragment_container)) EmojiKeyboardPopup(activity!!, activity!!.findViewById(R.id.fragment_container))
...@@ -883,7 +915,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -883,7 +915,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
clearMessageComposition(false) clearMessageComposition(false)
if (text_message.textContent.isEmpty()) { if (text_message.textContent.isEmpty()) {
KeyboardHelper.showSoftKeyboard(text_message) KeyboardHelper.showSoftKeyboard(text_message)
} }
} }
} }
...@@ -951,4 +983,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -951,4 +983,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private fun setupToolbar(toolbarTitle: String) { private fun setupToolbar(toolbarTitle: String) {
(activity as ChatRoomActivity).showToolbarTitle(toolbarTitle) (activity as ChatRoomActivity).showToolbarTitle(toolbarTitle)
} }
override fun unscheduleDrawable(who: Drawable?, what: Runnable?) {
text_message?.removeCallbacks(what)
}
override fun invalidateDrawable(p0: Drawable?) {
text_message?.invalidate()
}
override fun scheduleDrawable(who: Drawable?, what: Runnable?, w: Long) {
text_message?.postDelayed(what, w)
}
} }
...@@ -11,7 +11,6 @@ import android.text.Spanned ...@@ -11,7 +11,6 @@ import android.text.Spanned
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
import android.text.style.ImageSpan import android.text.style.ImageSpan
import android.text.style.ReplacementSpan import android.text.style.ReplacementSpan
import android.text.style.StyleSpan
import android.util.Patterns import android.util.Patterns
import android.view.View import android.view.View
import chat.rocket.android.R import chat.rocket.android.R
...@@ -137,13 +136,18 @@ class MessageParser @Inject constructor( ...@@ -137,13 +136,18 @@ class MessageParser @Inject constructor(
override fun visit(document: Document) { override fun visit(document: Document) {
val spannable = EmojiParser.parse(context, builder.text()) val spannable = EmojiParser.parse(context, builder.text())
if (spannable is Spanned) { if (spannable is Spanned) {
val spans = spannable.getSpans(0, spannable.length, EmojiTypefaceSpan::class.java) val emojiOneTypefaceSpans = spannable.getSpans(0, spannable.length,
val spans2 = spannable.getSpans(0, spannable.length, ImageSpan::class.java) EmojiTypefaceSpan::class.java)
spans.forEach { val emojiImageSpans = spannable.getSpans(0, spannable.length, ImageSpan::class.java)
builder.setSpan(it, spannable.getSpanStart(it), spannable.getSpanEnd(it), 0)
emojiOneTypefaceSpans.forEach {
builder.setSpan(it, spannable.getSpanStart(it), spannable.getSpanEnd(it),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
} }
spans2.forEach {
builder.setSpan(it, spannable.getSpanStart(it), spannable.getSpanEnd(it), 0) emojiImageSpans.forEach {
builder.setSpan(it, spannable.getSpanStart(it), spannable.getSpanEnd(it),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
} }
} }
} }
......
package chat.rocket.android.emoji package chat.rocket.android.emoji
import android.content.Context import android.content.Context
import androidx.appcompat.widget.AppCompatEditText import android.text.Spanned
import android.text.style.ImageSpan
import android.util.AttributeSet import android.util.AttributeSet
import android.view.KeyEvent import android.view.KeyEvent
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.text.getSpans
class ComposerEditText : AppCompatEditText { class ComposerEditText : AppCompatEditText {
var listener: ComposerEditTextListener? = null var listener: ComposerEditTextListener? = null
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
super(context, attrs, defStyleAttr) { super(context, attrs, defStyleAttr) {
isFocusable = true isFocusable = true
isFocusableInTouchMode = true isFocusableInTouchMode = true
isClickable = true isClickable = true
...@@ -20,6 +24,21 @@ class ComposerEditText : AppCompatEditText { ...@@ -20,6 +24,21 @@ class ComposerEditText : AppCompatEditText {
constructor(context: Context) : this(context, null) constructor(context: Context) : this(context, null)
override fun onSelectionChanged(selStart: Int, selEnd: Int) {
super.onSelectionChanged(selStart, selEnd)
text?.getSpans<ImageSpan>()?.forEach {
val s = text?.getSpanStart(it) ?: -1
val e = text?.getSpanEnd(it) ?: -1
val flags = if (selStart in s..e) {
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE or Spanned.SPAN_COMPOSING
} else {
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
}
text?.setSpan(it, s, e, flags)
}
}
override fun dispatchKeyEventPreIme(event: KeyEvent): Boolean { override fun dispatchKeyEventPreIme(event: KeyEvent): Boolean {
if (event.keyCode == KeyEvent.KEYCODE_BACK) { if (event.keyCode == KeyEvent.KEYCODE_BACK) {
val state = keyDispatcherState val state = keyDispatcherState
...@@ -43,4 +62,4 @@ class ComposerEditText : AppCompatEditText { ...@@ -43,4 +62,4 @@ class ComposerEditText : AppCompatEditText {
fun onKeyboardClosed() fun onKeyboardClosed()
fun onKeyboardOpened() fun onKeyboardOpened()
} }
} }
\ No newline at end of file
...@@ -2,19 +2,21 @@ package chat.rocket.android.emoji ...@@ -2,19 +2,21 @@ package chat.rocket.android.emoji
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.BitmapDrawable
import android.text.Spannable import android.text.Spannable
import android.text.SpannableString import android.text.SpannableString
import android.text.Spanned import android.text.Spanned
import android.text.style.ImageSpan import android.text.style.ImageSpan
import android.util.Log import android.util.Log
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.gif.GifDrawable import com.bumptech.glide.load.resource.gif.GifDrawable
import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.FutureTarget
import com.bumptech.glide.request.RequestFutureTarget
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.Deferred
import kotlinx.coroutines.experimental.async
class EmojiParser { class EmojiParser {
...@@ -77,7 +79,6 @@ class EmojiParser { ...@@ -77,7 +79,6 @@ class EmojiParser {
regex.findAll(spannable).iterator().forEach { match -> regex.findAll(spannable).iterator().forEach { match ->
customEmojis.find { it.shortname.toLowerCase() == match.value.toLowerCase() }?.let { customEmojis.find { it.shortname.toLowerCase() == match.value.toLowerCase() }?.let {
it.url?.let { url -> it.url?.let { url ->
try { try {
val glideRequest = if (url.endsWith("gif", true)) { val glideRequest = if (url.endsWith("gif", true)) {
Glide.with(context).asGif() Glide.with(context).asGif()
...@@ -85,7 +86,13 @@ class EmojiParser { ...@@ -85,7 +86,13 @@ class EmojiParser {
Glide.with(context).asBitmap() Glide.with(context).asBitmap()
} }
val futureTarget = glideRequest.load(url).submit(px, px) val futureTarget = glideRequest
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.onlyRetrieveFromCache(true))
.load(url)
.submit(px, px)
val range = match.range val range = match.range
futureTarget.get()?.let { image -> futureTarget.get()?.let { image ->
if (image is Bitmap) { if (image is Bitmap) {
...@@ -105,5 +112,13 @@ class EmojiParser { ...@@ -105,5 +112,13 @@ class EmojiParser {
} }
} }
} }
fun parseAsync(
context: Context,
text: CharSequence,
factory: Spannable.Factory? = null
): Deferred<CharSequence> {
return async(CommonPool) { parse(context, text, factory) }
}
} }
} }
...@@ -5,6 +5,9 @@ import android.content.SharedPreferences ...@@ -5,6 +5,9 @@ import android.content.SharedPreferences
import android.graphics.Typeface import android.graphics.Typeface
import chat.rocket.android.emoji.internal.EmojiCategory import chat.rocket.android.emoji.internal.EmojiCategory
import chat.rocket.android.emoji.internal.PREF_EMOJI_RECENTS import chat.rocket.android.emoji.internal.PREF_EMOJI_RECENTS
import com.bumptech.glide.Glide
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.launch
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedReader import java.io.BufferedReader
...@@ -15,6 +18,7 @@ import java.util.regex.Pattern ...@@ -15,6 +18,7 @@ import java.util.regex.Pattern
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.coroutines.experimental.buildSequence import kotlin.coroutines.experimental.buildSequence
object EmojiRepository { object EmojiRepository {
private val FITZPATRICK_REGEX = "(.*)_(tone[0-9]):".toRegex(RegexOption.IGNORE_CASE) private val FITZPATRICK_REGEX = "(.*)_(tone[0-9]):".toRegex(RegexOption.IGNORE_CASE)
...@@ -26,56 +30,68 @@ object EmojiRepository { ...@@ -26,56 +30,68 @@ object EmojiRepository {
internal lateinit var cachedTypeface: Typeface internal lateinit var cachedTypeface: Typeface
fun load(context: Context, customEmojis: List<Emoji> = emptyList(), path: String = "emoji.json") { fun load(context: Context, customEmojis: List<Emoji> = emptyList(), path: String = "emoji.json") {
this.customEmojis = customEmojis launch(CommonPool) {
preferences = context.getSharedPreferences("emoji", Context.MODE_PRIVATE) cachedTypeface = Typeface.createFromAsset(context.assets, "fonts/emojione-android.ttf")
ALL_EMOJIS.clear() this@EmojiRepository.customEmojis = customEmojis
cachedTypeface = Typeface.createFromAsset(context.assets, "fonts/emojione-android.ttf") preferences = context.getSharedPreferences("emoji", Context.MODE_PRIVATE)
val stream = context.assets.open(path) ALL_EMOJIS.clear()
val emojis = loadEmojis(stream).also { val stream = context.assets.open(path)
it.addAll(customEmojis) val emojis = loadEmojis(stream).also {
}.toList() it.addAll(customEmojis)
}.toList()
for (emoji in emojis) {
val unicodeIntList = mutableListOf<Int>() for (emoji in emojis) {
val unicodeIntList = mutableListOf<Int>()
// If empty it's a custom emoji.
if (emoji.unicode.isEmpty()) { // If empty it's a custom emoji.
ALL_EMOJIS.add(emoji) if (emoji.unicode.isEmpty()) {
continue ALL_EMOJIS.add(emoji)
} continue
}
emoji.unicode.split("-").forEach { emoji.unicode.split("-").forEach {
val value = it.toInt(16) val value = it.toInt(16)
if (value >= 0x10000) { if (value >= 0x10000) {
val surrogatePair = calculateSurrogatePairs(value) val surrogatePair = calculateSurrogatePairs(value)
unicodeIntList.add(surrogatePair.first) unicodeIntList.add(surrogatePair.first)
unicodeIntList.add(surrogatePair.second) unicodeIntList.add(surrogatePair.second)
} else { } else {
unicodeIntList.add(value) unicodeIntList.add(value)
}
} }
} val unicodeIntArray = unicodeIntList.toIntArray()
val unicodeIntArray = unicodeIntList.toIntArray() val unicode = String(unicodeIntArray, 0, unicodeIntArray.size)
val unicode = String(unicodeIntArray, 0, unicodeIntArray.size) val emojiWithUnicode = emoji.copy(unicode = unicode)
val emojiWithUnicode = emoji.copy(unicode = unicode) if (hasFitzpatrick(emoji.shortname)) {
if (hasFitzpatrick(emoji.shortname)) { val matchResult = FITZPATRICK_REGEX.find(emoji.shortname)
val matchResult = FITZPATRICK_REGEX.find(emoji.shortname) val prefix = matchResult!!.groupValues[1] + ":"
val prefix = matchResult!!.groupValues[1] + ":" val fitzpatrick = Fitzpatrick.valueOf(matchResult.groupValues[2])
val fitzpatrick = Fitzpatrick.valueOf(matchResult.groupValues[2]) val defaultEmoji = ALL_EMOJIS.firstOrNull { it.shortname == prefix }
val defaultEmoji = ALL_EMOJIS.firstOrNull { it.shortname == prefix } val emojiWithFitzpatrick = emojiWithUnicode.copy(fitzpatrick = fitzpatrick)
val emojiWithFitzpatrick = emojiWithUnicode.copy(fitzpatrick = fitzpatrick) if (defaultEmoji != null) {
if (defaultEmoji != null) { defaultEmoji.siblings.add(emojiWithFitzpatrick)
defaultEmoji.siblings.add(emojiWithFitzpatrick) } else {
// This emoji doesn't have a default tone, ie. :man_in_business_suit_levitating_tone1:
// In this case, the default emoji becomes the first toned one.
ALL_EMOJIS.add(emojiWithFitzpatrick)
}
} else { } else {
// This emoji doesn't have a default tone, ie. :man_in_business_suit_levitating_tone1: ALL_EMOJIS.add(emojiWithUnicode)
// In this case, the default emoji becomes the first toned one. }
ALL_EMOJIS.add(emojiWithFitzpatrick) shortNameToUnicode.apply {
put(emoji.shortname, unicode)
emoji.shortnameAlternates.forEach { alternate -> put(alternate, unicode) }
} }
} else {
ALL_EMOJIS.add(emojiWithUnicode)
} }
shortNameToUnicode.apply {
put(emoji.shortname, unicode) val density = context.resources.displayMetrics.density
emoji.shortnameAlternates.forEach { alternate -> put(alternate, unicode) } val px = (32 * density).toInt()
customEmojis.forEach {
val future = Glide.with(context)
.load(it.url)
.submit(px, px)
future.get()
} }
} }
} }
......
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