diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 3b5ab68c5..ecd1471e0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -130,6 +130,12 @@ class Note(val idHex: String) { return reports.filter { it.author in users } } + fun hasAnyReports(): Boolean { + val dayAgo = Date().time / 1000 - 24*60*60 + return author?.reports?.filter { it.event?.createdAt ?: 0 > dayAgo }?.isNotEmpty() ?: false + || reports.isNotEmpty() + } + fun directlyCiteUsers(): Set { val matcher = tagSearch.matcher(event?.content ?: "") val returningList = mutableSetOf() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index 88ced0693..1ae76a907 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -64,7 +64,7 @@ fun isValidURL(url: String?): Boolean { } @Composable -fun RichTextViewer(content: String, tags: List>?, navController: NavController) { +fun RichTextViewer(content: String, blockPreview: Boolean, tags: List>?, navController: NavController) { val translatedTextState = remember { mutableStateOf(ResultOrError(content, null, null, null)) } @@ -87,34 +87,56 @@ fun RichTextViewer(content: String, tags: List>?, navController: Na FlowRow() { paragraph.split(' ').forEach { word: String -> - // Explicit URL - val lnInvoice = LnInvoiceUtil.findInvoice(word) - if (lnInvoice != null) { - InvoicePreview(lnInvoice) - } else if (isValidURL(word)) { - val removedParamsFromUrl = word.split("?")[0].toLowerCase() - if (imageExtension.matcher(removedParamsFromUrl).matches()) { - ZoomableImageView(word) - } else if (videoExtension.matcher(removedParamsFromUrl).matches()) { - VideoView(word) + + if (blockPreview) { + if (isValidURL(word)) { + ClickableUrl("$word ", word) + } else if (Patterns.EMAIL_ADDRESS.matcher(word).matches()) { + ClickableEmail(word) + } else if (Patterns.PHONE.matcher(word).matches() && word.length > 6) { + ClickablePhone(word) + } else if (noProtocolUrlValidator.matcher(word).matches()) { + ClickableUrl("https://$word", word) + } else if (tagIndex.matcher(word).matches() && tags != null) { + TagLink(word, tags, navController) + } else if (isBechLink(word)) { + BechLink(word, navController) } else { - UrlPreview(word, word) + Text( + text = "$word ", + style = LocalTextStyle.current.copy(textDirection = TextDirection.Content), + ) } - } else if (Patterns.EMAIL_ADDRESS.matcher(word).matches()) { - ClickableEmail(word) - } else if (Patterns.PHONE.matcher(word).matches() && word.length > 6) { - ClickablePhone(word) - } else if (noProtocolUrlValidator.matcher(word).matches()) { - UrlPreview("https://$word", word) - } else if (tagIndex.matcher(word).matches() && tags != null) { - TagLink(word, tags, navController) - } else if (isBechLink(word)) { - BechLink(word, navController) } else { - Text( - text = "$word ", - style = LocalTextStyle.current.copy(textDirection = TextDirection.Content), - ) + // Explicit URL + val lnInvoice = LnInvoiceUtil.findInvoice(word) + if (lnInvoice != null) { + InvoicePreview(lnInvoice) + } else if (isValidURL(word)) { + val removedParamsFromUrl = word.split("?")[0].toLowerCase() + if (imageExtension.matcher(removedParamsFromUrl).matches()) { + ZoomableImageView(word) + } else if (videoExtension.matcher(removedParamsFromUrl).matches()) { + VideoView(word) + } else { + UrlPreview(word, word) + } + } else if (Patterns.EMAIL_ADDRESS.matcher(word).matches()) { + ClickableEmail(word) + } else if (Patterns.PHONE.matcher(word).matches() && word.length > 6) { + ClickablePhone(word) + } else if (noProtocolUrlValidator.matcher(word).matches()) { + UrlPreview("https://$word", word) + } else if (tagIndex.matcher(word).matches() && tags != null) { + TagLink(word, tags, navController) + } else if (isBechLink(word)) { + BechLink(word, navController) + } else { + Text( + text = "$word ", + style = LocalTextStyle.current.copy(textDirection = TextDirection.Content), + ) + } } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt index 6c78cfa64..8c393371f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.LocalTextStyle import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface import androidx.compose.material.Text @@ -32,6 +33,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDirection import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController @@ -201,19 +203,21 @@ fun ChatroomMessageCompose(baseNote: Note, routeForLastRead: String?, innerQuote } else { val eventContent = accountViewModel.decrypt(note) - if (eventContent != null) + if (eventContent != null) { RichTextViewer( eventContent, + noteForReports.hasAnyReports(), note.event?.tags, navController ) - else + } else { RichTextViewer( "Could Not decrypt the message", + false, note.event?.tags, navController ) - + } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 7b65090f7..4a9d702eb 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -247,17 +247,7 @@ fun NoteCompose( } else { val eventContent = note.event?.content if (eventContent != null) { - if (note.reports.size > 0) { - // Doesn't load images - Row() { - Text( - text = eventContent, - style = LocalTextStyle.current.copy(textDirection = TextDirection.Content), - ) - } - } else { - RichTextViewer(eventContent, note.event?.tags, navController) - } + RichTextViewer(eventContent, noteForReports.hasAnyReports(), note.event?.tags, navController) } ReactionsRow(note, accountViewModel) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt index 2071392fd..8f83c6a8b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/ThreadFeedView.kt @@ -16,6 +16,7 @@ import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Divider +import androidx.compose.material.LocalTextStyle import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -33,6 +34,7 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.runtime.collectAsState +import androidx.compose.ui.text.style.TextDirection import androidx.navigation.NavController import coil.compose.AsyncImage import coil.compose.rememberAsyncImagePainter @@ -218,8 +220,9 @@ fun NoteMaster(baseNote: Note, accountViewModel: AccountViewModel, navController Row(modifier = Modifier.padding(horizontal = 12.dp)) { Column() { val eventContent = note.event?.content - if (eventContent != null) - RichTextViewer(eventContent, note.event?.tags, navController) + if (eventContent != null) { + RichTextViewer(eventContent, noteForReports.hasAnyReports(), note.event?.tags, navController) + } ReactionsRow(note, accountViewModel)