mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 16:14:40 +00:00
fix(chats): match public-channel rows by channel id when merging updates
ChatroomListKnownFeedFilter.updateListWith only recognized ChannelMessageEvent when checking the old list for an existing row to replace. When a public channel's row was first populated from a ChannelCreateEvent or ChannelMetadataEvent (no message had arrived yet), the next incoming ChannelMessageEvent failed to match, so the filter appended a second note for the same channel. Both rows then produced the same PublicChannelLazyKey, crashing the LazyColumn with "Key was already used". Resolve the channel id from any IsInPublicChatChannel event (covers ChannelMessageEvent and ChannelMetadataEvent) and fall back to the event id for ChannelCreateEvent, mirroring how the lazy key is built in ChatroomListFeedView.
This commit is contained in:
+15
-1
@@ -30,6 +30,8 @@ import com.vitorpamplona.quartz.experimental.ephemChat.chat.EphemeralChatEvent
|
||||
import com.vitorpamplona.quartz.experimental.ephemChat.chat.RoomId
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
|
||||
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKeyable
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.base.IsInPublicChatChannel
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
|
||||
class ChatroomListKnownFeedFilter(
|
||||
@@ -111,7 +113,7 @@ class ChatroomListKnownFeedFilter(
|
||||
newRelevantPublicMessages.forEach { newNotePair ->
|
||||
var hasUpdated = false
|
||||
oldList.forEach { oldNote ->
|
||||
val channelId = (oldNote.event as? ChannelMessageEvent)?.channelId()
|
||||
val channelId = publicChannelIdOf(oldNote)
|
||||
if (newNotePair.key == channelId) {
|
||||
hasUpdated = true
|
||||
if ((newNotePair.value.createdAt() ?: 0L) > (oldNote.createdAt() ?: 0L)) {
|
||||
@@ -260,4 +262,16 @@ class ChatroomListKnownFeedFilter(
|
||||
}
|
||||
|
||||
override fun sort(items: Set<Note>): List<Note> = items.sortedWith(DefaultFeedOrder)
|
||||
|
||||
// The chat list keys public-channel rows by channel id, so the existing row
|
||||
// for a channel may be backed by a ChannelCreateEvent or ChannelMetadataEvent
|
||||
// (when no message has arrived yet) — not only a ChannelMessageEvent. Matching
|
||||
// only ChannelMessageEvent here would leave the old row in place and append the
|
||||
// new one, producing a duplicate LazyColumn key.
|
||||
private fun publicChannelIdOf(note: Note): String? =
|
||||
when (val event = note.event) {
|
||||
is IsInPublicChatChannel -> event.channelId()
|
||||
is ChannelCreateEvent -> event.id
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user