From 0dbd58d8d7aea796d541de96f9edb3c5f6be5174 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 12 Mar 2024 17:51:27 -0400 Subject: [PATCH] Fixing some of the old display name structure --- .../com/vitorpamplona/amethyst/model/User.kt | 15 +-- .../service/NostrSingleUserDataSource.kt | 6 +- .../amethyst/ui/actions/NewPostView.kt | 4 +- .../ui/actions/NewUserMetadataViewModel.kt | 4 +- .../amethyst/ui/components/ClickableRoute.kt | 29 ++--- .../amethyst/ui/components/RichTextViewer.kt | 8 +- .../ui/navigation/AccountSwitchBottomSheet.kt | 45 +++---- .../amethyst/ui/navigation/DrawerContent.kt | 2 +- .../ui/note/ChatroomMessageCompose.kt | 52 ++++---- .../amethyst/ui/note/ReplyInformation.kt | 117 +----------------- .../amethyst/ui/note/UserProfilePicture.kt | 2 +- .../amethyst/ui/note/UsernameDisplay.kt | 4 +- .../amethyst/ui/note/elements/ForkInfo.kt | 6 +- .../amethyst/ui/note/types/Highlight.kt | 2 +- .../amethyst/ui/qrcode/ShowQRDialog.kt | 2 +- .../amethyst/ui/screen/ThreadFeedView.kt | 2 +- .../quartz/events/ContactListEvent.kt | 8 +- 17 files changed, 91 insertions(+), 217 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt index 68aee2203..4b16bcdc5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt @@ -81,7 +81,7 @@ class User(val pubkeyHex: String) { override fun toString(): String = pubkeyHex fun toBestShortFirstName(): String { - val fullName = bestDisplayName() ?: bestUsername() ?: return pubkeyDisplayHex() + val fullName = toBestDisplayName() val names = fullName.split(' ') @@ -97,23 +97,14 @@ class User(val pubkeyHex: String) { } fun toBestDisplayName(): String { - return bestDisplayName() ?: bestUsername() ?: pubkeyDisplayHex() - } - - fun bestUsername(): String? { - return info?.name?.ifBlank { null } ?: info?.username?.ifBlank { null } - } - - fun bestDisplayName(): String? { - return info?.displayName?.ifBlank { null } + return info?.bestName() ?: pubkeyDisplayHex() } fun nip05(): String? { - return info?.nip05?.ifBlank { null } + return info?.nip05 } fun profilePicture(): String? { - if (info?.picture.isNullOrBlank()) info?.picture = null return info?.picture } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt index 472be2ace..65bd6032b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt @@ -35,7 +35,7 @@ object NostrSingleUserDataSource : NostrDataSource("SingleUserFeed") { fun createUserMetadataFilter(): List? { if (usersToWatch.isEmpty()) return null - val firstTimers = usersToWatch.filter { it.info?.latestMetadata == null }.map { it.pubkeyHex } + val firstTimers = usersToWatch.filter { it.latestMetadata == null }.map { it.pubkeyHex } if (firstTimers.isEmpty()) return null @@ -54,7 +54,7 @@ object NostrSingleUserDataSource : NostrDataSource("SingleUserFeed") { fun createUserMetadataStatusReportFilter(): List? { if (usersToWatch.isEmpty()) return null - val secondTimers = usersToWatch.filter { it.info?.latestMetadata != null } + val secondTimers = usersToWatch.filter { it.latestMetadata != null } if (secondTimers.isEmpty()) return null @@ -91,7 +91,7 @@ object NostrSingleUserDataSource : NostrDataSource("SingleUserFeed") { checkNotInMainThread() usersToWatch.forEach { - if (it.info?.latestMetadata != null) { + if (it.latestMetadata != null) { val eose = it.latestEOSEs[relayUrl] if (eose == null) { it.latestEOSEs = it.latestEOSEs + Pair(relayUrl, EOSETime(time)) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt index 8b5568654..0e81b6340 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt @@ -168,7 +168,6 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.replyModifier import com.vitorpamplona.amethyst.ui.theme.subtleBorder import com.vitorpamplona.quartz.events.ClassifiedsEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CancellationException @@ -1256,8 +1255,7 @@ fun Notifying( mentions.forEachIndexed { idx, user -> val innerUserState by user.live().metadata.observeAsState() innerUserState?.user?.let { myUser -> - val tags = - remember(innerUserState) { myUser.info?.latestMetadata?.tags?.toImmutableListOfLists() } + val tags = myUser.info?.tags Button( shape = ButtonBorder, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt index d0af1b125..02dc193f1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataViewModel.kt @@ -68,7 +68,7 @@ class NewUserMetadataViewModel : ViewModel() { account.userProfile().let { // userName.value = it.bestUsername() ?: "" - displayName.value = it.bestDisplayName() ?: "" + displayName.value = it.info?.bestName() ?: "" about.value = it.info?.about ?: "" picture.value = it.info?.picture ?: "" banner.value = it.info?.banner ?: "" @@ -82,7 +82,7 @@ class NewUserMetadataViewModel : ViewModel() { mastodon.value = "" // TODO: Validate Telegram input, somehow. - it.info?.latestMetadata?.identityClaims()?.forEach { + it.latestMetadata?.identityClaims()?.forEach { when (it) { is TwitterIdentity -> twitter.value = it.toProofUrl() is GitHubIdentity -> github.value = it.toProofUrl() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt index 4659778df..466dafdb1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt @@ -65,10 +65,10 @@ import com.vitorpamplona.quartz.encoders.HexKey import com.vitorpamplona.quartz.encoders.Nip19Bech32 import com.vitorpamplona.quartz.encoders.Nip30CustomEmoji import com.vitorpamplona.quartz.events.ChannelCreateEvent +import com.vitorpamplona.quartz.events.EmptyTagList import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.ImmutableListOfLists import com.vitorpamplona.quartz.events.PrivateDmEvent -import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap @@ -286,25 +286,16 @@ private fun RenderUserAsClickableText( additionalChars: String, nav: (String) -> Unit, ) { - val userState by baseUser.live().metadata.observeAsState() - val route = remember { "User/${baseUser.pubkeyHex}" } + val userState by baseUser.live().userMetadataInfo.observeAsState() - val userDisplayName by - remember(userState) { derivedStateOf { userState?.user?.toBestDisplayName() } } - - val userTags by - remember(userState) { - derivedStateOf { userState?.user?.info?.latestMetadata?.tags?.toImmutableListOfLists() } - } - - userDisplayName?.let { + userState?.bestName()?.let { CreateClickableTextWithEmoji( clickablePart = it, suffix = additionalChars.ifBlank { null }, maxLines = 1, - route = route, + route = "User/${baseUser.pubkeyHex}", nav = nav, - tags = userTags, + tags = userState?.tags ?: EmptyTagList, ) } } @@ -661,7 +652,10 @@ fun ClickableInLineIconRenderer( AsyncImage( model = value.url, contentDescription = null, - modifier = Modifier.fillMaxSize().padding(1.dp), + modifier = + Modifier + .fillMaxSize() + .padding(1.dp), ) }, ) @@ -743,7 +737,10 @@ fun InLineIconRenderer( AsyncImage( model = value.url, contentDescription = null, - modifier = Modifier.fillMaxSize().padding(horizontal = 0.dp), + modifier = + Modifier + .fillMaxSize() + .padding(horizontal = 0.dp), ) }, ) 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 16f6344df..a754f2226 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 @@ -858,18 +858,14 @@ private fun DisplayUserFromTag( baseUser: User, nav: (String) -> Unit, ) { - val route = remember { "User/${baseUser.pubkeyHex}" } - val hex = remember { baseUser.pubkeyDisplayHex() } - val meta by baseUser.live().userMetadataInfo.observeAsState(baseUser.info) Crossfade(targetState = meta, label = "DisplayUserFromTag") { Row { - val displayName = remember(it) { it?.bestDisplayName() ?: it?.bestUsername() ?: hex } CreateClickableTextWithEmoji( - clickablePart = displayName, + clickablePart = remember(meta) { it?.bestName() ?: baseUser.pubkeyDisplayHex() }, maxLines = 1, - route = route, + route = "User/${baseUser.pubkeyHex}", nav = nav, tags = it?.tags, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt index e7f17c92a..4114a8209 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AccountSwitchBottomSheet.kt @@ -61,7 +61,6 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties -import androidx.lifecycle.map import com.vitorpamplona.amethyst.AccountInfo import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.R @@ -78,7 +77,6 @@ import com.vitorpamplona.amethyst.ui.theme.AccountPictureModifier import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.quartz.encoders.decodePublicKeyAsHexOrNull -import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -95,7 +93,10 @@ fun AccountSwitchBottomSheet( Column(modifier = Modifier.verticalScroll(scrollState)) { Row( - modifier = Modifier.fillMaxWidth().padding(Size10dp), + modifier = + Modifier + .fillMaxWidth() + .padding(Size10dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, ) { @@ -103,7 +104,10 @@ fun AccountSwitchBottomSheet( } accounts.forEach { acc -> DisplayAccount(acc, accountViewModel, accountStateViewModel) } Row( - modifier = Modifier.fillMaxWidth().padding(top = Size10dp, bottom = Size55dp), + modifier = + Modifier + .fillMaxWidth() + .padding(top = Size10dp, bottom = Size55dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, ) { @@ -167,7 +171,8 @@ fun DisplayAccount( baseUser?.let { Row( modifier = - Modifier.fillMaxWidth() + Modifier + .fillMaxWidth() .clickable { accountStateViewModel.switchUser(acc) } .padding(16.dp, 16.dp), verticalAlignment = Alignment.CenterVertically, @@ -181,7 +186,10 @@ fun DisplayAccount( verticalAlignment = Alignment.CenterVertically, ) { Box( - modifier = Modifier.width(55.dp).padding(0.dp), + modifier = + Modifier + .width(55.dp) + .padding(0.dp), ) { val automaticallyShowProfilePicture = remember { @@ -241,22 +249,17 @@ private fun AccountName( acc: AccountInfo, user: User, ) { - val displayName by user.live().metadata.map { user.bestDisplayName() }.observeAsState() + val info by user.live().userMetadataInfo.observeAsState() - val tags by - user - .live() - .metadata - .map { user.info?.latestMetadata?.tags?.toImmutableListOfLists() } - .observeAsState() - - displayName?.let { - CreateTextWithEmoji( - text = it, - tags = tags, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) + info?.let { + it.bestName()?.let { name -> + CreateTextWithEmoji( + text = name, + tags = it.tags, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } } Text( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt index fb24a1803..eb39e7313 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt @@ -189,7 +189,7 @@ fun ProfileContent( profilePubHex = baseAccountUser.pubkeyHex, profileBanner = userInfo?.banner, profilePicture = userInfo?.profilePicture(), - bestDisplayName = userInfo?.bestDisplayName(), + bestDisplayName = userInfo?.bestName(), tags = userInfo?.tags, modifier = modifier, accountViewModel = accountViewModel, 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 f0224d6ef..8ea57ab90 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 @@ -374,11 +374,13 @@ private fun RenderBubble( val bubbleModifier = remember { - Modifier.padding(start = 10.dp, end = 5.dp, bottom = 5.dp).onSizeChanged { - if (bubbleSize.intValue != it.width) { - bubbleSize.intValue = it.width + Modifier + .padding(start = 10.dp, end = 5.dp, bottom = 5.dp) + .onSizeChanged { + if (bubbleSize.intValue != it.width) { + bubbleSize.intValue = it.width + } } - } } Column(modifier = bubbleModifier) { @@ -555,7 +557,8 @@ private fun ConstrainedStatusRow( horizontalArrangement = Arrangement.SpaceBetween, modifier = with(LocalDensity.current) { - Modifier.padding(top = Size5dp) + Modifier + .padding(top = Size5dp) .height(Size20dp) .widthIn( bubbleSize.value.toDp(), @@ -589,7 +592,10 @@ fun IncognitoBadge(baseNote: Note) { Icon( painter = painterResource(id = R.drawable.incognito), null, - modifier = Modifier.padding(top = 1.dp).size(14.dp), + modifier = + Modifier + .padding(top = 1.dp) + .size(14.dp), tint = MaterialTheme.colorScheme.placeholderText, ) Spacer(modifier = StdHorzSpacer) @@ -597,7 +603,10 @@ fun IncognitoBadge(baseNote: Note) { Icon( painter = painterResource(id = R.drawable.incognito_off), null, - modifier = Modifier.padding(top = 1.dp).size(14.dp), + modifier = + Modifier + .padding(top = 1.dp) + .size(14.dp), tint = MaterialTheme.colorScheme.placeholderText, ) Spacer(modifier = StdHorzSpacer) @@ -678,7 +687,7 @@ private fun RenderChangeChannelMetadataNote(note: Note) { CreateTextWithEmoji( text = text, - tags = remember { note.author?.info?.latestMetadata?.tags?.toImmutableListOfLists() }, + tags = note.author?.info?.tags, ) } @@ -699,7 +708,7 @@ private fun RenderCreateChannelNote(note: Note) { CreateTextWithEmoji( text = text, - tags = remember { note.author?.info?.latestMetadata?.tags?.toImmutableListOfLists() }, + tags = note.author?.info?.tags, ) } @@ -735,25 +744,17 @@ private fun WatchAndDisplayUser( loadProfilePicture: Boolean, nav: (String) -> Unit, ) { - val pubkeyHex = remember { author.pubkeyHex } - val route = remember { "User/${author.pubkeyHex}" } + val route = "User/${author.pubkeyHex}" - val userState by author.live().metadata.observeAsState() + val userState by author.live().userMetadataInfo.observeAsState() - val userDisplayName by - remember(userState) { derivedStateOf { userState?.user?.toBestDisplayName() } } + UserIcon(author.pubkeyHex, userState?.picture, loadProfilePicture, nav, route) - val userProfilePicture by - remember(userState) { derivedStateOf { userState?.user?.profilePicture() } } - - val userTags by - remember(userState) { - derivedStateOf { userState?.user?.info?.latestMetadata?.tags?.toImmutableListOfLists() } + userState?.let { + it.bestName()?.let { name -> + DisplayMessageUsername(name, it.tags, route, nav) } - - UserIcon(pubkeyHex, userProfilePicture, loadProfilePicture, nav, route) - - userDisplayName?.let { DisplayMessageUsername(it, userTags, route, nav) } + } } @Composable @@ -771,7 +772,8 @@ private fun UserIcon( loadProfilePicture = loadProfilePicture, modifier = remember { - Modifier.width(Size25dp) + Modifier + .width(Size25dp) .height(Size25dp) .clip(shape = CircleShape) .clickable(onClick = { nav(route) }) 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 2be4a0770..fce63082d 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 @@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.note import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.text.ClickableText import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -35,10 +34,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji @@ -46,112 +43,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.lessImportantLink import com.vitorpamplona.amethyst.ui.theme.placeholderText -import com.vitorpamplona.quartz.events.toImmutableListOfLists import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -@Composable -fun ReplyInformation( - replyTo: ImmutableList?, - mentions: ImmutableList, - accountViewModel: AccountViewModel, - nav: (String) -> Unit, -) { - var sortedMentions by remember { mutableStateOf?>(null) } - - LaunchedEffect(Unit) { - launch(Dispatchers.IO) { - sortedMentions = - mentions - .mapNotNull { LocalCache.checkGetOrCreateUser(it) } - .toSet() - .sortedBy { !accountViewModel.account.userProfile().isFollowingCached(it) } - .toImmutableList() - } - } - - if (sortedMentions != null) { - ReplyInformation(replyTo, sortedMentions) { nav("User/${it.pubkeyHex}") } - } -} - -@OptIn(ExperimentalLayoutApi::class) -@Composable -private fun ReplyInformation( - replyTo: ImmutableList?, - sortedMentions: ImmutableList?, - prefix: String = "", - onUserTagClick: (User) -> Unit, -) { - var expanded by remember { mutableStateOf((sortedMentions?.size ?: 0) <= 2) } - - FlowRow { - if (sortedMentions != null && sortedMentions.isNotEmpty()) { - if (replyTo != null && replyTo.isNotEmpty()) { - val repliesToDisplay = if (expanded) sortedMentions else sortedMentions.take(2) - - Text( - stringResource(R.string.replying_to), - fontSize = 13.sp, - color = MaterialTheme.colorScheme.placeholderText, - ) - - repliesToDisplay.forEachIndexed { idx, user -> - ReplyInfoMention(user, prefix, onUserTagClick) - - if (expanded) { - if (idx < repliesToDisplay.size - 2) { - Text( - ", ", - fontSize = 13.sp, - color = MaterialTheme.colorScheme.placeholderText, - ) - } else if (idx < repliesToDisplay.size - 1) { - Text( - stringResource(R.string.and), - fontSize = 13.sp, - color = MaterialTheme.colorScheme.placeholderText, - ) - } - } else { - if (idx < repliesToDisplay.size - 1) { - Text( - ", ", - fontSize = 13.sp, - color = MaterialTheme.colorScheme.placeholderText, - ) - } else if (idx < repliesToDisplay.size) { - Text( - stringResource(R.string.and), - fontSize = 13.sp, - color = MaterialTheme.colorScheme.placeholderText, - ) - - ClickableText( - AnnotatedString("${sortedMentions.size - 2}"), - style = - LocalTextStyle.current.copy( - color = MaterialTheme.colorScheme.lessImportantLink, - fontSize = 13.sp, - ), - onClick = { expanded = true }, - ) - - Text( - " ${stringResource(R.string.others)}", - fontSize = 13.sp, - color = MaterialTheme.colorScheme.placeholderText, - ) - } - } - } - } - } - } -} @Composable fun ReplyInformationChannel( @@ -225,15 +118,11 @@ private fun ReplyInfoMention( prefix: String, onUserTagClick: (User) -> Unit, ) { - val innerUserState by user.live().metadata.observeAsState() + val innerUserState by user.live().userMetadataInfo.observeAsState() CreateClickableTextWithEmoji( - clickablePart = - remember(innerUserState) { "$prefix${innerUserState?.user?.toBestDisplayName()}" }, - tags = - remember(innerUserState) { - innerUserState?.user?.info?.latestMetadata?.tags?.toImmutableListOfLists() - }, + clickablePart = "$prefix${innerUserState?.bestName()}", + tags = innerUserState?.tags, style = LocalTextStyle.current.copy( color = MaterialTheme.colorScheme.lessImportantLink, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index 85f70a93d..852bcc256 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -336,7 +336,7 @@ fun LoadUserProfilePicture( ) { val userProfile by baseUser.live().userMetadataInfo.observeAsState(baseUser.info) - innerContent(userProfile?.profilePicture(), userProfile?.bestDisplayName() ?: userProfile?.bestDisplayName()) + innerContent(userProfile?.profilePicture(), userProfile?.bestName()) } @Composable diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt index ae83ca0a9..10d018bc9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt @@ -70,9 +70,9 @@ fun UsernameDisplay( val userMetadata by baseUser.live().userMetadataInfo.observeAsState(baseUser.info) Crossfade(targetState = userMetadata, modifier = weight, label = "UsernameDisplay") { - val name = it?.bestDisplayName() ?: it?.bestUsername() + val name = it?.bestName() if (name != null) { - UserDisplay(name, it?.tags, weight, showPlayButton, fontWeight, textColor) + UserDisplay(name, it.tags, weight, showPlayButton, fontWeight, textColor) } else { NPubDisplay(baseUser, weight, fontWeight, textColor) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt index 83d60539f..dd536c4f9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt @@ -132,18 +132,20 @@ fun ForkInformationRow( ) { val noteState by originalVersion.live().metadata.observeAsState() val note = noteState?.note ?: return - val author = note.author ?: return val route = remember(note) { routeFor(note, accountViewModel.userProfile()) } if (route != null) { Row(modifier) { + val author = note.author ?: return + val meta by author.live().userMetadataInfo.observeAsState(author.info) + Text(stringResource(id = R.string.forked_from)) Spacer(modifier = StdHorzSpacer) val userMetadata by author.live().userMetadataInfo.observeAsState() CreateClickableTextWithEmoji( - clickablePart = userMetadata?.bestDisplayName() ?: userMetadata?.bestUsername() ?: author.pubkeyDisplayHex(), + clickablePart = remember(meta) { meta?.bestName() ?: author.pubkeyDisplayHex() }, maxLines = 1, route = route, nav = nav, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt index db227ced8..3c6f83281 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt @@ -144,7 +144,7 @@ private fun DisplayQuoteAuthor( val userMetadata by userBase.live().userMetadataInfo.observeAsState() CreateClickableTextWithEmoji( - clickablePart = userMetadata?.bestDisplayName() ?: userMetadata?.bestUsername() ?: userBase.pubkeyDisplayHex(), + clickablePart = userMetadata?.bestName() ?: userBase.pubkeyDisplayHex(), maxLines = 1, route = "User/${userBase.pubkeyHex}", nav = nav, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt index 3b47c5edc..37a408aa8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/qrcode/ShowQRDialog.kt @@ -133,7 +133,7 @@ fun ShowQRDialog( modifier = Modifier.fillMaxWidth().padding(top = 5.dp), ) { CreateTextWithEmoji( - text = user.bestDisplayName() ?: user.bestUsername() ?: "", + text = user.info?.bestName() ?: "", tags = user.info?.tags, fontWeight = FontWeight.Bold, fontSize = 18.sp, 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 0f9b5f595..f22263a33 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 @@ -757,7 +757,7 @@ private fun RenderClassifiedsReaderForThread( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { - val sellerName = note.author?.bestDisplayName() ?: note.author?.bestUsername() + val sellerName = note.author?.info?.bestName() val msg = if (sellerName != null) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt index a7ed88b62..f2fd835d8 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ContactListEvent.kt @@ -431,12 +431,8 @@ class UserMetadata { return lud16 ?: lud06 } - fun bestUsername(): String? { - return name ?: username - } - - fun bestDisplayName(): String? { - return displayName + fun bestName(): String? { + return displayName ?: name ?: username } fun nip05(): String? {