From bc1b71e9bfb58f99cfb0cb7f098115debce2de15 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 30 May 2023 13:58:00 -0400 Subject: [PATCH] Improves reply info rendering --- .../ui/components/ZoomableContentView.kt | 30 ++-- .../amethyst/ui/note/MultiSetCompose.kt | 6 +- .../amethyst/ui/note/NoteCompose.kt | 12 +- .../amethyst/ui/note/ReplyInformation.kt | 146 +++++++++--------- .../amethyst/ui/note/UserCompose.kt | 13 +- .../amethyst/ui/note/ZapNoteCompose.kt | 29 ++-- .../ui/screen/loggedIn/SearchScreen.kt | 13 +- 7 files changed, 123 insertions(+), 126 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index 055f31624..6c32a1d71 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt @@ -265,27 +265,27 @@ private fun UrlImageView( content: ZoomableUrlImage, mainImageModifier: Modifier ) { - val scope = rememberCoroutineScope() - val context = LocalContext.current + BoxWithConstraints(contentAlignment = Alignment.Center) { + val scope = rememberCoroutineScope() + val context = LocalContext.current - // store the dialog open or close state - var imageState by remember { - mutableStateOf(null) - } + // store the dialog open or close state + var imageState by remember { + mutableStateOf(null) + } - var verifiedHash by remember { - mutableStateOf(null) - } + var verifiedHash by remember { + mutableStateOf(null) + } - LaunchedEffect(key1 = content.url, key2 = imageState) { - if (imageState is AsyncImagePainter.State.Success) { - scope.launch(Dispatchers.IO) { - verifiedHash = verifyHash(content, context) + LaunchedEffect(key1 = content.url, key2 = imageState) { + if (imageState is AsyncImagePainter.State.Success) { + scope.launch(Dispatchers.IO) { + verifiedHash = verifyHash(content, context) + } } } - } - BoxWithConstraints(contentAlignment = Alignment.Center) { val myModifier = remember { mainImageModifier .widthIn(max = maxWidth) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index caf24b0b9..31b633c3d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -438,8 +438,10 @@ fun FastNoteAuthorPicture( accountViewModel: AccountViewModel ) { val userState by author.live().metadata.observeAsState() - val profilePicture = remember(userState) { - userState?.user?.profilePicture() + val profilePicture by remember(userState) { + derivedStateOf { + userState?.user?.profilePicture() + } } val authorPubKey = remember { 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 166dd8f28..fa572ece4 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 @@ -2171,12 +2171,16 @@ fun UserPicture( baseUser.pubkeyHex } - val userProfile = remember(userState) { - userState?.user?.profilePicture() + val userProfile by remember(userState) { + derivedStateOf { + userState?.user?.profilePicture() + } } - val showFollowingMark = remember(accountState) { - accountState?.user?.isFollowingCached(baseUser) == true || baseUser.pubkeyHex == accountState?.user?.pubkeyHex + val showFollowingMark by remember(accountState) { + derivedStateOf { + accountState?.user?.isFollowingCached(baseUser) == true || baseUser.pubkeyHex == accountState?.user?.pubkeyHex + } } // BaseUser is the same reference as accountState.user diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt index 8d30b3c4d..b0874f34c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt @@ -55,57 +55,47 @@ fun ReplyInformation(replyTo: List?, dupMentions: List?, account: Ac ) repliesToDisplay.forEachIndexed { idx, user -> - val innerUserState by user.live().metadata.observeAsState() - val innerUser = innerUserState?.user + ReplyInfoMention(user, prefix, onUserTagClick) - innerUser?.let { myUser -> - CreateClickableTextWithEmoji( - clickablePart = "$prefix@${myUser.toBestDisplayName()}", - tags = myUser.info?.latestMetadata?.tags, - style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary.copy(alpha = 0.52f), fontSize = 13.sp), - onClick = { onUserTagClick(myUser) } - ) + if (expanded) { + if (idx < repliesToDisplay.size - 2) { + Text( + ", ", + fontSize = 13.sp, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) + ) + } else if (idx < repliesToDisplay.size - 1) { + Text( + "${stringResource(R.string.and)}", + fontSize = 13.sp, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) + ) + } + } else { + if (idx < repliesToDisplay.size - 1) { + Text( + ", ", + fontSize = 13.sp, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) + ) + } else if (idx < repliesToDisplay.size) { + Text( + "${stringResource(R.string.and)}", + fontSize = 13.sp, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) + ) - if (expanded) { - if (idx < repliesToDisplay.size - 2) { - Text( - ", ", - fontSize = 13.sp, - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) - } else if (idx < repliesToDisplay.size - 1) { - Text( - "${stringResource(R.string.and)}", - fontSize = 13.sp, - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) - } - } else { - if (idx < repliesToDisplay.size - 1) { - Text( - ", ", - fontSize = 13.sp, - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) - } else if (idx < repliesToDisplay.size) { - Text( - "${stringResource(R.string.and)}", - fontSize = 13.sp, - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) + ClickableText( + AnnotatedString("${mentions.size - 2}"), + style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary.copy(alpha = 0.52f), fontSize = 13.sp), + onClick = { expanded = true } + ) - ClickableText( - AnnotatedString("${mentions.size - 2}"), - style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary.copy(alpha = 0.52f), fontSize = 13.sp), - onClick = { expanded = true } - ) - - Text( - " ${stringResource(R.string.others)}", - fontSize = 13.sp, - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) - } + Text( + " ${stringResource(R.string.others)}", + fontSize = 13.sp, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) + ) } } } @@ -190,36 +180,46 @@ fun ReplyInformationChannel( color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) ) - val mentionSet = mentions.toSet() + mentions.forEachIndexed { idx, user -> + ReplyInfoMention(user, prefix, onUserTagClick) - mentionSet.forEachIndexed { idx, user -> - val innerUserState by user.live().metadata.observeAsState() - val innerUser = innerUserState?.user - - innerUser?.let { myUser -> - CreateClickableTextWithEmoji( - clickablePart = "$prefix@${myUser.toBestDisplayName()}", - tags = myUser.info?.latestMetadata?.tags, - style = LocalTextStyle.current.copy(color = MaterialTheme.colors.primary.copy(alpha = 0.52f), fontSize = 13.sp), - onClick = { onUserTagClick(myUser) } + if (idx < mentions.size - 2) { + Text( + ", ", + fontSize = 13.sp, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) + ) + } else if (idx < mentions.size - 1) { + Text( + " ${stringResource(id = R.string.add)} ", + fontSize = 13.sp, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) ) - - if (idx < mentionSet.size - 2) { - Text( - ", ", - fontSize = 13.sp, - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) - } else if (idx < mentionSet.size - 1) { - Text( - " ${stringResource(id = R.string.add)} ", - fontSize = 13.sp, - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f) - ) - } } } } } } } + +@Composable +private fun ReplyInfoMention( + user: User, + prefix: String, + onUserTagClick: (User) -> Unit +) { + val innerUserState by user.live().metadata.observeAsState() + val innerUser = remember(innerUserState) { + innerUserState?.user + } ?: return + + CreateClickableTextWithEmoji( + clickablePart = "$prefix${innerUser.toBestDisplayName()}", + tags = innerUser.info?.latestMetadata?.tags, + style = LocalTextStyle.current.copy( + color = MaterialTheme.colors.primary.copy(alpha = 0.52f), + fontSize = 13.sp + ), + onClick = { onUserTagClick(innerUser) } + ) +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt index 5c366380f..c997c107d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt @@ -5,15 +5,12 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.material.Divider -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -60,15 +57,7 @@ fun UserCompose( UsernameDisplay(baseUser) } - val baseUserState by baseUser.live().metadata.observeAsState() - val user = baseUserState?.user ?: return - - Text( - user.info?.about ?: "", - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) + AboutDisplay(baseUser) } Column(modifier = Modifier.padding(start = 10.dp)) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt index de185a436..759b3d846 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt @@ -10,6 +10,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf @@ -25,6 +26,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.model.LnZapEvent import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.FollowButton @@ -79,15 +81,7 @@ fun ZapNoteCompose(baseNote: Pair, accountViewModel: AccountViewMode UsernameDisplay(baseAuthor) } - val baseAuthorState by baseAuthor.live().metadata.observeAsState() - val user = baseAuthorState?.user ?: return - - Text( - user.info?.about ?: "", - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) + AboutDisplay(baseAuthor) } var zapAmount by remember { mutableStateOf(null) } @@ -130,3 +124,20 @@ fun ZapNoteCompose(baseNote: Pair, accountViewModel: AccountViewMode } } } + +@Composable +fun AboutDisplay(baseAuthor: User) { + val baseAuthorState by baseAuthor.live().metadata.observeAsState() + val userAboutMe by remember(baseAuthorState) { + derivedStateOf { + baseAuthorState?.user?.info?.about ?: "" + } + } + + Text( + userAboutMe, + color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt index 2bdce2350..d1a4af6e9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt @@ -29,7 +29,6 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -42,7 +41,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver @@ -58,6 +56,7 @@ import com.vitorpamplona.amethyst.service.NostrGlobalDataSource import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource import com.vitorpamplona.amethyst.ui.components.BundledUpdate import com.vitorpamplona.amethyst.ui.dal.GlobalFeedFilter +import com.vitorpamplona.amethyst.ui.note.AboutDisplay import com.vitorpamplona.amethyst.ui.note.ChannelName import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.UserCompose @@ -418,15 +417,7 @@ fun UserLine( UsernameDisplay(baseUser) } - val userState by baseUser.live().metadata.observeAsState() - val user = userState?.user ?: return - - Text( - user.info?.about?.take(100) ?: "", - color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) + AboutDisplay(baseUser) } }