Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.AnnotatedString
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.TextMeasurer
Expand Down Expand Up @@ -185,8 +186,9 @@ public fun BasicReadMoreText(
// CoreReadMoreText
// ////////////////////////////////////

private const val ReadMoreTag = "read_more"
private const val ReadLessTag = "read_less"
private const val ReadMoreTag = "readmore:read_more"
private const val ReadLessTag = "readmore:read_less"
private const val ContentsTag = "readmore:contents"

@Composable
private fun CoreReadMoreText(
Expand Down Expand Up @@ -245,41 +247,27 @@ private fun CoreReadMoreText(
val state = remember { ReadMoreState() }

val currentText = buildAnnotatedString {
if (expanded) {
append(text)
if (readLessTextWithStyle.isNotEmpty()) {
append(' ')
if (toggleArea == ToggleArea.More) {
withLink(
LinkAnnotation.Clickable(tag = ReadLessTag) {
onExpandedChange?.invoke(false)
},
) {
append(readLessTextWithStyle)
}
} else {
append(readLessTextWithStyle)
}
}
} else {
val collapsedText = state.collapsedText
if (collapsedText.isNotEmpty()) {
append(collapsedText)
append(overflowText)

if (toggleArea == ToggleArea.More) {
withLink(
LinkAnnotation.Clickable(tag = ReadMoreTag) {
onExpandedChange?.invoke(true)
},
) {
append(readMoreTextWithStyle)
}
} else {
append(readMoreTextWithStyle)
}
withContentsLink(
hasLink = onExpandedChange != null && toggleArea == ToggleArea.All
&& text.hasLinks() && state.isCollapsible,
linkInteractionListener = { onExpandedChange?.invoke(!expanded) },
) {
if (expanded) {
appendExpandedText(
text = text,
onExpandedChange = onExpandedChange,
readLessTextWithStyle = readLessTextWithStyle,
toggleArea = toggleArea,
)
} else {
append(text)
appendCollapsedText(
text = text,
collapsedText = state.collapsedText,
overflowText = overflowText,
onExpandedChange = onExpandedChange,
readMoreTextWithStyle = readMoreTextWithStyle,
toggleArea = toggleArea,
)
}
}
}
Expand Down Expand Up @@ -333,6 +321,77 @@ private fun CoreReadMoreText(
}
}

private fun AnnotatedString.Builder.appendCollapsedText(
text: AnnotatedString,
collapsedText: AnnotatedString,
overflowText: String,
onExpandedChange: ((Boolean) -> Unit)?,
readMoreTextWithStyle: AnnotatedString,
toggleArea: ToggleArea,
) {
if (collapsedText.isNotEmpty()) {
append(collapsedText)
append(overflowText)

if (toggleArea == ToggleArea.More) {
withLink(
LinkAnnotation.Clickable(tag = ReadMoreTag) {
onExpandedChange?.invoke(true)
},
) {
append(readMoreTextWithStyle)
}
} else {
append(readMoreTextWithStyle)
}
} else {
append(text)
}
}

private fun AnnotatedString.Builder.appendExpandedText(
text: AnnotatedString,
onExpandedChange: ((Boolean) -> Unit)?,
readLessTextWithStyle: AnnotatedString,
toggleArea: ToggleArea,
) {
append(text)
if (readLessTextWithStyle.isNotEmpty()) {
append(' ')
if (toggleArea == ToggleArea.More) {
withLink(
LinkAnnotation.Clickable(tag = ReadLessTag) {
onExpandedChange?.invoke(false)
},
) {
append(readLessTextWithStyle)
}
} else {
append(readLessTextWithStyle)
}
}
}

private inline fun <R : Any> AnnotatedString.Builder.withContentsLink(
hasLink: Boolean,
linkInteractionListener: LinkInteractionListener?,
block: AnnotatedString.Builder.() -> R,
): R {
return if (hasLink) {
withLink(
LinkAnnotation.Clickable(
tag = ContentsTag,
linkInteractionListener = linkInteractionListener,
),
block = block,
)
} else {
block()
}
}

private fun AnnotatedString.hasLinks() = hasLinkAnnotations(0, length)

// ////////////////////////////////////
// ReadMoreState
// ////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,9 @@ private fun Item_Hyperlink(showMessage: (String) -> Unit) {
withLink(
LinkAnnotation.Clickable(
tag = "TAG$index",
styles = TextLinkStyles(style = SpanStyle(color = Color.Blue)),
styles = TextLinkStyles(
style = SpanStyle(color = Color.Blue),
),
) {
showMessage("#TAG$index Clicked!")
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,9 @@ private fun Item_Hyperlink(showMessage: (String) -> Unit) {
withLink(
LinkAnnotation.Clickable(
tag = "TAG$index",
styles = TextLinkStyles(style = SpanStyle(color = Color.Blue)),
styles = TextLinkStyles(
style = SpanStyle(color = Color.Blue),
),
) {
showMessage("#TAG$index Clicked!")
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,9 @@ private fun Item_Hyperlink(showMessage: (String) -> Unit) {
withLink(
LinkAnnotation.Clickable(
tag = "TAG$index",
styles = TextLinkStyles(style = SpanStyle(color = Color.Blue)),
styles = TextLinkStyles(
style = SpanStyle(color = Color.Blue),
),
) {
showMessage("#TAG$index Clicked!")
},
Expand Down
1 change: 0 additions & 1 deletion sample/src/main/res/layout/item_hyperlink.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
android:layout_marginTop="5dp"
android:layout_marginEnd="18dp"
android:layout_marginBottom="18dp"
android:background="?selectableItemBackground"
android:lineSpacingExtra="4sp"
android:textColor="?colorOnSurface"
android:textSize="15sp"
Expand Down
Loading