2 Commits

Author SHA1 Message Date
38b704fe18 improve initial loading 2026-07-09 16:44:11 +07:00
e0701504aa remove unnecessary query call 2026-07-09 16:12:38 +07:00
4 changed files with 23 additions and 32 deletions

View File

@@ -155,7 +155,7 @@ fun HomeScreen() {
onPauseOrDispose { }
}
LaunchedEffect(Unit) {
LaunchedEffect(authState.signerRequired) {
chatViewModel.refreshChatRooms()
}

View File

@@ -41,8 +41,7 @@ data class Room(
}
companion object {
fun new(rumor: UnsignedEvent, userPubkey: PublicKey): Room {
val id = rumor.roomId()
fun new(rumor: UnsignedEvent, userPubkey: PublicKey, id: Long = rumor.roomId()): Room {
val createdAt = rumor.createdAt()
val subject = rumor.tags().toVec().find { it.kind() == "subject" }?.content()

View File

@@ -170,32 +170,29 @@ class MessageManager(private val nostr: Nostr) {
// Get all DM events
val filter = Filter().kind(kind).customTags(kTag, listOf("14", "dm"))
val events = client?.database()?.query(filter)
val events = client?.database()?.query(filter)?.toVec() ?: return null
// Collect rooms
val roomsMap: MutableMap<Long, Room> = mutableMapOf()
events
?.toVec()
?.map { UnsignedEvent.fromJson(it.content()) }
?.filter { it.tags().publicKeys().isNotEmpty() }
?.forEach { event ->
val newRoom = Room.new(rumor = event, userPubkey = userPubkey)
val existingRoom = roomsMap[newRoom.id]
.map { UnsignedEvent.fromJson(it.content()) }
.filter { it.tags().publicKeys().isNotEmpty() }
.forEach { rumor ->
val id = rumor.roomId()
val isFromMe = rumor.author() == userPubkey
val existing = roomsMap[id]
val createdAt = rumor.createdAt()
// Check if the room already exists
if (existingRoom == null || newRoom.createdAt.asSecs() > existingRoom.createdAt.asSecs()) {
val rTag = SingleLetterTag.lowercase(Alphabet.R)
val filter = Filter().kind(kind).pubkey(userPubkey)
.customTag(rTag, newRoom.id.toString())
// Determine if it's an ongoing room
val isOngoing =
client?.database()?.query(filter)?.toVec()?.isNotEmpty() ?: false
// Append room to map
roomsMap[newRoom.id] =
if (isOngoing) newRoom.copy(kind = RoomKind.Ongoing) else newRoom
// 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
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)
}
}

View File

@@ -69,8 +69,8 @@ class ChatViewModel(private val nostr: Nostr) : BaseViewModel() {
_state.update { it.copy(isPartialProcessedGiftWrap = true) }
}
// Refresh UI every 10 messages OR when sync is fully done
if (syncState.processedCount % 10 == 0 || !syncState.isSyncing) {
// Refresh UI every 100 messages OR when sync is fully done
if (syncState.processedCount % 100 == 0 || !syncState.isSyncing) {
refreshChatRooms()
}
}
@@ -97,9 +97,6 @@ class ChatViewModel(private val nostr: Nostr) : BaseViewModel() {
_newEvents.emit(event)
}
}
// Initial load of rooms
refreshChatRooms()
}
}
@@ -149,9 +146,7 @@ class ChatViewModel(private val nostr: Nostr) : BaseViewModel() {
_state.update { currentState ->
val merged = currentState.rooms.associateBy { it.id }.toMutableMap()
// Add or update rooms from the database
rooms.forEach { room ->
merged[room.id] = room
}
rooms.forEach { room -> merged[room.id] = room }
// Return as a sorted set to maintain UI consistency
currentState.copy(rooms = merged.values.sortedDescending().toSet())
}