From 0366d6d58445bf7edef0e2539c35f5c54e1055a8 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Jul 2026 21:48:28 +0000 Subject: [PATCH] fix: render group messages on the Messages tab even when unattached MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A NIP-29 group message whose note isn't attached to its RelayGroupChannel (its gatherer never registered — loaded before the channel existed, or via a path that skips attach) hit ChatroomEntry's when(event) with no matching case and fell to `else -> BlankNote()`: a white, non-clickable row where the group should be. The inGatherers check only covers attached notes. Handle group-scoped events explicitly before the when: resolve the group from the event's `h` tag + the note's provenance relay and render RelayGroupRoomCompose, so the row shows the group and taps through to the chat. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01B5MLY4hq5LXJ2D5WeLRyXj --- .../chats/rooms/ChatroomHeaderCompose.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt index b7bf8ec2ff..ff59f05f9e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt @@ -58,6 +58,7 @@ import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.model.marmotGroups.MarmotGroupChatroom import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel +import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo @@ -97,6 +98,9 @@ import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent +import com.vitorpamplona.quartz.nip29RelayGroups.GroupId +import com.vitorpamplona.quartz.nip29RelayGroups.groupId +import com.vitorpamplona.quartz.nip29RelayGroups.isGroupScoped import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent @Composable @@ -159,6 +163,24 @@ private fun ChatroomEntry( return } + // A NIP-29 group message whose channel gatherer didn't attach (e.g. loaded before its channel + // existed, or via a path that skips attach) has no case in the when() below and would blank out. + // Resolve the group from its `h` tag + provenance relay and render the group row anyway. + val groupScopedEvent = lastMessage.event?.takeIf { it.isGroupScoped() } + if (groupScopedEvent != null) { + val gid = groupScopedEvent.groupId() + val hostRelay = lastMessage.relays.firstOrNull() + if (gid != null && hostRelay != null) { + RelayGroupRoomCompose( + lastMessage, + LocalCache.getOrCreateRelayGroupChannel(GroupId(gid, hostRelay)), + accountViewModel, + nav, + ) + return + } + } + val baseNoteEvent = lastMessage.event when (baseNoteEvent) { // ChannelMessageEvent and ChannelMetadataEvent both expose channelId() via