impr: show images in blogposts

This commit is contained in:
Sweetbread 2025-04-23 19:57:41 +03:00
parent 99effd1e52
commit 7f613a2106
Signed by: Sweetbread
GPG Key ID: 17A5CB9A7DD85319

View File

@ -5,8 +5,12 @@
package ru.sweetbread.unn.ui.composes
import android.graphics.drawable.Drawable
import android.text.Html
import android.text.method.LinkMovementMethod
import android.text.util.Linkify
import android.util.Log
import android.widget.TextView
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@ -43,11 +47,11 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.ImageLoader
import coil.compose.AsyncImage
import com.google.android.material.textview.MaterialTextView
import coil.request.ImageRequest
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@ -196,8 +200,10 @@ fun PostItem(modifier: Modifier = Modifier, post: Post, extended: Boolean = fals
val linkColor = MaterialTheme.colorScheme.primary.toArgb()
AndroidView(
modifier = Modifier,
factory = {
MaterialTextView(it).apply {
TextView(it).apply {
movementMethod = LinkMovementMethod.getInstance()
autoLinkMask = Linkify.WEB_URLS
linksClickable = true
setTextColor(textColor)
@ -206,7 +212,12 @@ fun PostItem(modifier: Modifier = Modifier, post: Post, extended: Boolean = fals
},
update = {
it.maxLines = if (extended) Int.MAX_VALUE else 5
it.text = HtmlCompat.fromHtml(html, 0)
it.text = Html.fromHtml(
html,
Html.FROM_HTML_MODE_LEGACY,
CoilImageGetter(it),
null
)
}
)
@ -257,4 +268,77 @@ fun PostItemPreview() {
)
}
}
}
class CoilImageGetter(
private val textView: TextView,
private val maxImageWidth: Int = textView.width
) : Html.ImageGetter {
override fun getDrawable(source: String): Drawable {
val urlDrawable = UrlDrawable()
if (maxImageWidth <= 0)
textView.post { updateImage(source, urlDrawable, textView.width) }
else
updateImage(source, urlDrawable, maxImageWidth)
return urlDrawable
}
private fun updateImage(source: String, urlDrawable: UrlDrawable, maxWidth: Int) {
val imageLoader = ImageLoader.Builder(textView.context)
.build()
val request = ImageRequest.Builder(textView.context)
.data(source)
.target { drawable ->
val (scaledWidth, scaledHeight) = calculateScaledSize(
drawable.intrinsicWidth,
drawable.intrinsicHeight,
maxWidth
)
drawable.setBounds(0, 0, scaledWidth, scaledHeight)
urlDrawable.drawable = drawable
urlDrawable.setBounds(0, 0, scaledWidth, scaledHeight)
textView.text = textView.text
}
.build()
imageLoader.enqueue(request)
}
private fun calculateScaledSize(
originalWidth: Int,
originalHeight: Int,
maxWidth: Int
): Pair<Int, Int> {
if (originalWidth <= maxWidth)
return Pair(originalWidth, originalHeight)
val ratio = maxWidth.toFloat() / originalWidth.toFloat()
return Pair(
maxWidth,
(originalHeight * ratio).toInt()
)
}
}
class UrlDrawable() : Drawable() {
var drawable: Drawable? = null
set(value) {
field = value
invalidateSelf()
}
override fun draw(canvas: android.graphics.Canvas) {
drawable?.draw(canvas)
}
override fun setAlpha(alpha: Int) {}
override fun setColorFilter(colorFilter: android.graphics.ColorFilter?) {}
override fun getOpacity(): Int = android.graphics.PixelFormat.TRANSLUCENT
}