diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt index 0be651a7dd..8accaaf8a0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/Event.kt @@ -38,6 +38,8 @@ open class Event( override fun toJson(): String = gson.toJson(this) + fun hasAnyTaggedUser() = tags.any { it.size > 1 && it[0] == "p" } + fun taggedUsers() = tags.filter { it.size > 1 && it[0] == "p" }.map { it[1] } fun taggedEvents() = tags.filter { it.size > 1 && it[0] == "e" }.map { it[1] } @@ -83,7 +85,7 @@ open class Event( override fun getReward(): BigDecimal? { return try { - tags.filter { it.firstOrNull() == "reward" }.mapNotNull { it.getOrNull(1)?.let { BigDecimal(it) } }.firstOrNull() + tags.firstOrNull { it.size > 1 && it[0] == "reward" }?.get(1)?.let { BigDecimal(it) } } catch (e: Exception) { null } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index cebfe1fdde..306b32596a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalUriHandler +import androidx.compose.ui.platform.UriHandler import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.style.TextOverflow @@ -92,64 +93,75 @@ fun ObserveDisplayNip05Status(baseUser: User, columnModifier: Modifier = Modifie val userState by baseUser.live().metadata.observeAsState() val user = userState?.user ?: return - val uri = LocalUriHandler.current - user.nip05()?.let { nip05 -> - if (nip05.split("@").size == 2) { + val parts = nip05.split("@") + if (parts.size == 2) { + val nip05Verified by nip05VerificationAsAState(user.info!!, user.pubkeyHex) + Column(modifier = columnModifier) { - Row(verticalAlignment = Alignment.CenterVertically) { - if (nip05.split("@")[0] != "_") { - Text( - text = AnnotatedString(nip05.split("@")[0]), - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - } - - val nip05Verified by nip05VerificationAsAState(user.info!!, user.pubkeyHex) - if (nip05Verified == null) { - Icon( - tint = Color.Yellow, - imageVector = Icons.Default.Downloading, - contentDescription = "Downloading", - modifier = Modifier - .size(14.dp) - .padding(top = 1.dp) - ) - } else if (nip05Verified == true) { - Icon( - painter = painterResource(R.drawable.ic_verified), - "NIP-05 Verified", - tint = Nip05.copy(0.52f), - modifier = Modifier - .size(14.dp) - .padding(top = 1.dp) - ) - } else { - Icon( - tint = Color.Red, - imageVector = Icons.Default.Report, - contentDescription = "Invalid Nip05", - modifier = Modifier - .size(14.dp) - .padding(top = 1.dp) - ) - } - - ClickableText( - text = AnnotatedString(nip05.split("@")[1]), - onClick = { nip05.let { runCatching { uri.openUri("https://${it.split("@")[1]}") } } }, - style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary.copy(0.52f)), - maxLines = 1, - overflow = TextOverflow.Visible - ) - } + DisplayNIP05(parts[0], parts[1], nip05Verified) } } } } +@Composable +private fun DisplayNIP05( + user: String, + domain: String, + nip05Verified: Boolean? +) { + val uri = LocalUriHandler.current + + Row(verticalAlignment = Alignment.CenterVertically) { + if (user != "_") { + Text( + text = AnnotatedString(user), + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + + if (nip05Verified == null) { + Icon( + tint = Color.Yellow, + imageVector = Icons.Default.Downloading, + contentDescription = "Downloading", + modifier = Modifier + .size(14.dp) + .padding(top = 1.dp) + ) + } else if (nip05Verified == true) { + Icon( + painter = painterResource(R.drawable.ic_verified), + "NIP-05 Verified", + tint = Nip05.copy(0.52f), + modifier = Modifier + .size(14.dp) + .padding(top = 1.dp) + ) + } else { + Icon( + tint = Color.Red, + imageVector = Icons.Default.Report, + contentDescription = "Invalid Nip05", + modifier = Modifier + .size(14.dp) + .padding(top = 1.dp) + ) + } + + ClickableText( + text = AnnotatedString(domain), + onClick = { runCatching { uri.openUri("https://${domain}") } }, + style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary.copy(0.52f)), + maxLines = 1, + overflow = TextOverflow.Visible + ) + } +} + @Composable fun DisplayNip05ProfileStatus(user: User) { val uri = LocalUriHandler.current 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 964045df61..9a4c1ca31f 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 @@ -225,26 +225,20 @@ fun NoteComposeInner( modifier = Modifier .padding(start = if (!isBoostedNote && !isQuotedNote) 10.dp else 0.dp) ) { - val (value, elapsed1) = measureTimedValue { - FirstUserInfoRow( - baseNote = baseNote, - showAuthorPicture = isQuotedNote, - account = account, - accountViewModel = accountViewModel, - navController = navController - ) - } - Log.d("Time", "$elapsed1 Line 1 of each post ${noteEvent.content()}") + FirstUserInfoRow( + baseNote = baseNote, + showAuthorPicture = isQuotedNote, + account = account, + accountViewModel = accountViewModel, + navController = navController + ) if (noteEvent !is RepostEvent && !makeItShort && !isQuotedNote) { - val (value, elapsed2) = measureTimedValue { - SecondUserInfoRow( - note, - account, - navController - ) - } - Log.d("Time", "$elapsed2 Line 2 of each post") + SecondUserInfoRow( + note, + account, + navController + ) } Spacer(modifier = Modifier.height(2.dp)) @@ -555,43 +549,43 @@ private fun RenderBadgeAward( var awardees by remember { mutableStateOf>(listOf()) } Text(text = stringResource(R.string.award_granted_to)) - /* - LaunchedEffect(key1 = note) { - withContext(Dispatchers.IO) { - awardees = noteEvent.awardees().mapNotNull { hex -> - LocalCache.checkGetOrCreateUser(hex) - } + + LaunchedEffect(key1 = note) { + withContext(Dispatchers.IO) { + awardees = noteEvent.awardees().mapNotNull { hex -> + LocalCache.checkGetOrCreateUser(hex) } } + } - FlowRow(modifier = Modifier.padding(top = 5.dp)) { - awardees.forEach { user -> - Row(modifier = Modifier.clickable { - navController.navigate("User/${user.pubkeyHex}") - }, - verticalAlignment = Alignment.CenterVertically - ) { - UserPicture( - baseUser = user, - baseUserAccount = accountViewModel.userProfile(), - size = 35.dp - ) - } - } - } - - note.replyTo?.firstOrNull()?.let { - NoteCompose( - it, - modifier = Modifier, - isBoostedNote = false, - isQuotedNote = true, - unPackReply = false, - parentBackgroundColor = backgroundColor, - accountViewModel = accountViewModel, - navController = navController + FlowRow(modifier = Modifier.padding(top = 5.dp)) { + awardees.forEach { user -> + Row(modifier = Modifier.clickable { + navController.navigate("User/${user.pubkeyHex}") + }, + verticalAlignment = Alignment.CenterVertically + ) { + UserPicture( + baseUser = user, + baseUserAccount = accountViewModel.userProfile(), + size = 35.dp ) - }*/ + } + } + } + + note.replyTo?.firstOrNull()?.let { + NoteCompose( + it, + modifier = Modifier, + isBoostedNote = false, + isQuotedNote = true, + unPackReply = false, + parentBackgroundColor = backgroundColor, + accountViewModel = accountViewModel, + navController = navController + ) + } ReactionsRow(note, accountViewModel, navController) @@ -704,9 +698,7 @@ private fun ReplyRow( ) { val noteEvent = note.event - if (noteEvent is TextNoteEvent && - (note.replyTo != null || noteEvent.mentions().isNotEmpty()) - ) { + if (noteEvent is TextNoteEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser())) { val replyingDirectlyTo = note.replyTo?.lastOrNull() if (replyingDirectlyTo != null && unPackReply) { NoteCompose( @@ -733,10 +725,7 @@ private fun ReplyRow( } Spacer(modifier = Modifier.height(5.dp)) - } else if ( - noteEvent is ChannelMessageEvent && - (note.replyTo != null || noteEvent.mentions().isNotEmpty()) - ) { + } else if (noteEvent is ChannelMessageEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser())) { val sortedMentions = noteEvent.mentions() .mapNotNull { LocalCache.checkGetOrCreateUser(it) } .toSet()