From 2eba3f41ba0638619df87f8f01268e29fe0bf258 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 19 Oct 2020 02:50:24 +0300 Subject: [PATCH] Animated emoji support --- app/src/husky/res/values/strings.xml | 1 + .../preference/PreferencesFragment.kt | 9 +++- .../tusky/settings/SettingsConstants.kt | 1 + .../tusky/util/CustomEmojiHelper.kt | 41 +++++++++++++------ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/app/src/husky/res/values/strings.xml b/app/src/husky/res/values/strings.xml index 6a5caeab..8c1fe345 100644 --- a/app/src/husky/res/values/strings.xml +++ b/app/src/husky/res/values/strings.xml @@ -47,6 +47,7 @@ Hide muted users Enable bigger custom emojis Enable experimental Pleroma-FE stickers(if available) + Animate custom emojis Image Video diff --git a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt index 370e4778..f1249b47 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/preference/PreferencesFragment.kt @@ -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) { diff --git a/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt b/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt index 6759d214..8aeed370 100644 --- a/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt +++ b/app/src/main/java/com/keylesspalace/tusky/settings/SettingsConstants.kt @@ -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" diff --git a/app/src/main/java/com/keylesspalace/tusky/util/CustomEmojiHelper.kt b/app/src/main/java/com/keylesspalace/tusky/util/CustomEmojiHelper.kt index 305a7945..99aa74f2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/CustomEmojiHelper.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/CustomEmojiHelper.kt @@ -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?, 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?, 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) : ReplacementSp } } - fun getTarget(): Target { - return object : CustomTarget() { - override fun onResourceReady(resource: Bitmap, transition: Transition?) { + fun getTarget(animate : Boolean): Target { + return object : CustomTarget() { + override fun onResourceReady(resource: Drawable, transition: Transition?) { 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() } }