mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 08:04:45 +00:00
fix: show a just-joined NIP-29 group on the Messages tab immediately
The Messages tab (INLINE mode) mapped each joined group to its newest cached kind-9 message and dropped it when none existed. Since the joined-groups subscription only fetches roster kinds (39000/1/2), not chat, a group you just joined stayed invisible until you opened it (loading messages) or posted — unlike Marmot groups, which already fall back to a placeholder row. Mirror the Marmot pattern for relay groups: - RelayGroupChannel.placeholderNote(): a cached synthetic note that adds the channel as a gatherer, so the existing Messages row renderer resolves it back to the group (RelayGroupRoomCompose already handles a null-event note). - ChatroomListKnownFeedFilter.feed(): fall back to placeholderNote() when the group has no loaded message. - AccountFeedContentStates: rebuild dmKnown when relayGroupList (kind 10009) changes — join/leave doesn't flow through newEventBundles, so without this the placeholder wouldn't appear until a later event. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B5MLY4hq5LXJ2D5WeLRyXj
This commit is contained in:
+11
@@ -167,6 +167,17 @@ class AccountFeedContentStates(
|
||||
}
|
||||
}
|
||||
|
||||
// Same for the NIP-29 joined-group list (kind 10009): joining/leaving changes the list but
|
||||
// doesn't flow through newEventBundles, so force a rebuild — otherwise a just-joined group
|
||||
// (whose messages haven't loaded yet) wouldn't appear on the Messages tab until a later event.
|
||||
scope.launch(Dispatchers.IO) {
|
||||
account.relayGroupList.liveRelayGroupList
|
||||
.drop(1)
|
||||
.collect {
|
||||
dmKnown.invalidateData()
|
||||
}
|
||||
}
|
||||
|
||||
// Pinning/unpinning a room only changes sort order, not membership, so no
|
||||
// chat event flows through LocalCache. Force a rebuild to re-sort. This
|
||||
// also fires when pins arrive via the synced AppSpecificData event.
|
||||
|
||||
+5
-3
@@ -102,12 +102,14 @@ class ChatroomListKnownFeedFilter(
|
||||
if (account.settings.relayGroupViewMode.value == RelayGroupViewMode.INLINE) {
|
||||
account.relayGroupList.liveRelayGroupList.value.mapNotNull { groupTag ->
|
||||
val relay = RelayUrlNormalizer.normalizeOrNull(groupTag.relayUrl) ?: return@mapNotNull null
|
||||
LocalCache
|
||||
.getOrCreateRelayGroupChannel(GroupId(groupTag.groupId, relay))
|
||||
.notes
|
||||
val channel = LocalCache.getOrCreateRelayGroupChannel(GroupId(groupTag.groupId, relay))
|
||||
// Newest loaded message, or a placeholder row so a just-joined group shows up on
|
||||
// Messages before its first kind-9 arrives (mirrors the Marmot-group path above).
|
||||
channel.notes
|
||||
.filter { _, it -> account.isAcceptable(it) && it.event != null }
|
||||
.sortedByDefaultFeedOrder()
|
||||
.firstOrNull()
|
||||
?: channel.placeholderNote()
|
||||
}
|
||||
} else {
|
||||
emptyList()
|
||||
|
||||
+22
@@ -23,6 +23,8 @@ package com.vitorpamplona.amethyst.commons.model.nip29RelayGroups
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.vitorpamplona.amethyst.commons.model.Channel
|
||||
import com.vitorpamplona.amethyst.commons.model.Note
|
||||
import com.vitorpamplona.amethyst.commons.util.KmpLock
|
||||
import com.vitorpamplona.amethyst.commons.util.withLock
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
|
||||
import com.vitorpamplona.quartz.nip29RelayGroups.GroupId
|
||||
@@ -203,4 +205,24 @@ class RelayGroupChannel(
|
||||
groupId.id.contains(prefix, true) ||
|
||||
event?.name()?.contains(prefix, true) == true ||
|
||||
event?.about()?.contains(prefix, true) == true
|
||||
|
||||
// Synthetic note representing this group in list views (the Messages tab) before any message
|
||||
// has loaded — so a group the user just joined shows up immediately instead of waiting for its
|
||||
// first cached kind-9. Mirrors MarmotGroupChatroom.placeholderNote(): adds this channel as a
|
||||
// gatherer so the list row resolves back to it, and is cached with a stable id so equality-based
|
||||
// feed diffing treats it as the same row across refreshes.
|
||||
private val placeholderLock = KmpLock()
|
||||
private var cachedPlaceholder: Note? = null
|
||||
|
||||
fun placeholderNote(): Note =
|
||||
placeholderLock.withLock {
|
||||
cachedPlaceholder ?: Note(placeholderIdHex(groupId)).apply {
|
||||
addGatherer(this@RelayGroupChannel)
|
||||
cachedPlaceholder = this
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun placeholderIdHex(groupId: GroupId): HexKey = "relaygroup-empty-${groupId.toKey()}"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user