Add message status logic

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

View File

@@ -25,5 +25,5 @@ interface BroadcastNostrEventRequestDao {
suspend fun upsert(broadcastNostrEventRequest: BroadcastNostrEventRequest)
@Insert
suspend fun insert(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>)
suspend fun insert(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>): LongArray
}

View File

@@ -16,6 +16,9 @@ interface ChatMessageDao {
@Query("SELECT * FROM ChatMessage WHERE chatRoomId = :chatRoomId ORDER BY createdAt DESC")
fun getChatMessagesByChatRoomId(chatRoomId: String): List<LocalChatMessage>
@Query("SELECT * FROM ChatMessage WHERE giftWrapPayloadId = :giftWrapPayloadId ORDER BY createdAt DESC")
fun getChatMessagesByGiftWrapPayloadId(giftWrapPayloadId: Long): ChatMessage?
@Upsert
suspend fun upsert(chatMessage: ChatMessage)
}

View File

@@ -3,8 +3,11 @@ package ac.cord.auxiliary.compose.database.dao
import ac.cord.auxiliary.compose.database.AuxDatabase
import ac.cord.auxiliary.compose.database.GENESIS_AT
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.GiftWrapMessage
import ac.cord.auxiliary.compose.database.model.GiftWrapPayload
import ac.cord.auxiliary.compose.database.model.GiftWrapSeal
import ac.cord.auxiliary.compose.database.model.NostrEvent
import ac.cord.auxiliary.compose.database.model.Participant
@@ -77,6 +80,7 @@ abstract class NostrNip17Dao(
@Transaction
open suspend fun persistAndBroadcastGiftWrap(
giftWrapPayload: Pair<Int, GiftWrapPayload>,
sealedRumorEvent: SealedRumorEvent,
giftWrapEvent: GiftWrapEvent,
receiverPublicKey: PTag
@@ -95,7 +99,18 @@ abstract class NostrNip17Dao(
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(
kinds = arrayOf(ChatMessageRelayListEvent.KIND),
authors = arrayOf(
@@ -118,10 +133,10 @@ abstract class NostrNip17Dao(
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 ->
logger.d("Submit BroadcastNostrEventRequest to $relayUrl")
database.broadcastNostrEventRequestDao().insert(
val broadcastNostrEventRequestIds = database.broadcastNostrEventRequestDao().insert(
listOf(
BroadcastNostrEventRequest(
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")
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 {

View File

@@ -2,6 +2,7 @@ package ac.cord.auxiliary.compose.database.repository
import ac.cord.auxiliary.compose.database.AuxDatabase
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.GiftWrapPayload
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatMessage
@@ -138,20 +139,14 @@ class DatabaseChatRepository(
logger.d("giftWrapEvent: ${giftWrapEvent.toJson()}")
database.nostrNip17Dao().persistAndBroadcastGiftWrap(
giftWrapPayload = Pair(
index,
giftWrapPayload
),
sealedRumorEvent = sealedRumorEvent,
giftWrapEvent = giftWrapEvent,
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}")
}
}
}

View File

@@ -717,7 +717,7 @@ class DatabaseNostrRepository(
}
override suspend fun scheduleBroadcastNostrEventRequests(broadcastNostrEventRequests: List<BroadcastNostrEventRequest>) {
return database.broadcastNostrEventRequestDao().insert(
database.broadcastNostrEventRequestDao().insert(
broadcastNostrEventRequests
)
}

View File

@@ -25,6 +25,8 @@ import androidx.compose.material.icons.filled.AccessTime
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.KeyOff
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.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
@@ -229,7 +231,7 @@ class ChatRoomDetailMessageListViewModel(
)
} else if (localChatMessage.chatMessageNostrEventRelation != null) {
Icon(
Icons.Default.LockClock,
Icons.Default.Pending,
contentDescription = "Message signed and sealed status"
)
} else {