.
This commit is contained in:
@@ -39,12 +39,11 @@ class MessageManager(private val nostr: Nostr) {
|
|||||||
private val client: Client? get() = nostr.client
|
private val client: Client? get() = nostr.client
|
||||||
private val signer: UniversalSigner get() = nostr.signer
|
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())
|
private val _messageSyncState = MutableStateFlow(MessageSyncState())
|
||||||
val messageSyncState = _messageSyncState.asStateFlow()
|
val messageSyncState = _messageSyncState.asStateFlow()
|
||||||
|
|
||||||
|
val rumorMap: MutableMap<EventId, EventId> = mutableMapOf()
|
||||||
|
|
||||||
fun updateSyncState(update: (MessageSyncState) -> MessageSyncState) {
|
fun updateSyncState(update: (MessageSyncState) -> MessageSyncState) {
|
||||||
_messageSyncState.update(update)
|
_messageSyncState.update(update)
|
||||||
}
|
}
|
||||||
@@ -333,9 +332,6 @@ class MessageManager(private val nostr: Nostr) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (output != null) {
|
if (output != null) {
|
||||||
// Keep track of sent events
|
|
||||||
sentEvents[output.id] = emptyList()
|
|
||||||
|
|
||||||
// Keep track of rumor IDs
|
// Keep track of rumor IDs
|
||||||
val id = rumor.id() ?: throw IllegalStateException("Rumor ID is null")
|
val id = rumor.id() ?: throw IllegalStateException("Rumor ID is null")
|
||||||
rumorMap[id] = output.id
|
rumorMap[id] = output.id
|
||||||
|
|||||||
@@ -174,8 +174,6 @@ class Nostr(
|
|||||||
|
|
||||||
when (notification) {
|
when (notification) {
|
||||||
is ClientNotification.Message -> {
|
is ClientNotification.Message -> {
|
||||||
val relayUrl = notification.relayUrl
|
|
||||||
|
|
||||||
when (val message = notification.message.asEnum()) {
|
when (val message = notification.message.asEnum()) {
|
||||||
is RelayMessageEnum.EventMsg -> {
|
is RelayMessageEnum.EventMsg -> {
|
||||||
val event = message.event
|
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 -> {
|
else -> {
|
||||||
/* Ignore other message types */
|
/* Ignore other message types */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
try {
|
||||||
val event = EventBuilder.relayList(relays).finalizeAsync(signer)
|
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)
|
throw IllegalStateException("Failed to set msg relays: ${e.message}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun setMsgRelays(urls: List<RelayUrl>) {
|
suspend fun setMsgRelays(urls: List<RelayUrl>) {
|
||||||
try {
|
try {
|
||||||
val event = EventBuilder.nip17RelayList(urls).finalizeAsync(signer)
|
val event = EventBuilder.nip17RelayList(urls).finalizeAsync(signer)
|
||||||
|
|||||||
@@ -511,7 +511,7 @@ class AccountRepository(
|
|||||||
val relays = currentUserRelayListInternal().toMutableMap()
|
val relays = currentUserRelayListInternal().toMutableMap()
|
||||||
relays[relayUrl] = RelayMetadata.WRITE
|
relays[relayUrl] = RelayMetadata.WRITE
|
||||||
|
|
||||||
nostr.relays.setRelaylist(relays)
|
nostr.relays.setRelayList(relays)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showError("Error: ${e.message}")
|
showError("Error: ${e.message}")
|
||||||
}
|
}
|
||||||
@@ -525,7 +525,7 @@ class AccountRepository(
|
|||||||
val relays = currentUserRelayListInternal().toMutableMap()
|
val relays = currentUserRelayListInternal().toMutableMap()
|
||||||
relays[relayUrl] = RelayMetadata.READ
|
relays[relayUrl] = RelayMetadata.READ
|
||||||
|
|
||||||
nostr.relays.setRelaylist(relays)
|
nostr.relays.setRelayList(relays)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showError("Error: ${e.message}")
|
showError("Error: ${e.message}")
|
||||||
}
|
}
|
||||||
@@ -539,7 +539,7 @@ class AccountRepository(
|
|||||||
val relays = currentUserRelayListInternal().toMutableMap()
|
val relays = currentUserRelayListInternal().toMutableMap()
|
||||||
relays.remove(relayUrl)
|
relays.remove(relayUrl)
|
||||||
|
|
||||||
nostr.relays.setRelaylist(relays)
|
nostr.relays.setRelayList(relays)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showError("Error: ${e.message}")
|
showError("Error: ${e.message}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,18 +85,7 @@ class ChatRepository(
|
|||||||
// Observe new messages
|
// Observe new messages
|
||||||
launch {
|
launch {
|
||||||
nostr.newEvents.collect { event ->
|
nostr.newEvents.collect { event ->
|
||||||
val roomId = event.roomId()
|
updateRoomState(event)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,9 +186,10 @@ class ChatRepository(
|
|||||||
content = message,
|
content = message,
|
||||||
subject = room.subject,
|
subject = room.subject,
|
||||||
replies = replies,
|
replies = replies,
|
||||||
onRumorCreated = { event ->
|
onRumorCreated = {
|
||||||
updateRoomList(roomId, event)
|
scope.launch(defaultDispatcher) {
|
||||||
scope.launch(defaultDispatcher) { _newEvents.tryEmit(event) }
|
updateRoomState(it, roomId)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -226,26 +216,32 @@ class ChatRepository(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isMessageSent(id: EventId): Boolean {
|
private suspend fun updateRoomState(event: UnsignedEvent, roomId: Long = event.roomId()) {
|
||||||
val giftWrapId = nostr.messages.rumorMap[id]
|
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 ->
|
_state.update { currentState ->
|
||||||
val room = currentState.rooms[roomId] ?: return@update currentState
|
val rooms = currentState.rooms.toMutableMap()
|
||||||
val updatedRoom = room.copy(
|
val existingRoom = rooms[roomId]
|
||||||
lastMessage = newMessage.content(),
|
|
||||||
createdAt = newMessage.createdAt()
|
if (existingRoom == null) {
|
||||||
)
|
// New room discovery
|
||||||
currentState.copy(rooms = currentState.rooms + (roomId to updatedRoom))
|
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() {
|
fun resetInternalState() {
|
||||||
|
|||||||
Reference in New Issue
Block a user