mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
fix: Fetch original message when displaying a reply (#2152)
This commit is contained in:
parent
0799122c9e
commit
468c4ab6b7
6 changed files with 40 additions and 12 deletions
|
|
@ -24,8 +24,10 @@ import com.geeksville.mesh.database.dao.PacketDao
|
|||
import com.geeksville.mesh.database.entity.ContactSettings
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import com.geeksville.mesh.database.entity.ReactionEntity
|
||||
import com.geeksville.mesh.model.Node
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -58,7 +60,19 @@ class PacketRepository @Inject constructor(private val packetDaoLazy: dagger.Laz
|
|||
packetDao.insert(packet)
|
||||
}
|
||||
|
||||
fun getMessagesFrom(contact: String) = packetDao.getMessagesFrom(contact)
|
||||
suspend fun getMessagesFrom(contact: String, getNode: suspend (String?) -> Node) =
|
||||
withContext(Dispatchers.IO) {
|
||||
packetDao.getMessagesFrom(contact).mapLatest { packets ->
|
||||
packets.map { packet ->
|
||||
val message = packet.toMessage(getNode)
|
||||
message.replyId.takeIf { it != null && it != 0 }
|
||||
?.let { getPacketByPacketId(it) }
|
||||
?.toMessage(getNode)
|
||||
?.let { originalMessage -> message.copy(originalMessage = originalMessage) }
|
||||
?: message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateMessageStatus(d: DataPacket, m: MessageStatus) = withContext(Dispatchers.IO) {
|
||||
packetDao.updateMessageStatus(d, m)
|
||||
|
|
@ -72,6 +86,10 @@ class PacketRepository @Inject constructor(private val packetDaoLazy: dagger.Laz
|
|||
packetDao.getPacketById(requestId)
|
||||
}
|
||||
|
||||
suspend fun getPacketByPacketId(packetId: Int) = withContext(Dispatchers.IO) {
|
||||
packetDao.getPacketByPacketId(packetId)
|
||||
}
|
||||
|
||||
suspend fun deleteMessages(uuidList: List<Long>) = withContext(Dispatchers.IO) {
|
||||
for (chunk in uuidList.chunked(500)) { // limit number of UUIDs per query
|
||||
packetDao.deleteMessages(chunk)
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ package com.geeksville.mesh.database.dao
|
|||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.MapColumn
|
||||
import androidx.room.Update
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import androidx.room.Upsert
|
||||
import com.geeksville.mesh.DataPacket
|
||||
import com.geeksville.mesh.MessageStatus
|
||||
import com.geeksville.mesh.database.entity.ContactSettings
|
||||
import com.geeksville.mesh.database.entity.PacketEntity
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import com.geeksville.mesh.database.entity.PacketEntity
|
||||
import com.geeksville.mesh.database.entity.ReactionEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
|
@ -174,6 +174,9 @@ interface PacketDao {
|
|||
)
|
||||
suspend fun getPacketById(requestId: Int): Packet?
|
||||
|
||||
@Query("SELECT * FROM packet WHERE packet_id = :packetId LIMIT 1")
|
||||
suspend fun getPacketByPacketId(packetId: Int): PacketEntity?
|
||||
|
||||
@Transaction
|
||||
suspend fun getQueuedPackets(): List<DataPacket>? =
|
||||
getDataPackets().filter { it.status == MessageStatus.QUEUED }
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ data class Message(
|
|||
val rssi: Int,
|
||||
val hopsAway: Int,
|
||||
val replyId: Int?,
|
||||
val originalMessage: Message? = null,
|
||||
) {
|
||||
fun getStatusStringRes(): Pair<Int, Int> {
|
||||
val title = if (routingError > 0) R.string.error else R.string.message_delivery_status
|
||||
|
|
|
|||
|
|
@ -517,8 +517,20 @@ class UIViewModel @Inject constructor(
|
|||
initialValue = emptyList(),
|
||||
)
|
||||
|
||||
fun getMessagesFrom(contactKey: String) = packetRepository.getMessagesFrom(contactKey)
|
||||
.mapLatest { list -> list.map { it.toMessage(::getNode) } }
|
||||
fun getMessagesFrom(contactKey: String): StateFlow<List<Message>> {
|
||||
_contactKeyForMessages.value = contactKey
|
||||
return messagesForContactKey
|
||||
}
|
||||
|
||||
private val _contactKeyForMessages: MutableStateFlow<String?> = MutableStateFlow(null)
|
||||
private val messagesForContactKey: StateFlow<List<Message>> =
|
||||
_contactKeyForMessages.filterNotNull().flatMapLatest { contactKey ->
|
||||
packetRepository.getMessagesFrom(contactKey, ::getNode)
|
||||
}.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5_000),
|
||||
initialValue = emptyList(),
|
||||
)
|
||||
|
||||
val waypoints = packetRepository.getWaypoints().mapLatest { list ->
|
||||
list.associateBy { packet -> packet.data.waypoint!!.id }
|
||||
|
|
|
|||
|
|
@ -171,10 +171,6 @@ internal fun MessageList(
|
|||
var node by remember {
|
||||
mutableStateOf(nodes.find { it.num == msg.node.num } ?: msg.node)
|
||||
}
|
||||
val originalMessage = messages.find { it.packetId == msg.replyId }
|
||||
LaunchedEffect(nodes, messages) {
|
||||
node = nodes.find { it.num == msg.node.num } ?: msg.node
|
||||
}
|
||||
MessageItem(
|
||||
node = node,
|
||||
ourNode = ourNode!!,
|
||||
|
|
@ -192,7 +188,6 @@ internal fun MessageList(
|
|||
sendReaction = { onSendReaction(it, msg.packetId) },
|
||||
onShowReactions = { showReactionDialog = msg.emojis },
|
||||
isConnected = isConnected,
|
||||
originalMessage = originalMessage,
|
||||
onNavigateToOriginalMessage = {
|
||||
coroutineScope.launch {
|
||||
listState.animateScrollToItem(
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ internal fun MessageItem(
|
|||
onAction: (NodeMenuAction) -> Unit = {},
|
||||
onStatusClick: () -> Unit = {},
|
||||
isConnected: Boolean,
|
||||
originalMessage: Message? = null,
|
||||
onNavigateToOriginalMessage: (Int) -> Unit = {},
|
||||
) = Column(
|
||||
modifier = modifier
|
||||
|
|
@ -124,7 +123,7 @@ internal fun MessageItem(
|
|||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
if (originalMessage != null) {
|
||||
message.originalMessage?.let { originalMessage ->
|
||||
val originalMessageIsFromLocal = originalMessage.node.user.id == DataPacket.ID_LOCAL
|
||||
val originalMessageNode =
|
||||
if (originalMessageIsFromLocal) ourNode else originalMessage.node
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue