Skip to content

Commit

Permalink
Merge pull request #308 from SuhasDissa/main
Browse files Browse the repository at this point in the history
feat: highlight links/email/phone in sms threads
  • Loading branch information
SuhasDissa authored Oct 29, 2023
2 parents ae6f4e5 + 24e2a57 commit 07f1a58
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 3 deletions.
80 changes: 79 additions & 1 deletion app/src/main/java/com/bnyro/contacts/db/obj/SmsData.kt
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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<Pair<Format, String>>().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(
"(?<!@)(?<!\\S)((https?://)?[a-zA-Z0-9\\-]{2,}(\\.[a-zA-Z0-9]{2,})+)"
)
private val emailRegex = Regex(
"([A-Za-z0-9+_.-]+@(.+))"
)
private val phoneRegex = Regex(
"((\\+\\d{1,3}(\\s)?)?((\\(\\d{3}\\))|(\\d{3}))[-\\s]?\\d{3}[-\\s]?\\d{4})"
)
}
}
21 changes: 19 additions & 2 deletions app/src/main/java/com/bnyro/contacts/ui/screens/SmsThreadScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CardElevation
import androidx.compose.material3.DismissDirection
import androidx.compose.material3.DismissValue
import androidx.compose.material3.ElevatedCard
Expand All @@ -51,6 +52,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
Expand Down Expand Up @@ -180,7 +182,22 @@ fun SmsThreadScreen(
Column(
modifier = Modifier.padding(12.dp)
) {
Text(text = smsData.body)
SelectionContainer {
val uriHandler = LocalUriHandler.current
ClickableText(
text = smsData.formatted,
onClick = { offset ->
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),
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/java/com/bnyro/contacts/util/TextFormatUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.bnyro.contacts.util

enum class Format {
LINK, EMAIL, PHONE
}

fun MutableList<Pair<Format, String>>.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()
}
}

0 comments on commit 07f1a58

Please sign in to comment.