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 a3ac909..3e3a002 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Messaging.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Messaging.kt @@ -39,12 +39,11 @@ class MessageManager(private val nostr: Nostr) { private val client: Client? get() = nostr.client private val signer: UniversalSigner get() = nostr.signer - val sentEvents: MutableMap> = mutableMapOf() - val rumorMap: MutableMap = mutableMapOf() - private val _messageSyncState = MutableStateFlow(MessageSyncState()) val messageSyncState = _messageSyncState.asStateFlow() + val rumorMap: MutableMap = mutableMapOf() + fun updateSyncState(update: (MessageSyncState) -> MessageSyncState) { _messageSyncState.update(update) } @@ -333,9 +332,6 @@ class MessageManager(private val nostr: Nostr) { ) if (output != null) { - // Keep track of sent events - sentEvents[output.id] = emptyList() - // Keep track of rumor IDs val id = rumor.id() ?: throw IllegalStateException("Rumor ID is null") rumorMap[id] = output.id diff --git a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt index 9d90f55..2580334 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt @@ -174,8 +174,6 @@ class Nostr( when (notification) { is ClientNotification.Message -> { - val relayUrl = notification.relayUrl - when (val message = notification.message.asEnum()) { is RelayMessageEnum.EventMsg -> { val event = message.event @@ -229,14 +227,6 @@ class Nostr( } } - is RelayMessageEnum.Ok -> { - if (messages.sentEvents.containsKey(message.eventId)) { - val currentRelays = - messages.sentEvents[message.eventId] ?: emptyList() - messages.sentEvents[message.eventId] = currentRelays + relayUrl - } - } - else -> { /* Ignore other message types */ } diff --git a/shared/src/commonMain/kotlin/su/reya/coop/nostr/RelayManager.kt b/shared/src/commonMain/kotlin/su/reya/coop/nostr/RelayManager.kt index 12482bd..5242dad 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/nostr/RelayManager.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/nostr/RelayManager.kt @@ -130,7 +130,7 @@ class RelayManager(private val nostr: Nostr) { } } - suspend fun setRelaylist(relays: Map) { + suspend fun setRelayList(relays: Map) { try { val event = EventBuilder.relayList(relays).finalizeAsync(signer) @@ -143,7 +143,7 @@ class RelayManager(private val nostr: Nostr) { throw IllegalStateException("Failed to set msg relays: ${e.message}", e) } } - + suspend fun setMsgRelays(urls: List) { try { val event = EventBuilder.nip17RelayList(urls).finalizeAsync(signer) diff --git a/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt b/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt index e7562c7..f92956f 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt @@ -511,7 +511,7 @@ class AccountRepository( val relays = currentUserRelayListInternal().toMutableMap() relays[relayUrl] = RelayMetadata.WRITE - nostr.relays.setRelaylist(relays) + nostr.relays.setRelayList(relays) } catch (e: Exception) { showError("Error: ${e.message}") } @@ -525,7 +525,7 @@ class AccountRepository( val relays = currentUserRelayListInternal().toMutableMap() relays[relayUrl] = RelayMetadata.READ - nostr.relays.setRelaylist(relays) + nostr.relays.setRelayList(relays) } catch (e: Exception) { showError("Error: ${e.message}") } @@ -539,7 +539,7 @@ class AccountRepository( val relays = currentUserRelayListInternal().toMutableMap() relays.remove(relayUrl) - nostr.relays.setRelaylist(relays) + nostr.relays.setRelayList(relays) } catch (e: Exception) { showError("Error: ${e.message}") } 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 3968af5..f26410b 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/repository/ChatRepository.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/repository/ChatRepository.kt @@ -85,18 +85,7 @@ class ChatRepository( // Observe new messages launch { nostr.newEvents.collect { event -> - val roomId = event.roomId() - val existingRoom = _state.value.rooms[roomId] - - if (existingRoom == null) { - val currentUser = nostr.signer.getPublicKeyAsync() ?: return@collect - val newRoom = Room.new(event, currentUser) - _state.update { it.copy(rooms = it.rooms + (newRoom.id to newRoom)) } - } else { - updateRoomList(roomId, event) - } - - _newEvents.tryEmit(event) + updateRoomState(event) } } } @@ -197,9 +186,10 @@ class ChatRepository( content = message, subject = room.subject, replies = replies, - onRumorCreated = { event -> - updateRoomList(roomId, event) - scope.launch(defaultDispatcher) { _newEvents.tryEmit(event) } + onRumorCreated = { + scope.launch(defaultDispatcher) { + updateRoomState(it, roomId) + } }, ) } catch (e: Exception) { @@ -226,26 +216,32 @@ class ChatRepository( } } - fun isMessageSent(id: EventId): Boolean { - val giftWrapId = nostr.messages.rumorMap[id] + private suspend fun updateRoomState(event: UnsignedEvent, roomId: Long = event.roomId()) { + val currentUser = nostr.signer.getPublicKeyAsync() ?: return - if (giftWrapId != null) { - val isSent = nostr.messages.sentEvents[giftWrapId]?.isNotEmpty() ?: false - return isSent - } else { - return false - } - } - - private fun updateRoomList(roomId: Long, newMessage: UnsignedEvent) { _state.update { currentState -> - val room = currentState.rooms[roomId] ?: return@update currentState - val updatedRoom = room.copy( - lastMessage = newMessage.content(), - createdAt = newMessage.createdAt() - ) - currentState.copy(rooms = currentState.rooms + (roomId to updatedRoom)) + val rooms = currentState.rooms.toMutableMap() + val existingRoom = rooms[roomId] + + if (existingRoom == null) { + // New room discovery + val newRoom = Room.new(event, currentUser, roomId) + rooms[newRoom.id] = newRoom + } else if (event.createdAt().asSecs() >= existingRoom.createdAt.asSecs()) { + // Only update preview if message is newer (handles sync/late arrivals) + rooms[roomId] = existingRoom.copy( + lastMessage = event.content(), + createdAt = event.createdAt() + ) + } else { + // Don't update the room list state for older messages + return@update currentState + } + currentState.copy(rooms = rooms) } + + // Notify subscribers about the new event (for the active chat screen) + _newEvents.tryEmit(event) } fun resetInternalState() {