# HG changeset patch # User Da Risk # Date 1745789317 14400 # Node ID ed956769792c57938c064bfce9abf0dc65269f06 # Parent e9663e1763b0ab7e9879b3842b46ce68204876aa ui:material2: update creation of LinkAnnotation.Url diff -r e9663e1763b0 -r ed956769792c ui/material2/src/commonMain/kotlin/com/geekorum/aboutoss/ui/material/OpenSourceLicenseScreen.kt --- a/ui/material2/src/commonMain/kotlin/com/geekorum/aboutoss/ui/material/OpenSourceLicenseScreen.kt Sun Apr 27 16:48:23 2025 -0400 +++ b/ui/material2/src/commonMain/kotlin/com/geekorum/aboutoss/ui/material/OpenSourceLicenseScreen.kt Sun Apr 27 17:28:37 2025 -0400 @@ -22,7 +22,6 @@ package com.geekorum.aboutoss.ui.material import androidx.compose.animation.core.animateDpAsState -import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize @@ -42,19 +41,17 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.ui.text.LinkAnnotation +import androidx.compose.ui.text.LinkInteractionListener import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.TextLayoutResult -import androidx.compose.ui.text.UrlAnnotation import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.text.withAnnotation +import androidx.compose.ui.text.withLink import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import com.geekorum.aboutoss.ui.common.BrowserLauncher @@ -107,10 +104,12 @@ onUrlClick: (String) -> Unit, onUrlsFound: (List) -> Unit, ) { - val linkifiedLicense = linkifyText(text = license) + val linkifiedLicense = linkifyText(text = license, onUrlClick) LaunchedEffect(linkifiedLicense) { val uris = - linkifiedLicense.getUrlAnnotations(0, linkifiedLicense.length).map { it.item.url } + linkifiedLicense.getLinkAnnotations(0, linkifiedLicense.length).map { it.item } + .filterIsInstance() + .map { it.url } onUrlsFound(uris) } @@ -135,31 +134,13 @@ elevation = topBarElevation ) }) { paddingValues -> - val layoutResult = remember { mutableStateOf(null) } - val pressIndicator = Modifier.pointerInput(layoutResult, linkifiedLicense) { - detectTapGestures { pos -> - layoutResult.value?.let { layoutResult -> - val posWithScroll = pos.copy(y = pos.y + scrollState.value) - val offset = layoutResult.getOffsetForPosition(posWithScroll) - linkifiedLicense.getUrlAnnotations(start = offset, end = offset) - .firstOrNull()?.let { annotation -> - onUrlClick(annotation.item.url) - } - } - } - } - Text(linkifiedLicense, modifier = Modifier .padding(paddingValues) .consumeWindowInsets(paddingValues) .padding(horizontal = 16.dp) .fillMaxSize() - .then(pressIndicator) .verticalScroll(scrollState), - onTextLayout = { - layoutResult.value = it - } ) } } @@ -171,7 +152,7 @@ @OptIn(ExperimentalTextApi::class) @Composable -private fun linkifyText(text: String): AnnotatedString { +private fun linkifyText(text: String, onUrlClick: (String) -> Unit): AnnotatedString { val style = SpanStyle( color = MaterialTheme.colors.secondary, textDecoration = TextDecoration.Underline @@ -184,7 +165,17 @@ append(text.substring(currentIdx, match.range.first)) } val url = text.substring(match.range) - withAnnotation(UrlAnnotation(url)) { + val linkInteractionListener = LinkInteractionListener { + val url = when(it) { + is LinkAnnotation.Url -> it.url + is LinkAnnotation.Clickable -> it.tag + else -> null + } + if (url != null) { + onUrlClick(url) + } + } + withLink(LinkAnnotation.Url(url, linkInteractionListener = linkInteractionListener)) { withStyle(style) { append(url) }