From 24e2a571999af56f7b4a612867912c088a98fa88 Mon Sep 17 00:00:00 2001 From: Suhas Dissanayake Date: Sun, 29 Oct 2023 15:46:47 +0530 Subject: [PATCH] feat: highlight links/email/phone in sms threads --- .../java/com/bnyro/contacts/db/obj/SmsData.kt | 80 ++++++++++++++++++- .../contacts/ui/screens/SmsThreadScreen.kt | 21 ++++- .../bnyro/contacts/util/TextFormatUtils.kt | 17 ++++ 3 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/com/bnyro/contacts/util/TextFormatUtils.kt diff --git a/app/src/main/java/com/bnyro/contacts/db/obj/SmsData.kt b/app/src/main/java/com/bnyro/contacts/db/obj/SmsData.kt index cd92d98d..640c7baf 100644 --- a/app/src/main/java/com/bnyro/contacts/db/obj/SmsData.kt +++ b/app/src/main/java/com/bnyro/contacts/db/obj/SmsData.kt @@ -1,8 +1,15 @@ package com.bnyro.contacts.db.obj +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.style.TextDecoration import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey +import com.bnyro.contacts.util.Format +import com.bnyro.contacts.util.addKeywords @Entity(tableName = "localSms") data class SmsData( @@ -12,4 +19,75 @@ data class SmsData( @ColumnInfo val timestamp: Long = 0, @ColumnInfo val threadId: Long = 0, @ColumnInfo val type: Int = 0 -) +) { + val formatted: AnnotatedString + get() { + val text = body + val keywords = mutableListOf>().apply { + addKeywords( + text, + linkRegex, + Format.LINK + ) + addKeywords( + text, + emailRegex, + Format.EMAIL + ) + addKeywords( + text, + phoneRegex, + Format.PHONE + ) + } + + return buildAnnotatedString { + append(text) + keywords.forEach { kw -> + val (format, keyword) = kw + val indexOf = text.indexOf(keyword) + addStyle( + style = SpanStyle( + color = Color.Blue, + textDecoration = when (format) { + Format.LINK -> TextDecoration.Underline + else -> TextDecoration.None + } + ), + start = indexOf, + end = indexOf + keyword.length + ) + val link = when (format) { + Format.LINK -> if (keyword.startsWith("http")) { + keyword + } else { + "http://$keyword" + } + + Format.PHONE -> + "tel:$keyword" + + Format.EMAIL -> "mailto:$keyword" + } + addStringAnnotation( + tag = format.name, + annotation = link, + start = indexOf, + end = indexOf + keyword.length + ) + } + } + } + + companion object { + private val linkRegex = Regex( + "(? + val annotation = + smsData.formatted.getStringAnnotations( + offset, + offset + ).firstOrNull() + annotation?.let { + uriHandler.openUri(it.item) + } + } + ) + } Spacer(modifier = Modifier.height(4.dp)) Text( modifier = Modifier.align(messageAlignment), diff --git a/app/src/main/java/com/bnyro/contacts/util/TextFormatUtils.kt b/app/src/main/java/com/bnyro/contacts/util/TextFormatUtils.kt new file mode 100644 index 00000000..77fbe618 --- /dev/null +++ b/app/src/main/java/com/bnyro/contacts/util/TextFormatUtils.kt @@ -0,0 +1,17 @@ +package com.bnyro.contacts.util + +enum class Format { + LINK, EMAIL, PHONE +} + +fun MutableList>.addKeywords( + text: String, + regex: Regex, + format: Format +) { + var results: MatchResult? = regex.find(text) + while (results != null) { + this.add(format to results.groupValues[1]) + results = results.next() + } +}