Merge pull request #2511 from vitorpamplona/claude/fix-marmot-group-tabs-zLq2N

Implement known/new group classification based on follow set
This commit is contained in:
Vitor Pamplona
2026-04-22 18:02:58 -04:00
committed by GitHub
5 changed files with 37 additions and 4 deletions
@@ -124,6 +124,7 @@ class AccountFeedContentStates(
scope.launch(Dispatchers.IO) {
account.marmotGroupList.groupListChanges.collect {
dmKnown.invalidateData()
dmNew.invalidateData()
}
}
}
@@ -93,8 +93,12 @@ fun MarmotGroupListScreen(
// (Account.ensureMarmotKeyPackagePublished), so this screen no longer
// needs to do anything to make sure invitees can find a KeyPackage.
val knownGroups = remember(groupList) { groupList.filter { it.second.ownerSentMessage } }
val newRequestGroups = remember(groupList) { groupList.filter { !it.second.ownerSentMessage } }
val followState by accountViewModel.account.kind3FollowList.flow
.collectAsStateWithLifecycle()
val followingKeySet = followState.authors
val knownGroups = remember(groupList, followingKeySet) { groupList.filter { it.second.isKnown(followingKeySet) } }
val newRequestGroups = remember(groupList, followingKeySet) { groupList.filter { !it.second.isKnown(followingKeySet) } }
val visibleGroups = if (selectedTab == 0) knownGroups else newRequestGroups
Scaffold(
@@ -79,7 +79,11 @@ class ChatroomListKnownFeedFilter(
val marmotGroups =
account.marmotGroupList.rooms.mapNotNull { _, chatroom ->
chatroom.newestMessage ?: chatroom.placeholderNote()
if (chatroom.isKnown(followingKeySet)) {
chatroom.newestMessage ?: chatroom.placeholderNote()
} else {
null
}
}
return (privateMessages + publicChannels + ephemeralChats + marmotGroups).sortedWith(DefaultFeedOrder)
@@ -47,7 +47,16 @@ class ChatroomListNewFeedFilter(
}
}
return privateMessages.sortedWith(DefaultFeedOrder)
val marmotGroups =
account.marmotGroupList.rooms.mapNotNull { _, chatroom ->
if (!chatroom.isKnown(followingKeySet)) {
chatroom.newestMessage ?: chatroom.placeholderNote()
} else {
null
}
}
return (privateMessages + marmotGroups).sortedWith(DefaultFeedOrder)
}
override fun updateListWith(
@@ -69,6 +69,21 @@ class MarmotGroupChatroom(
*/
var ownerSentMessage: Boolean = false
/**
* Classifies this group for the Known/New Requests split.
*
* Rules:
* - If the local user has already participated ([ownerSentMessage]), Known.
* - If the group has no known members and no messages yet, New Requests
* (we don't know who invited us, so it's untrusted by default).
* - Otherwise, Known iff at least one admin is in the follow set.
*/
fun isKnown(followingKeySet: Set<HexKey>): Boolean {
if (ownerSentMessage) return true
if (memberCount.value == 0 && messages.isEmpty()) return false
return adminPubkeys.value.any { it in followingKeySet }
}
// Synthetic note used by list views to represent the group when no
// messages have been received yet. Lazily created and kept stable so
// equality-based feed diffing treats it as the same row across refreshes.