diff --git a/app/src/main/java/dev/lonami/talaria/ui/screens/ChatScreen.kt b/app/src/main/java/dev/lonami/talaria/ui/screens/ChatScreen.kt index fef1bbb..ec34376 100644 --- a/app/src/main/java/dev/lonami/talaria/ui/screens/ChatScreen.kt +++ b/app/src/main/java/dev/lonami/talaria/ui/screens/ChatScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.Button @@ -12,9 +13,15 @@ import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.runtime.* import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel @@ -23,7 +30,62 @@ import dev.lonami.talaria.data.MockMessageRepository import dev.lonami.talaria.ui.state.ChatViewModel import dev.lonami.talaria.ui.theme.TalariaTheme import kotlinx.coroutines.launch +import uniffi.talaria.Formatting import uniffi.talaria.Message +import uniffi.talaria.TextFormat + +@Composable +fun FormattedText( + text: String, + formatting: List, + onFormatClicked: (TextFormat) -> Unit, +) { + val anno = AnnotatedString(text, spanStyles = formatting.map { + AnnotatedString.Range(SpanStyle( + fontWeight = when (it.format) { + Formatting.BOLD -> FontWeight.Bold + else -> FontWeight.Normal + }, + fontStyle = when (it.format) { + Formatting.ITALIC -> FontStyle.Italic + else -> FontStyle.Normal + }, + fontFamily = when (it.format) { + Formatting.CODE, + Formatting.PRE, + -> FontFamily.Monospace + else -> FontFamily.Default + }, + textDecoration = when (it.format) { + Formatting.UNDERLINE -> TextDecoration.Underline + Formatting.STRIKE -> TextDecoration.LineThrough + else -> TextDecoration.None + }, + color = when (it.format) { + Formatting.MENTION, + Formatting.HASH_TAG, + Formatting.BOT_COMMAND, + Formatting.URL, + Formatting.EMAIL, + Formatting.TEXT_URL, + Formatting.MENTION_NAME, + Formatting.PHONE, + Formatting.CASH_TAG, + -> Color(0xff0000ff) + else -> Color.Black + }), it.offset, it.offset + it.length) + }) + ClickableText( + anno, + onClick = { offset -> + anno.spanStyles.indexOfFirst { + it.start <= offset && offset <= it.end + }.takeIf { it != -1 }?.also { + onFormatClicked(formatting[it]) + } + } + ) +} @Composable fun MessageCard(message: Message, modifier: Modifier = Modifier) { @@ -39,7 +101,7 @@ fun MessageCard(message: Message, modifier: Modifier = Modifier) { .padding(8.dp) ) { Text(message.sender, fontWeight = FontWeight.Bold) - Text(message.text) + FormattedText(message.text, message.formatting, onFormatClicked = {}) } } }