fix: lag when loading emotes into view
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
ec46e95a70
commit
a84ce38b1f
|
|
@ -1,14 +1,16 @@
|
||||||
package chat.revolt.internals.markdown
|
package chat.revolt.internals.markdown
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
|
import android.util.Log
|
||||||
import chat.revolt.api.REVOLT_FILES
|
import chat.revolt.api.REVOLT_FILES
|
||||||
import com.bumptech.glide.Glide
|
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.load.resource.gif.GifDrawable
|
||||||
|
import com.bumptech.glide.request.target.CustomTarget
|
||||||
import com.discord.simpleast.core.node.Node
|
import com.discord.simpleast.core.node.Node
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class UserMentionNode(private val userId: String) : Node<MarkdownContext>() {
|
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()
|
val density = context.resources.displayMetrics.density.toInt()
|
||||||
|
|
||||||
builder.append(content)
|
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) {
|
try {
|
||||||
drawable.apply {
|
Glide.with(context)
|
||||||
start()
|
.asDrawable()
|
||||||
}
|
.load(emoteUrl)
|
||||||
}
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
|
.into(object : CustomTarget<Drawable>() {
|
||||||
val targetSize = if (renderContext.useLargeEmojis) 48 else 22
|
override fun onLoadCleared(placeholder: Drawable?) {
|
||||||
val maxWidth = if (renderContext.useLargeEmojis) 58 else 38
|
// no-op
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
),
|
|
||||||
builder.length - content.length,
|
override fun onResourceReady(
|
||||||
builder.length,
|
resource: Drawable,
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
transition: com.bumptech.glide.request.transition.Transition<in Drawable>?
|
||||||
)
|
) {
|
||||||
builder.setSpan(
|
if (resource is GifDrawable) {
|
||||||
EmoteClickableSpan(emoteId),
|
resource.apply {
|
||||||
builder.length - content.length,
|
setLoopCount(GifDrawable.LOOP_FOREVER)
|
||||||
builder.length,
|
start()
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue