use annotated string in tv
This commit is contained in:
@@ -7,7 +7,7 @@ plugins {
|
|||||||
alias(libs.plugins.convention.ktor.client)
|
alias(libs.plugins.convention.ktor.client)
|
||||||
}
|
}
|
||||||
|
|
||||||
val appVersion = "1.25.3"
|
val appVersion = "1.25.4"
|
||||||
|
|
||||||
android {
|
android {
|
||||||
buildFeatures { buildConfig = true }
|
buildFeatures { buildConfig = true }
|
||||||
|
|||||||
+25
-20
@@ -235,25 +235,24 @@ private fun MessageBubble(
|
|||||||
val focusedColor = MaterialTheme.colorScheme.error
|
val focusedColor = MaterialTheme.colorScheme.error
|
||||||
val isTv = isTv()
|
val isTv = isTv()
|
||||||
val annotatedString = remember(tokens) {
|
val annotatedString = remember(tokens) {
|
||||||
if (isTv) {
|
buildText(isTv, tokens, primaryColor, focusedColor, onClickLink)
|
||||||
buildAnnotatedString { append(message.content) }
|
|
||||||
} else {
|
|
||||||
buildText(tokens, primaryColor, focusedColor, onClickLink)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
val itemFocusRequester = remember { FocusRequester() }
|
||||||
var dialog by remember { mutableStateOf(false) }
|
var dialog by remember { mutableStateOf(false) }
|
||||||
var boxModifier = Modifier.widthIn(max = 280.dp)
|
var boxModifier = Modifier.widthIn(max = 280.dp)
|
||||||
if (isTv) {
|
if (isTv) {
|
||||||
boxModifier = boxModifier.focusBorder(false).onKeyEvent {
|
boxModifier = boxModifier.focusRequester(itemFocusRequester)
|
||||||
if (it.type == KeyEventType.KeyDown) {
|
.focusBorder(false)
|
||||||
when (it.key) {
|
.onKeyEvent {
|
||||||
Key.Enter,
|
if (it.type == KeyEventType.KeyDown) {
|
||||||
Key.DirectionCenter -> dialog = true
|
when (it.key) {
|
||||||
else -> onKeyEvent(it)
|
Key.Enter,
|
||||||
|
Key.DirectionCenter -> dialog = true
|
||||||
|
else -> onKeyEvent(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@@ -275,8 +274,11 @@ private fun MessageBubble(
|
|||||||
modifier = boxModifier
|
modifier = boxModifier
|
||||||
) { ChatText(annotatedString) }
|
) { ChatText(annotatedString) }
|
||||||
}
|
}
|
||||||
if (dialog && isTv) {
|
if (dialog && isTv && !isUser) {
|
||||||
TextDialog(message.content, linkTokens, onClickLink) { dialog = false }
|
TextDialog(annotatedString, linkTokens, onClickLink) {
|
||||||
|
dialog = false
|
||||||
|
itemFocusRequester.requestFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +296,7 @@ private fun ChatText(annotatedString: AnnotatedString) {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun TextDialog(
|
private fun TextDialog(
|
||||||
text: String,
|
annotatedString: AnnotatedString,
|
||||||
links: List<TextToken.Link>,
|
links: List<TextToken.Link>,
|
||||||
onClickLink: (String) -> Unit,
|
onClickLink: (String) -> Unit,
|
||||||
dismiss: () -> Unit
|
dismiss: () -> Unit
|
||||||
@@ -306,7 +308,7 @@ private fun TextDialog(
|
|||||||
Column {
|
Column {
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
if (!showLinks) {
|
if (!showLinks) {
|
||||||
ScrollableMessage(focusRequester, text) {
|
ScrollableMessage(focusRequester, annotatedString) {
|
||||||
if (links.isNotEmpty()) {
|
if (links.isNotEmpty()) {
|
||||||
showLinks = true
|
showLinks = true
|
||||||
} else {
|
} else {
|
||||||
@@ -341,7 +343,7 @@ private fun TextDialog(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun ScrollableMessage(
|
private fun ScrollableMessage(
|
||||||
focusRequester: FocusRequester,
|
focusRequester: FocusRequester,
|
||||||
text: String,
|
annotatedString: AnnotatedString,
|
||||||
onEnter: () -> Unit
|
onEnter: () -> Unit
|
||||||
) {
|
) {
|
||||||
val scrollStep = 250f
|
val scrollStep = 250f
|
||||||
@@ -376,7 +378,7 @@ private fun ScrollableMessage(
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = text,
|
text = annotatedString,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
.verticalScroll(scrollState)
|
.verticalScroll(scrollState)
|
||||||
)
|
)
|
||||||
@@ -384,6 +386,7 @@ private fun ScrollableMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun buildText(
|
private fun buildText(
|
||||||
|
isTv: Boolean,
|
||||||
tokens: List<TextToken>,
|
tokens: List<TextToken>,
|
||||||
primaryColor: Color,
|
primaryColor: Color,
|
||||||
focusedColor: Color,
|
focusedColor: Color,
|
||||||
@@ -407,7 +410,9 @@ private fun buildText(
|
|||||||
textDecoration = TextDecoration.Underline
|
textDecoration = TextDecoration.Underline
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
linkInteractionListener = { onClickLink(token.text) }
|
linkInteractionListener = {
|
||||||
|
if (!isTv) onClickLink(token.text)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
withLink(linkAnnotation) { append(token.text) }
|
withLink(linkAnnotation) { append(token.text) }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user