chore: fix some crash and performance issues #45

Merged
reya merged 5 commits from perf-patch into master 2026-07-15 12:44:29 +00:00
5 changed files with 35 additions and 53 deletions
Showing only changes of commit 265bc0cbf7 - Show all commits

View File

@@ -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<EventId, List<RelayUrl>> = mutableMapOf()
val rumorMap: MutableMap<EventId, EventId> = mutableMapOf()
private val _messageSyncState = MutableStateFlow(MessageSyncState())
val messageSyncState = _messageSyncState.asStateFlow()
val rumorMap: MutableMap<EventId, EventId> = 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

View File

@@ -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 */
}

View File

@@ -130,7 +130,7 @@ class RelayManager(private val nostr: Nostr) {
}
}
suspend fun setRelaylist(relays: Map<RelayUrl, RelayMetadata?>) {
suspend fun setRelayList(relays: Map<RelayUrl, RelayMetadata?>) {
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<RelayUrl>) {
try {
val event = EventBuilder.nip17RelayList(urls).finalizeAsync(signer)

View File

@@ -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}")
}

View File

@@ -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() {