test+polish: verify NIP-29 placeholder gatherer; show "No messages yet"

Add a regression test proving RelayGroupChannel.placeholderNote() carries the
channel as a gatherer and is cached/stable — this is what lets the Messages row
renderer resolve the event-less placeholder back to the group (the prior fix).

Also give the empty-group placeholder row a visible "No messages yet" second
line instead of blank content, matching the Marmot-group row, so a just-joined
group with no messages reads clearly rather than looking like an empty item.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B5MLY4hq5LXJ2D5WeLRyXj
This commit is contained in:
Claude
2026-07-09 21:21:59 +00:00
parent 7c581edddc
commit a645688baf
3 changed files with 18 additions and 1 deletions
@@ -337,7 +337,9 @@ private fun RelayGroupRoomCompose(
val authorName by observeUserName(author, accountViewModel)
"$authorName: ${noteEvent.content.take(200)}"
} else {
""
// Event-less placeholder row for a just-joined group with no messages yet — say so
// explicitly (like Marmot groups) instead of an empty second line.
stringRes(R.string.relay_group_no_messages_yet)
}
ChannelName(
+1
View File
@@ -2007,6 +2007,7 @@
<string name="relay_group_browse_go">Browse</string>
<string name="relay_group_browse_your_relays">Relays you\'re on</string>
<string name="relay_group_browse_popular">Popular relays</string>
<string name="relay_group_no_messages_yet">No messages yet</string>
<string name="relay_group_join_to_post">Join this group to send messages.</string>
<string name="relay_group_invite_only_to_post">This group is invite-only — you need an invite to post.</string>
<plurals name="relay_group_member_count">
@@ -79,6 +79,20 @@ class RelayGroupChannelTest {
return EventFactory.create("00".repeat(32), relaySelf, createdAt, GroupAdminsEvent.KIND, tags, "", "22".repeat(64)) as GroupAdminsEvent
}
@Test
fun placeholderNoteCarriesChannelGathererAndIsStable() {
val c = channel()
val note = c.placeholderNote()
// Stable, group-derived id and — crucially — the channel is registered as a gatherer so the
// Messages row renderer (ChatroomHeaderCompose) resolves the event-less note back to the
// group instead of blanking it.
assertEquals("relaygroup-empty-${c.groupId.toKey()}", note.idHex)
assertTrue(note.inGatherers?.any { it === c } == true)
// Cached: same instance on repeat so equality-based feed diffing keeps one stable row.
assertTrue(c.placeholderNote() === note)
}
@Test
fun membershipFromRolesAndMembers() {
val c = channel()