Split link text into a ListSupportingText component.

This also requires some internal changes to `ListSupportingText`, `ClickableLinkText` and `TimelineTextView` to match the behaviour and design.
This commit is contained in:
Jorge Martín 2023-08-30 09:33:53 +02:00
parent 3a6de68721
commit 0a77590e76
4 changed files with 69 additions and 70 deletions

View file

@ -16,26 +16,23 @@
package io.element.android.features.analytics.api.preferences package io.element.android.features.analytics.api.preferences
import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.layout.Column
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.analytics.api.AnalyticsOptInEvents import io.element.android.features.analytics.api.AnalyticsOptInEvents
import io.element.android.libraries.designsystem.components.LINK_TAG
import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithStyledPart import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithStyledPart
import io.element.android.libraries.designsystem.theme.components.ListItem import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.ListSupportingText
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
private const val LINK_TAG = "link"
@Composable @Composable
fun AnalyticsPreferencesView( fun AnalyticsPreferencesView(
state: AnalyticsPreferencesState, state: AnalyticsPreferencesState,
@ -46,43 +43,37 @@ fun AnalyticsPreferencesView(
state.eventSink(AnalyticsOptInEvents.EnableAnalytics(isEnabled = isEnabled)) state.eventSink(AnalyticsOptInEvents.EnableAnalytics(isEnabled = isEnabled))
} }
val firstPart = stringResource(id = CommonStrings.screen_analytics_settings_help_us_improve, state.applicationName) val linkText = buildAnnotatedStringWithStyledPart(
val secondPart = buildAnnotatedStringWithStyledPart(
CommonStrings.screen_analytics_settings_read_terms, CommonStrings.screen_analytics_settings_read_terms,
CommonStrings.screen_analytics_settings_read_terms_content_link, CommonStrings.screen_analytics_settings_read_terms_content_link,
tagAndLink = LINK_TAG to state.policyUrl, tagAndLink = LINK_TAG to state.policyUrl,
) )
val subtitle = buildAnnotatedString { val supportingText = stringResource(
append(firstPart) id = CommonStrings.screen_analytics_settings_help_us_improve,
append("\n\n") state.applicationName
append(secondPart) )
Column(modifier) {
ListItem(
headlineContent = {
Text(stringResource(id = CommonStrings.screen_analytics_settings_share_data))
},
supportingContent = {
Text(supportingText)
},
leadingContent = null,
trailingContent = ListItemContent.Switch(
checked = state.isEnabled,
),
onClick = {
onEnabledChanged(!state.isEnabled)
}
)
ListSupportingText(annotatedString = linkText)
} }
ListItem(
headlineContent = {
Text(stringResource(id = CommonStrings.screen_analytics_settings_share_data))
},
supportingContent = {
ClickableText(
text = subtitle,
onClick = {
subtitle
.getStringAnnotations(LINK_TAG, it, it)
.firstOrNull()
?.let { stringAnnotation ->
onOpenAnalyticsPolicy(stringAnnotation.item)
}
},
style = ElementTheme.typography.fontBodyMdRegular
.copy(
color = MaterialTheme.colorScheme.secondary,
),
)
},
leadingContent = null,
trailingContent = ListItemContent.Switch(checked = state.isEnabled, onChange = ::onEnabledChanged),
modifier = modifier,
)
} }
@Preview @Preview

View file

