From c21b8e286834c8b36e2fe100bffb9c69824843b3 Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Mon, 7 Sep 2026 20:25:38 +0700 Subject: [PATCH] update chat room list --- .../kotlin/su/reya/coop/nostr/Messaging.kt | 44 ++++++++++++++----- .../su/reya/coop/repository/ChatRepository.kt | 9 ++-- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Messaging.kt b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Messaging.kt index 03d428f..f362db1 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Messaging.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Messaging.kt @@ -179,12 +179,13 @@ class MessageManager(private val nostr: Nostr) { val kind = Kind.fromStd(KindStandard.APPLICATION_SPECIFIC_DATA) val kTag = SingleLetterTag.lowercase(Alphabet.K) - // Get all DM events - val filter = Filter().kind(kind).customTags(kTag, listOf("14", "dm")) + // Get all rumors (DMs and Reactions) + val filter = Filter().kind(kind).customTags(kTag, listOf("14", "dm", "reaction")) val events = client?.database()?.query(filter)?.toVec() ?: return null // Collect rooms val roomsMap: MutableMap = mutableMapOf() + val lastDmTimestampMap: MutableMap = mutableMapOf() events .map { UnsignedEvent.fromJson(it.content()) } @@ -192,18 +193,41 @@ class MessageManager(private val nostr: Nostr) { .forEach { rumor -> val id = rumor.roomId() val isFromMe = rumor.author() == userPubkey + val isReaction = rumor.kind().asStd() == KindStandard.REACTION val existing = roomsMap[id] val createdAt = rumor.createdAt() - // If the room is new or the current rumor is newer than the existing one - if (existing == null || createdAt.asSecs() > existing.createdAt.asSecs()) { - // A room is "Ongoing" if it was already marked as such or if the current rumor is from the user - val isOngoing = (existing?.kind == RoomKind.Ongoing) || isFromMe + if (existing == null) { val room = Room.new(rumor = rumor, userPubkey = userPubkey, id = id) - roomsMap[id] = if (isOngoing) room.copy(kind = RoomKind.Ongoing) else room - } else if (isFromMe && existing.kind != RoomKind.Ongoing) { - // If it's an older rumor but sent by the user, mark the room as Ongoing - roomsMap[id] = existing.copy(kind = RoomKind.Ongoing) + // If the first event we see is a reaction, don't use it as lastMessage + roomsMap[id] = if (isReaction) { + room.copy(lastMessage = null) + } else { + lastDmTimestampMap[id] = createdAt.asSecs() + room + } + if (isFromMe) { + roomsMap[id] = roomsMap[id]!!.copy(kind = RoomKind.Ongoing) + } + } else { + // Update the overall room timestamp (for sorting) if this event is newer + if (createdAt.asSecs() > existing.createdAt.asSecs()) { + roomsMap[id] = roomsMap[id]!!.copy(createdAt = createdAt) + } + + // Update the last message content if this is a DM and it's newer than the last DM we've seen + if (!isReaction) { + val lastDmTs = lastDmTimestampMap[id] ?: 0uL + if (createdAt.asSecs() >= lastDmTs) { + lastDmTimestampMap[id] = createdAt.asSecs() + roomsMap[id] = roomsMap[id]!!.copy(lastMessage = rumor.content()) + } + } + + // If any event is from the user, mark the room as Ongoing + if (isFromMe && roomsMap[id]?.kind != RoomKind.Ongoing) { + roomsMap[id] = roomsMap[id]!!.copy(kind = RoomKind.Ongoing) + } } } diff --git a/shared/src/commonMain/kotlin/su/reya/coop/repository/ChatRepository.kt b/shared/src/commonMain/kotlin/su/reya/coop/repository/ChatRepository.kt index 71f9eed..645b384 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/repository/ChatRepository.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/repository/ChatRepository.kt @@ -281,13 +281,14 @@ class ChatRepository( lastMessage = if (isReaction) null else event.content() ) rooms[newRoom.id] = newRoom - } else if (!isReaction && event.createdAt().asSecs() >= existingRoom.createdAt.asSecs()) { - // Only update preview if message is newer (handles sync/late arrivals) + } else if (event.createdAt().asSecs() >= existingRoom.createdAt.asSecs()) { + // Update timestamp for any newer event (DM or Reaction) + // But only update preview if it's a DM rooms[roomId] = existingRoom.copy( - lastMessage = event.content(), + lastMessage = if (isReaction) existingRoom.lastMessage else event.content(), createdAt = event.createdAt(), kind = newKind, - unreadCount = if (isFromMe) existingRoom.unreadCount else existingRoom.unreadCount + 1 + unreadCount = if (isFromMe || isReaction) existingRoom.unreadCount else existingRoom.unreadCount + 1 ) } else if (isFromMe && existingRoom.kind != RoomKind.Ongoing) { // Even if it's an older message or reaction, if it's from me, the room is ongoing