Merge pull request #1177 from vector-im/feature/bma/analyticsSettingLink
Fix issue on analytics setting link
This commit is contained in:
commit
e67c7ac9f1
15 changed files with 125 additions and 99 deletions
1
changelog.d/1177.bugfix
Normal file
1
changelog.d/1177.bugfix
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add missing link to the terms on the analytics setting screen.
|
||||||
|
|
@ -21,5 +21,6 @@ import io.element.android.features.analytics.api.AnalyticsOptInEvents
|
||||||
data class AnalyticsPreferencesState(
|
data class AnalyticsPreferencesState(
|
||||||
val applicationName: String,
|
val applicationName: String,
|
||||||
val isEnabled: Boolean,
|
val isEnabled: Boolean,
|
||||||
|
val policyUrl: String,
|
||||||
val eventSink: (AnalyticsOptInEvents) -> Unit,
|
val eventSink: (AnalyticsOptInEvents) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,6 @@ open class AnalyticsPreferencesStateProvider : PreviewParameterProvider<Analytic
|
||||||
fun aAnalyticsPreferencesState() = AnalyticsPreferencesState(
|
fun aAnalyticsPreferencesState() = AnalyticsPreferencesState(
|
||||||
applicationName = "Element X",
|
applicationName = "Element X",
|
||||||
isEnabled = false,
|
isEnabled = false,
|
||||||
|
policyUrl = "https://element.io",
|
||||||
eventSink = {}
|
eventSink = {}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,22 +16,21 @@
|
||||||
|
|
||||||
package io.element.android.features.analytics.api.preferences
|
package io.element.android.features.analytics.api.preferences
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.SpanStyle
|
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
|
||||||
import androidx.compose.ui.text.style.TextDecoration
|
|
||||||
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.preferences.PreferenceSwitch
|
import io.element.android.libraries.designsystem.components.LINK_TAG
|
||||||
|
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.theme.LinkColor
|
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.ListSupportingText
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.Text
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -43,40 +42,33 @@ 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 supportingText = stringResource(
|
||||||
val secondPart = buildAnnotatedStringWithColoredPart(
|
id = CommonStrings.screen_analytics_settings_help_us_improve,
|
||||||
|
state.applicationName
|
||||||
|
)
|
||||||
|
val linkText = 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,
|
||||||
val subtitle = "$firstPart\n\n$secondPart"
|
|
||||||
|
|
||||||
PreferenceSwitch(
|
|
||||||
modifier = modifier,
|
|
||||||
title = stringResource(id = CommonStrings.screen_analytics_settings_share_data),
|
|
||||||
subtitle = subtitle,
|
|
||||||
isChecked = state.isEnabled,
|
|
||||||
onCheckedChange = ::onEnabledChanged,
|
|
||||||
switchAlignment = Alignment.Top,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun buildAnnotatedStringWithColoredPart(
|
|
||||||
@StringRes fullTextRes: Int,
|
|
||||||
@StringRes coloredTextRes: Int,
|
|
||||||
color: Color = LinkColor,
|
|
||||||
underline: Boolean = true,
|
|
||||||
) = buildAnnotatedString {
|
|
||||||
val coloredPart = stringResource(coloredTextRes)
|
|
||||||
val fullText = stringResource(fullTextRes, coloredPart)
|
|
||||||
val startIndex = fullText.indexOf(coloredPart)
|
|
||||||
append(fullText)
|
|
||||||
addStyle(
|
|
||||||
style = SpanStyle(
|
|
||||||
color = color,
|
|
||||||
textDecoration = if (underline) TextDecoration.Underline else null
|
|
||||||
), start = startIndex, end = startIndex + coloredPart.length
|
|
||||||
)
|
)
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
|
|
@ -91,5 +83,7 @@ internal fun AnalyticsPreferencesViewDarkPreview(@PreviewParameter(AnalyticsPref
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ContentToPreview(state: AnalyticsPreferencesState) {
|
private fun ContentToPreview(state: AnalyticsPreferencesState) {
|
||||||
AnalyticsPreferencesView(state)
|
AnalyticsPreferencesView(
|
||||||
|
state = state,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package io.element.android.features.analytics.impl
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
|
@ -28,7 +27,7 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.systemBarsPadding
|
import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.text.ClickableText
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Poll
|
import androidx.compose.material.icons.filled.Poll
|
||||||
import androidx.compose.material.icons.rounded.Check
|
import androidx.compose.material.icons.rounded.Check
|
||||||
|
|
@ -37,7 +36,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.BiasAlignment
|
import androidx.compose.ui.BiasAlignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
|
@ -45,6 +43,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.features.analytics.api.AnalyticsOptInEvents
|
import io.element.android.features.analytics.api.AnalyticsOptInEvents
|
||||||
|
import io.element.android.features.analytics.api.Config
|
||||||
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
|
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
|
||||||
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
|
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
|
||||||
import io.element.android.libraries.designsystem.atomic.molecules.InfoListItem
|
import io.element.android.libraries.designsystem.atomic.molecules.InfoListItem
|
||||||
|
|
@ -56,7 +55,6 @@ import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithSt
|
||||||
import io.element.android.libraries.designsystem.theme.components.Button
|
import io.element.android.libraries.designsystem.theme.components.Button
|
||||||
import io.element.android.libraries.designsystem.theme.components.ButtonSize
|
import io.element.android.libraries.designsystem.theme.components.ButtonSize
|
||||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||||
import io.element.android.libraries.designsystem.theme.components.Text
|
|
||||||
import io.element.android.libraries.designsystem.theme.components.TextButton
|
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||||
import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial
|
import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial
|
||||||
import io.element.android.libraries.designsystem.utils.LogCompositions
|
import io.element.android.libraries.designsystem.utils.LogCompositions
|
||||||
|
|
@ -98,6 +96,8 @@ fun AnalyticsOptInView(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const val LINK_TAG = "link"
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AnalyticsOptInHeader(
|
private fun AnalyticsOptInHeader(
|
||||||
state: AnalyticsOptInState,
|
state: AnalyticsOptInState,
|
||||||
|
|
@ -114,21 +114,29 @@ private fun AnalyticsOptInHeader(
|
||||||
subTitle = stringResource(id = R.string.screen_analytics_prompt_help_us_improve),
|
subTitle = stringResource(id = R.string.screen_analytics_prompt_help_us_improve),
|
||||||
iconImageVector = Icons.Filled.Poll
|
iconImageVector = Icons.Filled.Poll
|
||||||
)
|
)
|
||||||
Text(
|
val text = buildAnnotatedStringWithStyledPart(
|
||||||
text = buildAnnotatedStringWithStyledPart(
|
R.string.screen_analytics_prompt_read_terms,
|
||||||
R.string.screen_analytics_prompt_read_terms,
|
R.string.screen_analytics_prompt_read_terms_content_link,
|
||||||
R.string.screen_analytics_prompt_read_terms_content_link,
|
color = Color.Unspecified,
|
||||||
color = Color.Unspecified,
|
underline = false,
|
||||||
underline = false,
|
bold = true,
|
||||||
bold = true,
|
tagAndLink = LINK_TAG to Config.POLICY_LINK,
|
||||||
),
|
)
|
||||||
|
ClickableText(
|
||||||
|
text = text,
|
||||||
|
onClick = {
|
||||||
|
text
|
||||||
|
.getStringAnnotations(LINK_TAG, it, it)
|
||||||
|
.firstOrNull()
|
||||||
|
?.let { _ -> onClickTerms() }
|
||||||
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(shape = RoundedCornerShape(8.dp))
|
|
||||||
.clickable { onClickTerms() }
|
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
style = ElementTheme.typography.fontBodyMdRegular,
|
style = ElementTheme.typography.fontBodyMdRegular
|
||||||
textAlign = TextAlign.Center,
|
.copy(
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = MaterialTheme.colorScheme.secondary,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.features.analytics.api.AnalyticsOptInEvents
|
import io.element.android.features.analytics.api.AnalyticsOptInEvents
|
||||||
|
import io.element.android.features.analytics.api.Config
|
||||||
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesPresenter
|
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesPresenter
|
||||||
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesState
|
import io.element.android.features.analytics.api.preferences.AnalyticsPreferencesState
|
||||||
import io.element.android.libraries.core.meta.BuildMeta
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
|
|
@ -51,6 +52,7 @@ class DefaultAnalyticsPreferencesPresenter @Inject constructor(
|
||||||
return AnalyticsPreferencesState(
|
return AnalyticsPreferencesState(
|
||||||
applicationName = buildMeta.applicationName,
|
applicationName = buildMeta.applicationName,
|
||||||
isEnabled = isEnabled.value,
|
isEnabled = isEnabled.value,
|
||||||
|
policyUrl = Config.POLICY_LINK,
|
||||||
eventSink = ::handleEvents
|
eventSink = ::handleEvents
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ class AnalyticsPreferencesPresenterTest {
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.isEnabled).isTrue()
|
assertThat(initialState.isEnabled).isTrue()
|
||||||
|
assertThat(initialState.policyUrl).isNotEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,8 +78,8 @@ fun ClickableLinkText(
|
||||||
@Composable
|
@Composable
|
||||||
fun ClickableLinkText(
|
fun ClickableLinkText(
|
||||||
annotatedString: AnnotatedString,
|
annotatedString: AnnotatedString,
|
||||||
interactionSource: MutableInteractionSource,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
linkify: Boolean = true,
|
linkify: Boolean = true,
|
||||||
linkAnnotationTag: String = LINK_TAG,
|
linkAnnotationTag: String = LINK_TAG,
|
||||||
onClick: () -> Unit = {},
|
onClick: () -> Unit = {},
|
||||||
|
|
@ -136,7 +135,6 @@ fun ClickableLinkText(
|
||||||
layoutResult.value = it
|
layoutResult.value = it
|
||||||
},
|
},
|
||||||
inlineContent = inlineContent,
|
inlineContent = inlineContent,
|
||||||
color = MaterialTheme.colorScheme.primary,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ fun String.toAnnotatedString(): AnnotatedString = buildAnnotatedString {
|
||||||
* @param color the color to apply to the string
|
* @param color the color to apply to the string
|
||||||
* @param underline whether to underline the string
|
* @param underline whether to underline the string
|
||||||
* @param bold whether to bold the string
|
* @param bold whether to bold the string
|
||||||
|
* @param tagAndLink an optional pair of tag and link to add to the styled part of the string, as StringAnnotation
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun buildAnnotatedStringWithStyledPart(
|
fun buildAnnotatedStringWithStyledPart(
|
||||||
|
|
@ -67,6 +68,7 @@ fun buildAnnotatedStringWithStyledPart(
|
||||||
color: Color = LinkColor,
|
color: Color = LinkColor,
|
||||||
underline: Boolean = true,
|
underline: Boolean = true,
|
||||||
bold: Boolean = false,
|
bold: Boolean = false,
|
||||||
|
tagAndLink: Pair<String, String>? = null,
|
||||||
) = buildAnnotatedString {
|
) = buildAnnotatedString {
|
||||||
val coloredPart = stringResource(coloredTextRes)
|
val coloredPart = stringResource(coloredTextRes)
|
||||||
val fullText = stringResource(fullTextRes, coloredPart)
|
val fullText = stringResource(fullTextRes, coloredPart)
|
||||||
|
|
@ -81,6 +83,14 @@ fun buildAnnotatedStringWithStyledPart(
|
||||||
start = startIndex,
|
start = startIndex,
|
||||||
end = startIndex + coloredPart.length,
|
end = startIndex + coloredPart.length,
|
||||||
)
|
)
|
||||||
|
if (tagAndLink != null) {
|
||||||
|
addStringAnnotation(
|
||||||
|
tag = tagAndLink.first,
|
||||||
|
annotation = tagAndLink.second,
|
||||||
|
start = startIndex,
|
||||||
|
end = startIndex + coloredPart.length
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:a08d5ff1f91c0db7c502882815d36d6a675567ebf8c3eddc0ebff431e3592e67
|
oid sha256:b365229cac3351e4ec44979b7a22fcae090a8995e4784d9114cfd0033a242510
|
||||||
size 23390
|
size 23147
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6a5300ac57d9d0137cf82af4ed4bd86c3ab7f3a70d2560954e524b7b3c120199
|
oid sha256:5fc43706603ce52fa3495fa4e6dfa9aa684540a9dec996a5f705427d34ffb55c
|
||||||
size 23515
|
size 23274
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:4dd40c1eac2e5f33ce340ce69d8c0f502cd0912a0d511602e1122a6f4d8ae330
|
oid sha256:e22dc131e8f1f7461c050e871eaa408895529976ef7445aa6faf09852370df90
|
||||||
size 25433
|
size 25176
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:76dbcb5845565774bd33a192d02a3da0216c34b17e6e1bc1f208cabef9506617
|
oid sha256:bc234611dd3df74196467129476c69a0212a4c665f2a94797c175cbd911c2083
|
||||||
size 26630
|
size 26339
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue