Private
Public Access
1
0

Links in message bubbles

This commit is contained in:
2024-03-23 20:22:05 -07:00
parent f266e04895
commit 3d165b6acd
3 changed files with 55 additions and 3 deletions

View File

@@ -6,7 +6,10 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.cache
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.buzzert.kordophone.backend.model.Conversation
@@ -29,6 +32,7 @@ class ConversationListViewModel @Inject constructor(
) : ViewModel() {
val conversations: Flow<List<Conversation>>
get() = chatRepository.conversationChanges
.shareIn(viewModelScope, started = SharingStarted.WhileSubscribed())
.map {
it.sortedBy { it.date }
.reversed()

View File

@@ -19,6 +19,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
@@ -37,6 +38,7 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -58,6 +60,8 @@ import net.buzzert.kordophonedroid.ui.Destination
import net.buzzert.kordophonedroid.ui.LocalNavController
import net.buzzert.kordophonedroid.ui.attachments.AttachmentFetchData
import net.buzzert.kordophonedroid.ui.attachments.AttachmentViewModel
import net.buzzert.kordophonedroid.ui.shared.LINK_ANNOTATION_TAG
import net.buzzert.kordophonedroid.ui.shared.linkify
import net.buzzert.kordophonedroid.ui.theme.KordophoneTopAppBar
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
@@ -317,16 +321,27 @@ fun MessageBubble(
) {
val backgroundBubbleColor = if (mine) MaterialTheme.colors.primary else MaterialTheme.colors.secondary
// Linkify text
val annotatedString = text.linkify()
val urlHandler = LocalUriHandler.current
BubbleScaffold(mine = mine, modifier = modifier) {
Surface(
color = backgroundBubbleColor,
shape = if (mine) OutgoingChatBubbleShape else IncomingChatBubbleShape,
) {
Text(
text = text,
ClickableText(
text = annotatedString,
style = MaterialTheme.typography.body2,
modifier = Modifier
.padding(12.dp)
.padding(12.dp),
onClick = { index ->
annotatedString
.getStringAnnotations(LINK_ANNOTATION_TAG, index, index)
.firstOrNull()?.let {
urlHandler.openUri(it.item)
}
}
)
}
}

View File

@@ -0,0 +1,33 @@
package net.buzzert.kordophonedroid.ui.shared
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
const val LINK_ANNOTATION_TAG = "link"
private val LINK_REGEX = "(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]".toRegex()
fun String.linkify(): AnnotatedString {
val text = this
val matches = LINK_REGEX.findAll(this)
return buildAnnotatedString {
append(text)
for (match in matches) {
val range = match.range.also {
// Make inclusive.
IntRange(it.first, it.last + 1)
}
// Annotate link
addStringAnnotation(LINK_ANNOTATION_TAG, match.value, range.first, range.last)
// Add style
addStyle(
style = SpanStyle(textDecoration = TextDecoration.Underline),
start = range.first, end = range.last
)
}
}
}