diff --git a/app/src/main/java/com/geeksville/mesh/model/NodeDB.kt b/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt similarity index 73% rename from app/src/main/java/com/geeksville/mesh/model/NodeDB.kt rename to app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt index 8b5d0a602..7da648fe2 100644 --- a/app/src/main/java/com/geeksville/mesh/model/NodeDB.kt +++ b/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt @@ -15,32 +15,38 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.model +package com.geeksville.mesh.database import androidx.lifecycle.Lifecycle import androidx.lifecycle.coroutineScope +import com.geeksville.mesh.CoroutineDispatchers import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.database.dao.NodeInfoDao import com.geeksville.mesh.database.entity.MyNodeEntity import com.geeksville.mesh.database.entity.NodeEntity -import kotlinx.coroutines.Dispatchers +import com.geeksville.mesh.model.NodeSortOption import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Singleton @Singleton -class NodeDB @Inject constructor( +class NodeRepository @Inject constructor( processLifecycle: Lifecycle, private val nodeInfoDao: NodeInfoDao, + private val dispatchers: CoroutineDispatchers, ) { // hardware info about our local device (can be null) - private val _myNodeInfo = MutableStateFlow(null) - val myNodeInfo: StateFlow get() = _myNodeInfo + val myNodeInfo: StateFlow = nodeInfoDao.getMyNodeInfo() + .flowOn(dispatchers.io) + .stateIn(processLifecycle.coroutineScope, SharingStarted.Eagerly, null) // our node info private val _ourNodeInfo = MutableStateFlow(null) @@ -51,8 +57,15 @@ class NodeDB @Inject constructor( val myId: StateFlow get() = _myId // A map from nodeNum to NodeEntity - private val _nodeDBbyNum = MutableStateFlow>(mapOf()) - val nodeDBbyNum: StateFlow> get() = _nodeDBbyNum + val nodeDBbyNum: StateFlow> = nodeInfoDao.nodeDBbyNum() + .onEach { + val ourNodeInfo = it.values.firstOrNull() + _ourNodeInfo.value = ourNodeInfo + _myId.value = ourNodeInfo?.user?.id + } + .flowOn(dispatchers.io) + .conflate() + .stateIn(processLifecycle.coroutineScope, SharingStarted.Eagerly, emptyMap()) fun getUser(nodeNum: Int): MeshProtos.User = getUser(DataPacket.nodeNumToDefaultId(nodeNum)) @@ -65,18 +78,6 @@ class NodeDB @Inject constructor( .setHwModel(MeshProtos.HardwareModel.UNSET) .build() - init { - nodeInfoDao.getMyNodeInfo().onEach { _myNodeInfo.value = it } - .launchIn(processLifecycle.coroutineScope) - - nodeInfoDao.nodeDBbyNum().onEach { - _nodeDBbyNum.value = it - val ourNodeInfo = it.values.firstOrNull() - _ourNodeInfo.value = ourNodeInfo - _myId.value = ourNodeInfo?.user?.id - }.launchIn(processLifecycle.coroutineScope) - } - fun getNodes( sort: NodeSortOption = NodeSortOption.LAST_HEARD, filter: String = "", @@ -85,20 +86,20 @@ class NodeDB @Inject constructor( sort = sort.sqlValue, filter = filter, includeUnknown = includeUnknown, - ) + ).flowOn(dispatchers.io).conflate() - suspend fun upsert(node: NodeEntity) = withContext(Dispatchers.IO) { + suspend fun upsert(node: NodeEntity) = withContext(dispatchers.io) { nodeInfoDao.upsert(node) } - suspend fun installNodeDB(mi: MyNodeEntity, nodes: List) = withContext(Dispatchers.IO) { + suspend fun installNodeDB(mi: MyNodeEntity, nodes: List) = withContext(dispatchers.io) { nodeInfoDao.clearMyNodeInfo() nodeInfoDao.setMyNodeInfo(mi) // set MyNodeEntity first nodeInfoDao.clearNodeInfo() nodeInfoDao.putAll(nodes) } - suspend fun deleteNode(num: Int) = withContext(Dispatchers.IO) { + suspend fun deleteNode(num: Int) = withContext(dispatchers.io) { nodeInfoDao.deleteNode(num) } } 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 becaa056e..03e7b0f26 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -48,6 +48,7 @@ import com.geeksville.mesh.channelSettings import com.geeksville.mesh.config import com.geeksville.mesh.copy import com.geeksville.mesh.database.MeshLogRepository +import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.database.QuickChatActionRepository import com.geeksville.mesh.database.entity.MyNodeEntity @@ -165,7 +166,7 @@ data class Contact( @HiltViewModel class UIViewModel @Inject constructor( private val app: Application, - private val nodeDB: NodeDB, + private val nodeDB: NodeRepository, private val radioConfigRepository: RadioConfigRepository, private val radioInterfaceService: RadioInterfaceService, private val meshLogRepository: MeshLogRepository, diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt index 9e0c24daf..b50de2b1b 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt @@ -30,7 +30,7 @@ import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig import com.geeksville.mesh.database.entity.MyNodeEntity import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.deviceProfile -import com.geeksville.mesh.model.NodeDB +import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.model.getChannelUrl import com.geeksville.mesh.service.MeshService.ConnectionState import com.geeksville.mesh.service.ServiceAction @@ -48,7 +48,7 @@ import javax.inject.Inject */ class RadioConfigRepository @Inject constructor( private val serviceRepository: ServiceRepository, - private val nodeDB: NodeDB, + private val nodeDB: NodeRepository, private val channelSetRepository: ChannelSetRepository, private val localConfigRepository: LocalConfigRepository, private val moduleConfigRepository: ModuleConfigRepository,