@ -21,7 +21,9 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -35,6 +37,7 @@ import io.element.android.libraries.designsystem.components.ClickableLinkText
import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.text.toAnnotatedString import io.element.android.libraries.designsystem.text.toAnnotatedString
import io.element.android.libraries.theme.ElementTheme
@Composable @Composable
fun TimelineItemTextView( fun TimelineItemTextView(
@ -45,31 +48,33 @@ fun TimelineItemTextView(
onTextClicked: () -> Unit = {}, onTextClicked: () -> Unit = {},
onTextLongClicked: () -> Unit = {}, onTextLongClicked: () -> Unit = {},
) { ) {
val htmlDocument = content.htmlDocument CompositionLocalProvider(LocalContentColor provides ElementTheme.colors.textPrimary) {
if (htmlDocument != null) { val htmlDocument = content.htmlDocument
// For now we ignore the extra padding for html content, so add some spacing if (htmlDocument != null) {
// below the content (as previous behavior) // For now we ignore the extra padding for html content, so add some spacing
Column(modifier = modifier) { // below the content (as previous behavior)
HtmlDocument( Column(modifier = modifier) {
document = htmlDocument, HtmlDocument(
modifier = Modifier, document = htmlDocument,
onTextClicked = onTextClicked, modifier = Modifier,
onTextLongClicked = onTextLongClicked, onTextClicked = onTextClicked,
interactionSource = interactionSource onTextLongClicked = onTextLongClicked,
) interactionSource = interactionSource
Spacer(Modifier.height(16.dp)) )
} Spacer(Modifier.height(16.dp))
} else { }
Box(modifier) { } else {
val textWithPadding = remember(content.body) { Box(modifier) {
content.body + extraPadding.getStr(16.sp).toAnnotatedString() val textWithPadding = remember(content.body) {
content.body + extraPadding.getStr(16.sp).toAnnotatedString()
}
ClickableLinkText(
text = textWithPadding,
onClick = onTextClicked,
onLongClick = onTextLongClicked,
interactionSource = interactionSource
)
} }
ClickableLinkText(
text = textWithPadding,
onClick = onTextClicked,
onLongClick = onTextLongClicked,
interactionSource = interactionSource
)
} }
} }
} }

View file

@ -24,7 +24,6 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -79,7 +78,7 @@ fun ClickableLinkText(
@Composable @Composable
fun ClickableLinkText( fun ClickableLinkText(
annotatedString: AnnotatedString, annotatedString: AnnotatedString,
interactionSource: MutableInteractionSource, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
linkify: Boolean = true, linkify: Boolean = true,
linkAnnotationTag: String = LINK_TAG, linkAnnotationTag: String = LINK_TAG,
@ -136,7 +135,6 @@ fun ClickableLinkText(
layoutResult.value = it layoutResult.value = it
}, },
inlineContent = inlineContent, inlineContent = inlineContent,
color = MaterialTheme.colorScheme.primary,
) )
} }

View file

@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Share
import androidx.compose.material.icons.outlined.Share import androidx.compose.material.icons.outlined.Share
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.LocalTextStyle
@ -30,9 +29,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ExperimentalTextApi
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.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.components.ClickableLinkText
import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.PreviewGroup
@ -103,17 +104,21 @@ fun ListSupportingText(
* @param modifier The modifier to be applied to the text. * @param modifier The modifier to be applied to the text.
* @param contentPadding The padding to apply to the text. Default is [ListSupportingTextDefaults.Padding.Default]. * @param contentPadding The padding to apply to the text. Default is [ListSupportingTextDefaults.Padding.Default].
*/ */
@OptIn(ExperimentalTextApi::class)
@Composable @Composable
fun ListSupportingText( fun ListSupportingText(
annotatedString: AnnotatedString, annotatedString: AnnotatedString,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
contentPadding: ListSupportingTextDefaults.Padding = ListSupportingTextDefaults.Padding.Default, contentPadding: ListSupportingTextDefaults.Padding = ListSupportingTextDefaults.Padding.Default,
) { ) {
Text( val style = ElementTheme.typography.fontBodySmRegular
text = annotatedString, .copy(color = ElementTheme.colors.textSecondary)
modifier = modifier.padding(contentPadding.paddingValues()), val paddedModifier = modifier.padding(contentPadding.paddingValues())
style = ElementTheme.typography.fontBodySmRegular, ClickableLinkText(
color = ElementTheme.colors.textSecondary, annotatedString = annotatedString,
modifier = paddedModifier,
style = style,
linkify = false,
) )
} }