diff --git a/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt b/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt index e9ccb341e..a6b61d643 100644 --- a/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt @@ -18,6 +18,8 @@ class PacketRepository @Inject constructor(private val packetDaoLazy: dagger.Laz packetDao.getAllPackets() } + fun getContacts(): Flow> = packetDao.getContactKeys() + suspend fun getQueuedPackets(): List? = withContext(Dispatchers.IO) { packetDao.getQueuedPackets() } diff --git a/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt b/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt index 2b159289c..5d7ae134e 100644 --- a/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt +++ b/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt @@ -2,6 +2,7 @@ package com.geeksville.mesh.database.dao import androidx.room.Dao import androidx.room.Insert +import androidx.room.MapColumn import androidx.room.Update import androidx.room.Query import androidx.room.Transaction @@ -16,6 +17,9 @@ interface PacketDao { @Query("Select * from packet order by received_time asc") fun getAllPackets(): Flow> + @Query("Select * from packet where port_num = 1 order by received_time desc") + fun getContactKeys(): Flow> + @Insert fun insert(packet: Packet) diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index 8a4a9f038..a2e230f2a 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -198,9 +198,14 @@ class UIViewModel @Inject constructor( }.asLiveData() @OptIn(ExperimentalCoroutinesApi::class) - val contacts: LiveData> = _packets.mapLatest { list -> - list.filter { it.port_num == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE } - .associateBy { packet -> packet.contact_key } + val contacts: LiveData> = packetRepository.getContacts().mapLatest { + // Add empty channel placeholders (always show Broadcast contacts, even when empty) + val placeholder = (0 until channelSet.settingsCount).associate { ch -> + val contactKey = "$ch${DataPacket.ID_BROADCAST}" + val data = DataPacket(bytes = null, dataType = 1, time = 0L, channel = ch) + contactKey to Packet(0L, 1, contactKey, 0L, data) + } + it + (placeholder - it.keys) }.asLiveData() @OptIn(ExperimentalCoroutinesApi::class) diff --git a/app/src/main/java/com/geeksville/mesh/ui/ContactsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/ContactsFragment.kt index 6939690ac..fd16f3ce1 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/ContactsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/ContactsFragment.kt @@ -171,16 +171,7 @@ class ContactsFragment : ScreenFragment("Messages"), Logging { } fun onContactsChanged(contacts: Map) { - // Add empty channel placeholders (always show Broadcast contacts, even when empty) - val mutableMap = contacts.toMutableMap() - for (ch in 0 until model.channelSet.settingsCount) { - val contactKey = "$ch${DataPacket.ID_BROADCAST}" - if (mutableMap[contactKey] == null) mutableMap[contactKey] = Packet( - 0L, 1, contactKey, 0L, - DataPacket(bytes = null, dataType = 1, time = 0L, channel = ch) - ) - } - this.contacts = mutableMap.values.sortedByDescending { it.received_time }.toTypedArray() + this.contacts = contacts.values.toTypedArray() notifyDataSetChanged() // FIXME, this is super expensive and redraws all nodes }