Add message status logic

This commit is contained in:
Kgothatso Ngako committed 2026-06-03 03:20:20 +02:00
1 parent ff7fe8bc4b
commit 8f7381d182
6 files changed
+53 -16

No files matched your search

@@ -25,5 +25,5 @@ interface BroadcastNostrEventRequestDao {
suspend fun upsert(broadcastNostrEventRequest: BroadcastNostrEventRequest) suspend fun upsert(broadcastNostrEventRequest: BroadcastNostrEventRequest)
@Insert @Insert
suspend fun insert(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>) suspend fun insert(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>): LongArray
} }
@@ -16,6 +16,9 @@ interface ChatMessageDao {
@Query("SELECT * FROM ChatMessage WHERE chatRoomId = :chatRoomId ORDER BY createdAt DESC") @Query("SELECT * FROM ChatMessage WHERE chatRoomId = :chatRoomId ORDER BY createdAt DESC")
fun getChatMessagesByChatRoomId(chatRoomId: String): List<LocalChatMessage> fun getChatMessagesByChatRoomId(chatRoomId: String): List<LocalChatMessage>
@Query("SELECT * FROM ChatMessage WHERE giftWrapPayloadId = :giftWrapPayloadId ORDER BY createdAt DESC")
fun getChatMessagesByGiftWrapPayloadId(giftWrapPayloadId: Long): ChatMessage?
@Upsert @Upsert
suspend fun upsert(chatMessage: ChatMessage) suspend fun upsert(chatMessage: ChatMessage)
} }
@@ -3,8 +3,11 @@ package ac.cord.auxiliary.compose.database.dao
import ac.cord.auxiliary.compose.database.AuxDatabase import ac.cord.auxiliary.compose.database.AuxDatabase
import ac.cord.auxiliary.compose.database.GENESIS_AT import ac.cord.auxiliary.compose.database.GENESIS_AT
import ac.cord.auxiliary.compose.database.model.BroadcastNostrEventRequest import ac.cord.auxiliary.compose.database.model.BroadcastNostrEventRequest
import ac.cord.auxiliary.compose.database.model.ChatMessageBroadcastNostrEventRequestRelation
import ac.cord.auxiliary.compose.database.model.ChatMessageNostrEventRelation
import ac.cord.auxiliary.compose.database.model.ChatRoom import ac.cord.auxiliary.compose.database.model.ChatRoom
import ac.cord.auxiliary.compose.database.model.GiftWrapMessage import ac.cord.auxiliary.compose.database.model.GiftWrapMessage
import ac.cord.auxiliary.compose.database.model.GiftWrapPayload
import ac.cord.auxiliary.compose.database.model.GiftWrapSeal import ac.cord.auxiliary.compose.database.model.GiftWrapSeal
import ac.cord.auxiliary.compose.database.model.NostrEvent import ac.cord.auxiliary.compose.database.model.NostrEvent
import ac.cord.auxiliary.compose.database.model.Participant import ac.cord.auxiliary.compose.database.model.Participant
@@ -77,6 +80,7 @@ abstract class NostrNip17Dao(
@Transaction @Transaction
open suspend fun persistAndBroadcastGiftWrap( open suspend fun persistAndBroadcastGiftWrap(
giftWrapPayload: Pair<Int, GiftWrapPayload>,
sealedRumorEvent: SealedRumorEvent, sealedRumorEvent: SealedRumorEvent,
giftWrapEvent: GiftWrapEvent, giftWrapEvent: GiftWrapEvent,
receiverPublicKey: PTag receiverPublicKey: PTag
@@ -95,7 +99,18 @@ abstract class NostrNip17Dao(
database.nostrEventDao().insert(nostrEvent) database.nostrEventDao().insert(nostrEvent)
// TODO: Get ChatMessageRelayListEvent.KIND for receiverPublicKey.pubkey val chatMessage = database.chatMessageDao().getChatMessagesByGiftWrapPayloadId(giftWrapPayload.second.id)
chatMessage?.let {
database.chatMessageNostrEventRelationDao().upsert(
ChatMessageNostrEventRelation(
chatMessageId = it.id,
nostrEventId = nostrEvent.id
)
)
}
// Get ChatMessageRelayListEvent.KIND for receiverPublicKey.pubkey
val chatMessageRelayListEvents = database.nostrEventDao().getAuthoredNostrEvents( val chatMessageRelayListEvents = database.nostrEventDao().getAuthoredNostrEvents(
kinds = arrayOf(ChatMessageRelayListEvent.KIND), kinds = arrayOf(ChatMessageRelayListEvent.KIND),
authors = arrayOf( authors = arrayOf(
@@ -118,10 +133,10 @@ abstract class NostrNip17Dao(
logger.d("Broadcast to ${chatMessageRelayListEvent.relays()}") logger.d("Broadcast to ${chatMessageRelayListEvent.relays()}")
// TODO: Only broadcasting to the first 3 relays... // Only broadcasting to the first 3 relays...
chatMessageRelayListEvent.relays().take(3).forEach { relayUrl -> chatMessageRelayListEvent.relays().take(3).forEach { relayUrl ->
logger.d("Submit BroadcastNostrEventRequest to $relayUrl") logger.d("Submit BroadcastNostrEventRequest to $relayUrl")
database.broadcastNostrEventRequestDao().insert( val broadcastNostrEventRequestIds = database.broadcastNostrEventRequestDao().insert(
listOf( listOf(
BroadcastNostrEventRequest( BroadcastNostrEventRequest(
nostrEventId = nostrEvent.id, nostrEventId = nostrEvent.id,
@@ -129,6 +144,18 @@ abstract class NostrNip17Dao(
) )
) )
) )
chatMessage?.let {
broadcastNostrEventRequestIds.forEach {
database.chatMessageBroadcastNostrEventRequestRelationDao().upsert(
ChatMessageBroadcastNostrEventRequestRelation(
chatMessageId = chatMessage.id,
broadcastNostrEventRequestId = it
)
)
}
}
} }
} }
@@ -161,6 +188,16 @@ abstract class NostrNip17Dao(
) )
) )
logger.d("persistAndBroadcastGiftWrap done") logger.d("persistAndBroadcastGiftWrap done")
if (giftWrapPayload.first == 0 && giftWrapPayload.second.giftWrapSealId == null) {
// Only update the giftWrapPayload.giftWrapSealId on the first seal...
database.giftWrapPayloadDao().upsert(
giftWrapPayload.second.copy(
giftWrapSealId = sealedRumorEvent.id
)
)
logger.d("GiftWrap now sealed: ${giftWrapPayload.second.id}")
}
} }
companion object { companion object {
@@ -2,6 +2,7 @@ package ac.cord.auxiliary.compose.database.repository
import ac.cord.auxiliary.compose.database.AuxDatabase import ac.cord.auxiliary.compose.database.AuxDatabase
import ac.cord.auxiliary.compose.database.model.ChatMessage import ac.cord.auxiliary.compose.database.model.ChatMessage
import ac.cord.auxiliary.compose.database.model.ChatMessageNostrEventRelation
import ac.cord.auxiliary.compose.database.model.ChatRoom import ac.cord.auxiliary.compose.database.model.ChatRoom
import ac.cord.auxiliary.compose.database.model.GiftWrapPayload import ac.cord.auxiliary.compose.database.model.GiftWrapPayload
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatMessage import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatMessage
@@ -138,20 +139,14 @@ class DatabaseChatRepository(
logger.d("giftWrapEvent: ${giftWrapEvent.toJson()}") logger.d("giftWrapEvent: ${giftWrapEvent.toJson()}")
database.nostrNip17Dao().persistAndBroadcastGiftWrap( database.nostrNip17Dao().persistAndBroadcastGiftWrap(
giftWrapPayload = Pair(
index,
giftWrapPayload
),
sealedRumorEvent = sealedRumorEvent, sealedRumorEvent = sealedRumorEvent,
giftWrapEvent = giftWrapEvent, giftWrapEvent = giftWrapEvent,
receiverPublicKey = receiverPublicKey receiverPublicKey = receiverPublicKey
) )
if (index == 0 && giftWrapPayload.giftWrapSealId == null) {
// Only update the giftWrapPayload.giftWrapSealId on the first seal...
database.giftWrapPayloadDao().upsert(
giftWrapPayload.copy(
giftWrapSealId = sealedRumorEvent.id
)
)
logger.d("GiftWrap now sealed: ${giftWrapPayload.id}")
}
} }
} }
@@ -717,7 +717,7 @@ class DatabaseNostrRepository(
} }
override suspend fun scheduleBroadcastNostrEventRequests(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>) { override suspend fun scheduleBroadcastNostrEventRequests(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>) {
return database.broadcastNostrEventRequestDao().insert( database.broadcastNostrEventRequestDao().insert(
broadcastNostrEventRequests broadcastNostrEventRequests
) )
} }
@@ -25,6 +25,8 @@ import androidx.compose.material.icons.filled.AccessTime
import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.KeyOff import androidx.compose.material.icons.filled.KeyOff
import androidx.compose.material.icons.filled.LockClock import androidx.compose.material.icons.filled.LockClock
import androidx.compose.material.icons.filled.Pending
import androidx.compose.material.icons.filled.PendingActions
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@@ -229,7 +231,7 @@ class ChatRoomDetailMessageListViewModel(
) )
} else if (localChatMessage.chatMessageNostrEventRelation != null) { } else if (localChatMessage.chatMessageNostrEventRelation != null) {
Icon( Icon(
Icons.Default.LockClock, Icons.Default.Pending,
contentDescription = "Message signed and sealed status" contentDescription = "Message signed and sealed status"
) )
} else { } else {