diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/ui/ConversationInfoScreen.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/ui/ConversationInfoScreen.kt index 960dcb5f4c..3fd87bd91b 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/ui/ConversationInfoScreen.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/ui/ConversationInfoScreen.kt @@ -86,6 +86,7 @@ import com.nextcloud.talk.models.json.status.StatusType import com.nextcloud.talk.ui.StatusDrawable import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils +import com.nextcloud.talk.utils.withLinks data class ConversationInfoScreenCallbacks( val onNavigateBack: () -> Unit = {}, @@ -328,7 +329,7 @@ private fun HeaderUserInfo(state: ConversationInfoUiState) { @Composable private fun ConversationDescriptionSection(description: String) { Text( - text = description, + text = description.withLinks(), style = MaterialTheme.typography.bodyMedium, modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/com/nextcloud/talk/utils/TextLinkUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/TextLinkUtils.kt new file mode 100644 index 0000000000..9c1cd4889c --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/utils/TextLinkUtils.kt @@ -0,0 +1,57 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.utils + +import android.util.Patterns +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.LinkAnnotation +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.style.TextDecoration + +@Composable +fun String.withLinks(linkColor: Color = MaterialTheme.colorScheme.primary): AnnotatedString = + remember(this, linkColor) { + buildAnnotatedString { + val matcher = Patterns.WEB_URL.matcher(this@withLinks) + var lastIndex = 0 + + while (matcher.find()) { + append(this@withLinks, lastIndex, matcher.start()) + + val url = matcher.group() + val actualUrl = if (UriUtils.hasHttpProtocolPrefixed(url)) url else "https://$url" + + val start = length + append(url) + + addStyle( + SpanStyle( + color = linkColor, + textDecoration = TextDecoration.Underline + ), + start, + length + ) + + addLink( + LinkAnnotation.Url(actualUrl), + start, + length + ) + + lastIndex = matcher.end() + } + + append(this@withLinks, lastIndex, this@withLinks.length) + } + }