Make image links in comments clickable

This commit is contained in:
FooIbar committed 2024-12-04 20:53:00 +08:00
1 parent d924237b7e
commit 53b3190bbf
2 files changed
+35 -31

No files matched your search

@@ -22,14 +22,35 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.compose.ConstraintLayout
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import coil3.compose.AsyncImage
import com.hippo.ehviewer.R
import com.hippo.ehviewer.client.data.GalleryComment
import com.hippo.ehviewer.ui.screen.breakToTextAndUrl
import com.hippo.ehviewer.ui.tools.thenIf
import com.hippo.ehviewer.util.ReadableTime
typealias TextOrUrl = Either<String, AnnotatedString>
typealias TextOrUrlList = List<TextOrUrl>
typealias TextOrUrls = Either<Pair<String, String>, AnnotatedString>
private const val IMAGE_OBJ = ''
private val IMAGE_PATTERN = Regex("(?:<a href=\"([^\"]+)\">)?<img src=\"([^\"]+)\"")
fun breakToTextAndUrls(origin: String, text: AnnotatedString): List<TextOrUrls> {
val urls = IMAGE_PATTERN.findAll(origin).toList()
if (urls.isEmpty()) return listOf(text.right())
val iter = urls.iterator()
var currentOfs = 0
return buildList<TextOrUrls> {
while (true) {
val index = text.text.indexOf(IMAGE_OBJ, currentOfs)
if (index == -1) break
add(text.subSequence(currentOfs, index).right())
add(iter.next().groupValues.let { it[1] to it[2] }.left())
currentOfs = index + 1
}
add(text.subSequence(currentOfs, text.length).right())
}
}
@Composable
fun GalleryCommentCard(
@@ -80,13 +101,19 @@ fun GalleryCommentCard(
onUrlClick(link.url)
}
if (showImage) {
val list = breakToTextAndUrl(comment.comment, processed)
val list = breakToTextAndUrls(comment.comment, processed)
list.forEach {
when (it) {
is Either.Left -> AsyncImage(
model = it.value,
contentDescription = null,
)
is Either.Left -> {
val (url, imageUrl) = it.value
AsyncImage(
model = imageUrl,
contentDescription = null,
modifier = Modifier.thenIf(url.isNotEmpty()) {
clickable { onUrlClick(url) }
},
)
}
is Either.Right -> Text(text = it.value)
}
}
@@ -75,8 +75,6 @@ import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.max
import androidx.compose.ui.util.lerp
import androidx.core.text.parseAsHtml
import arrow.core.left
import arrow.core.right
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhEngine
@@ -90,8 +88,6 @@ import com.hippo.ehviewer.dao.FilterMode
import com.hippo.ehviewer.ui.composing
import com.hippo.ehviewer.ui.jumpToReaderByPage
import com.hippo.ehviewer.ui.main.GalleryCommentCard
import com.hippo.ehviewer.ui.main.TextOrUrl
import com.hippo.ehviewer.ui.main.TextOrUrlList
import com.hippo.ehviewer.ui.openBrowser
import com.hippo.ehviewer.ui.tools.animateFloatMergePredictiveBackAsState
import com.hippo.ehviewer.ui.tools.normalizeSpan
@@ -114,27 +110,8 @@ import kotlin.sequences.forEach
import kotlinx.coroutines.launch
import moe.tarsin.coroutines.runSuspendCatching
private const val IMAGE_OBJ = ''
private val IMAGE_PATTERN = Regex("<img src=\"([^\"]+)\"")
private val URL_PATTERN = Regex("(http|https)://[a-z0-9A-Z%-]+(\\.[a-z0-9A-Z%-]+)+(:\\d{1,5})?(/[a-zA-Z0-9-_~:#@!&',;=%/*.?+$\\[\\]()]+)?/?")
fun breakToTextAndUrl(origin: String, text: AnnotatedString): TextOrUrlList {
val urls = IMAGE_PATTERN.findAll(origin).toList()
if (urls.isEmpty()) return listOf(text.right())
val iter = urls.iterator()
var currentOfs = 0
return buildList<TextOrUrl> {
while (true) {
val index = text.text.indexOf(IMAGE_OBJ, currentOfs)
if (index == -1) break
add(text.subSequence(currentOfs, index).right())
add(iter.next().groupValues[1].left())
currentOfs = index + 1
}
add(text.subSequence(currentOfs, text.length).right())
}
}
@Composable
fun processComment(
comment: GalleryComment,