impr: show images in blogposts
This commit is contained in:
parent
6260796084
commit
d0347426c3
@ -5,8 +5,12 @@
|
|||||||
|
|
||||||
package ru.sweetbread.unn.ui.composes
|
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.text.util.Linkify
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.core.text.HtmlCompat
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import coil.ImageLoader
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.google.android.material.textview.MaterialTextView
|
import coil.request.ImageRequest
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
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()
|
val linkColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||||
|
|
||||||
AndroidView(
|
AndroidView(
|
||||||
|
modifier = Modifier,
|
||||||
factory = {
|
factory = {
|
||||||
MaterialTextView(it).apply {
|
TextView(it).apply {
|
||||||
|
movementMethod = LinkMovementMethod.getInstance()
|
||||||
autoLinkMask = Linkify.WEB_URLS
|
autoLinkMask = Linkify.WEB_URLS
|
||||||
linksClickable = true
|
linksClickable = true
|
||||||
setTextColor(textColor)
|
setTextColor(textColor)
|
||||||
@ -206,7 +212,12 @@ fun PostItem(modifier: Modifier = Modifier, post: Post, extended: Boolean = fals
|
|||||||
},
|
},
|
||||||
update = {
|
update = {
|
||||||
it.maxLines = if (extended) Int.MAX_VALUE else 5
|
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
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user