Animated emoji support
This commit is contained in:
parent
5e9e626012
commit
2eba3f41ba
|
@ -47,6 +47,7 @@
|
|||
<string name="pref_title_hide_muted_users">Hide muted users</string>
|
||||
<string name="pref_title_enable_big_emojis">Enable bigger custom emojis</string>
|
||||
<string name="pref_title_enable_experimental_stickers">Enable experimental Pleroma-FE stickers(if available)</string>
|
||||
<string name="pref_title_animate_custom_emojis">Animate custom emojis</string>
|
||||
|
||||
<string name="attachment_type_image">Image</string>
|
||||
<string name="attachment_type_video">Video</string>
|
||||
|
|
|
@ -169,7 +169,7 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
|
|||
setDefaultValue(false)
|
||||
key = PrefKeys.HIDE_MUTED_USERS
|
||||
setTitle(R.string.pref_title_hide_muted_users)
|
||||
isSingleLineTitle = true
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
|
@ -192,6 +192,13 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
|
|||
setTitle(R.string.pref_title_enable_experimental_stickers)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.ANIMATE_CUSTOM_EMOJIS
|
||||
setTitle(R.string.pref_title_animate_custom_emojis)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_privacy) {
|
||||
|
|
|
@ -35,6 +35,7 @@ object PrefKeys {
|
|||
const val STICKERS = "stickers"
|
||||
const val ANONYMIZE_FILENAMES = "anonymizeFilenames"
|
||||
const val HIDE_MUTED_USERS = "hideMutedUsers"
|
||||
const val ANIMATE_CUSTOM_EMOJIS = "animateCustomEmojis"
|
||||
|
||||
const val CUSTOM_TABS = "customTabs"
|
||||
|
||||
|
|
|
@ -16,17 +16,13 @@
|
|||
@file:JvmName("CustomEmojiHelper")
|
||||
package com.keylesspalace.tusky.util
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.*
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.style.ReplacementSpan
|
||||
import android.view.View
|
||||
import androidx.core.text.toSpannable
|
||||
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
|
@ -37,6 +33,7 @@ import com.keylesspalace.tusky.entity.Emoji
|
|||
import java.lang.ref.WeakReference
|
||||
import java.util.regex.Pattern
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
|
||||
/**
|
||||
* replaces emoji shortcodes in a text with EmojiSpans
|
||||
|
@ -51,8 +48,8 @@ fun CharSequence.emojify(emojis: List<Emoji>?, view: View, forceSmallEmoji: Bool
|
|||
|
||||
val builder = SpannableString.valueOf(this)
|
||||
val pm = PreferenceManager.getDefaultSharedPreferences(view.context)
|
||||
val smallEmojis = forceSmallEmoji || !pm.getBoolean("bigEmojis", true)
|
||||
// val animatedEmojis = pm.getBoolean("animateEmojis", false)
|
||||
val smallEmojis = forceSmallEmoji || !pm.getBoolean(PrefKeys.BIG_EMOJIS, true)
|
||||
val animate = pm.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
||||
|
||||
emojis.forEach { (shortcode, url) ->
|
||||
val matcher = Pattern.compile(":$shortcode:", Pattern.LITERAL)
|
||||
|
@ -67,9 +64,9 @@ fun CharSequence.emojify(emojis: List<Emoji>?, view: View, forceSmallEmoji: Bool
|
|||
|
||||
builder.setSpan(span, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
Glide.with(view)
|
||||
.asBitmap()
|
||||
.asDrawable()
|
||||
.load(url)
|
||||
.into(span.getTarget())
|
||||
.into(span.getTarget(animate))
|
||||
}
|
||||
}
|
||||
return builder
|
||||
|
@ -112,11 +109,29 @@ open class EmojiSpan(val viewWeakReference: WeakReference<View>) : ReplacementSp
|
|||
}
|
||||
}
|
||||
|
||||
fun getTarget(): Target<Bitmap> {
|
||||
return object : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
fun getTarget(animate : Boolean): Target<Drawable> {
|
||||
return object : CustomTarget<Drawable>() {
|
||||
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
|
||||
viewWeakReference.get()?.let { view ->
|
||||
imageDrawable = BitmapDrawable(view.context.resources, resource)
|
||||
if(animate && resource is Animatable) {
|
||||
val callback = resource.callback
|
||||
|
||||
resource.callback = object: Drawable.Callback {
|
||||
override fun unscheduleDrawable(p0: Drawable, p1: Runnable) {
|
||||
callback?.unscheduleDrawable(p0, p1)
|
||||
}
|
||||
override fun scheduleDrawable(p0: Drawable, p1: Runnable, p2: Long) {
|
||||
callback?.scheduleDrawable(p0, p1, p2)
|
||||
}
|
||||
override fun invalidateDrawable(p0: Drawable) {
|
||||
callback?.invalidateDrawable(p0)
|
||||
view.invalidate()
|
||||
}
|
||||
}
|
||||
resource.start()
|
||||
}
|
||||
|
||||
imageDrawable = resource
|
||||
view.invalidate()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue