Fix conversation persistence review issues

This commit is contained in:
callebtc 2026-07-29 14:43:13 +02:00
parent 172d086c23
commit a21c0242a6
4 changed files with 44 additions and 1 deletions

View File

@ -40,6 +40,10 @@ class ConversationNotificationReceiver : BroadcastReceiver() {
?.trim()
?.takeIf(String::isNotEmpty)
?: return@launch
// A notification can outlive the process/service that posted it. Promote
// the mesh runtime before dispatch so Android keeps the transport alive
// after this short-lived receiver finishes.
MeshForegroundService.start(context.applicationContext)
val mesh = MeshServiceHolder.getUnifiedOrCreate(
context.applicationContext
)

View File

@ -384,8 +384,11 @@ object AppStateStore {
}
if (changed) {
_privateMessages.value = map
conversationRepository?.updateDeliveryStatus(messageID, status)
}
// Full histories are unloaded after a chat closes, so the message may only exist in
// SQLite. Always offer the update to the repository; it safely ignores unknown IDs
// and enforces the same monotonic status rules as the in-memory path.
conversationRepository?.updateDeliveryStatus(messageID, status)
}
}

View File

@ -3,6 +3,7 @@ package com.bitchat.android.services
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.bitchat.android.model.BitchatMessage
import com.bitchat.android.model.DeliveryStatus
import com.bitchat.android.ui.ChatState
import com.bitchat.android.ui.DataManager
import com.bitchat.android.ui.MessageManager
@ -99,6 +100,40 @@ class IncomingMessageAdmissionTest {
)
}
@Test
fun `delivery receipt persists after older message is unloaded from memory`() {
val older = privateMessage(id = "older-outgoing").copy(
sender = "me",
senderPeerID = "self",
recipientNickname = "alice",
deliveryStatus = DeliveryStatus.Sent
)
val latest = privateMessage(id = "latest-summary").copy(timestamp = Date(2L))
assertTrue(AppStateStore.addPrivateMessage("peer-a", older, forceRead = true))
assertTrue(IncomingMessageAdmission.admitToAppState(latest))
runBlocking { repository.awaitPendingWrites() }
AppStateStore.releasePrivateConversationHistory("peer-a")
assertEquals(
listOf(latest.id),
AppStateStore.privateMessages.value.getValue("peer-a").map { it.id }
)
val delivered = DeliveryStatus.Delivered(to = "alice", at = Date(3L))
AppStateStore.updatePrivateMessageStatus(older.id, delivered)
runBlocking { repository.awaitPendingWrites() }
val snapshot = runBlocking {
repository.loadConversationAndWait("peer-a")
}
assertEquals(
delivered,
snapshot?.chats?.getValue("peer-a")
?.single { it.id == older.id }
?.deliveryStatus
)
}
@Test
fun `public and channel messages preserve best effort admission`() {
val public = BitchatMessage(

View File

@ -78,6 +78,7 @@ val sharedSourceIncludes = listOf(
"com/bitchat/android/services/ContactDirectory.kt",
"com/bitchat/android/services/ContactIdentityResolver.kt",
"com/bitchat/android/services/ConversationRepository.kt",
"com/bitchat/android/services/ConversationStorageCipher.kt",
"com/bitchat/android/services/PrivateMessageArrivalOrder.kt",
"com/bitchat/android/services/SeenMessageStore.kt",
"com/bitchat/android/services/VerificationService.kt",