From a84ce38b1fdaab850860b2c334d93ee72838fb3f Mon Sep 17 00:00:00 2001 From: Infi Date: Tue, 3 Oct 2023 01:26:08 +0200 Subject: [PATCH] fix: lag when loading emotes into view Signed-off-by: Infi --- .../internals/markdown/MarkdownNodes.kt | 101 +++++++++--------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt b/app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt index 2d9d779a..ad338a73 100644 --- a/app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt +++ b/app/src/main/java/chat/revolt/internals/markdown/MarkdownNodes.kt @@ -1,14 +1,16 @@ package chat.revolt.internals.markdown import android.content.Context +import android.graphics.drawable.Drawable import android.text.SpannableStringBuilder import android.text.Spanned +import android.util.Log import chat.revolt.api.REVOLT_FILES import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.load.resource.gif.GifDrawable +import com.bumptech.glide.request.target.CustomTarget import com.discord.simpleast.core.node.Node -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import kotlin.math.min class UserMentionNode(private val userId: String) : Node() { @@ -63,56 +65,55 @@ class CustomEmoteNode(private val emoteId: String, private val context: Context) val density = context.resources.displayMetrics.density.toInt() builder.append(content) - runBlocking(Dispatchers.IO) { - val drawable = try { - Glide.with(context) - .asDrawable() - .load(emoteUrl) - .submit() - .get() - } catch (e: Exception) { - null - }.also { - if (it == null) { - builder.replace( - builder.length - content.length, - builder.length, - content - ) - } - } ?: return@runBlocking - if (drawable is GifDrawable) { - drawable.apply { - start() - } - } - - val targetSize = if (renderContext.useLargeEmojis) 48 else 22 - val maxWidth = if (renderContext.useLargeEmojis) 58 else 38 - - val wantWidth = min( - (drawable.intrinsicWidth * (targetSize * density)) / drawable.intrinsicHeight, - maxWidth * density - ) - val wantHeight = targetSize * density - - builder.setSpan( - EmoteSpan( - drawable.apply { - setBounds(0, 0, wantWidth, wantHeight) + try { + Glide.with(context) + .asDrawable() + .load(emoteUrl) + .transition(DrawableTransitionOptions.withCrossFade()) + .into(object : CustomTarget() { + override fun onLoadCleared(placeholder: Drawable?) { + // no-op } - ), - builder.length - content.length, - builder.length, - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE - ) - builder.setSpan( - EmoteClickableSpan(emoteId), - builder.length - content.length, - builder.length, - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE - ) + + override fun onResourceReady( + resource: Drawable, + transition: com.bumptech.glide.request.transition.Transition? + ) { + if (resource is GifDrawable) { + resource.apply { + setLoopCount(GifDrawable.LOOP_FOREVER) + start() + } + } + + val targetSize = if (renderContext.useLargeEmojis) 48 else 22 + val maxWidth = if (renderContext.useLargeEmojis) 58 else 38 + + val wantWidth = min( + (resource.intrinsicWidth * (targetSize * density)) / resource.intrinsicHeight, + maxWidth * density + ) + val wantHeight = targetSize * density + + resource.setBounds(0, 0, wantWidth, wantHeight) + + builder.setSpan( + EmoteSpan(resource), + builder.length - content.length, + builder.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + builder.setSpan( + EmoteClickableSpan(emoteId), + builder.length - content.length, + builder.length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + }) + } catch (e: Exception) { + Log.e("CustomEmoteNode", "Failed to load emote", e) } } }