From 7dc033ec796aa2db7ed6c82cd395ad19329cf439 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Jul 2026 18:33:19 +0000 Subject: [PATCH] fix(ui): show NIP-29 group names in the picker, not their ids The read-only settings picker never fetches a group's kind-39000 metadata, so with no cached event RelayGroupChannel.toBestDisplayName() fell back to the raw group id. Resolve the label from the group's metadata name when loaded, otherwise the name the user's joined-groups list already stored for it (the NIP-51 ["group", id, relay, name] tag), and only then the id. Also helps the live bar before 39000 arrives. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_017mxdSFQcarsKaL179tSub1 --- .../bottombars/GroupBottomBarEntries.kt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt index 7b0a2a60ef..242dcf9eef 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt @@ -110,8 +110,21 @@ fun rememberRelayGroupEntryDisplay( // call structure is unconditional; a null channel just yields a null state and the id fallback. val state by observeChannelMetadataOrNull(channel, accountViewModel, subscribe) val current = (state?.channel as? RelayGroupChannel) ?: channel + + // The name from the group's own kind-39000 metadata, once it has loaded. + val metaName = current?.event?.name()?.ifBlank { null } + // Otherwise the name the user's joined-groups list stored for this group (the NIP-51 + // ["group", id, relay, name] tag) — so the row reads as a name even before 39000 is fetched, + // which the read-only settings picker never does. + val joined by accountViewModel.account.relayGroupList.liveRelayGroupList + .collectAsStateWithLifecycle() + val tagName = + remember(joined, entry) { + joined.firstOrNull { it.groupId == entry.groupId && it.relayUrl == entry.relayUrl }?.name?.ifBlank { null } + } + return GroupEntryDisplay( - label = current?.toBestDisplayName() ?: entry.groupId, + label = metaName ?: tagName ?: entry.groupId, robotSeed = entry.groupId, model = current?.profilePicture(), route = Route.RelayGroup(entry.groupId, entry.relayUrl),