diff --git a/apps/vbox/client/androidApp/build.gradle.kts b/apps/vbox/client/androidApp/build.gradle.kts index b36a2e1..f4ad2d2 100644 --- a/apps/vbox/client/androidApp/build.gradle.kts +++ b/apps/vbox/client/androidApp/build.gradle.kts @@ -7,7 +7,7 @@ plugins { alias(libs.plugins.convention.ktor.client) } -val appVersion = "1.25.3" +val appVersion = "1.25.4" android { buildFeatures { buildConfig = true } diff --git a/feature/chat/chat-client/src/commonMain/kotlin/ru/shadowsparky/chat/presentation/ChatScreen.kt b/feature/chat/chat-client/src/commonMain/kotlin/ru/shadowsparky/chat/presentation/ChatScreen.kt index 4888277..06c6eff 100644 --- a/feature/chat/chat-client/src/commonMain/kotlin/ru/shadowsparky/chat/presentation/ChatScreen.kt +++ b/feature/chat/chat-client/src/commonMain/kotlin/ru/shadowsparky/chat/presentation/ChatScreen.kt @@ -235,25 +235,24 @@ private fun MessageBubble( val focusedColor = MaterialTheme.colorScheme.error val isTv = isTv() val annotatedString = remember(tokens) { - if (isTv) { - buildAnnotatedString { append(message.content) } - } else { - buildText(tokens, primaryColor, focusedColor, onClickLink) - } + buildText(isTv, tokens, primaryColor, focusedColor, onClickLink) } + val itemFocusRequester = remember { FocusRequester() } var dialog by remember { mutableStateOf(false) } var boxModifier = Modifier.widthIn(max = 280.dp) if (isTv) { - boxModifier = boxModifier.focusBorder(false).onKeyEvent { - if (it.type == KeyEventType.KeyDown) { - when (it.key) { - Key.Enter, - Key.DirectionCenter -> dialog = true - else -> onKeyEvent(it) + boxModifier = boxModifier.focusRequester(itemFocusRequester) + .focusBorder(false) + .onKeyEvent { + if (it.type == KeyEventType.KeyDown) { + when (it.key) { + Key.Enter, + Key.DirectionCenter -> dialog = true + else -> onKeyEvent(it) + } } + false } - false - } } Box( modifier = Modifier.fillMaxWidth(), @@ -275,8 +274,11 @@ private fun MessageBubble( modifier = boxModifier ) { ChatText(annotatedString) } } - if (dialog && isTv) { - TextDialog(message.content, linkTokens, onClickLink) { dialog = false } + if (dialog && isTv && !isUser) { + TextDialog(annotatedString, linkTokens, onClickLink) { + dialog = false + itemFocusRequester.requestFocus() + } } } @@ -294,7 +296,7 @@ private fun ChatText(annotatedString: AnnotatedString) { @Composable private fun TextDialog( - text: String, + annotatedString: AnnotatedString, links: List, onClickLink: (String) -> Unit, dismiss: () -> Unit @@ -306,7 +308,7 @@ private fun TextDialog( Column { val focusRequester = remember { FocusRequester() } if (!showLinks) { - ScrollableMessage(focusRequester, text) { + ScrollableMessage(focusRequester, annotatedString) { if (links.isNotEmpty()) { showLinks = true } else { @@ -341,7 +343,7 @@ private fun TextDialog( @Composable private fun ScrollableMessage( focusRequester: FocusRequester, - text: String, + annotatedString: AnnotatedString, onEnter: () -> Unit ) { val scrollStep = 250f @@ -376,7 +378,7 @@ private fun ScrollableMessage( } ) { Text( - text = text, + text = annotatedString, modifier = Modifier.fillMaxWidth() .verticalScroll(scrollState) ) @@ -384,6 +386,7 @@ private fun ScrollableMessage( } private fun buildText( + isTv: Boolean, tokens: List, primaryColor: Color, focusedColor: Color, @@ -407,7 +410,9 @@ private fun buildText( textDecoration = TextDecoration.Underline ) ), - linkInteractionListener = { onClickLink(token.text) } + linkInteractionListener = { + if (!isTv) onClickLink(token.text) + } ) withLink(linkAnnotation) { append(token.text) } }