fix: lag when loading emotes into view

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2023-10-03 01:26:08 +02:00
parent ec46e95a70
commit a84ce38b1f
1 changed files with 51 additions and 50 deletions

View File

@ -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<MarkdownContext>() {
@ -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<Drawable>() {
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<in Drawable>?
) {
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)
}
}
}