mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat/decoupling (#4685)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
40244f8337
commit
2c49db8041
254 changed files with 5132 additions and 2666 deletions
|
|
@ -87,9 +87,8 @@ import org.meshtastic.core.common.gpsDisabled
|
|||
import org.meshtastic.core.common.util.DateFormatter
|
||||
import org.meshtastic.core.common.util.nowMillis
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.util.toString
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.calculating
|
||||
|
|
@ -344,7 +343,7 @@ fun MapView(
|
|||
|
||||
LaunchedEffect(selectedWaypointId, waypoints) {
|
||||
if (selectedWaypointId != null && waypoints.containsKey(selectedWaypointId)) {
|
||||
waypoints[selectedWaypointId]?.data?.waypoint?.let { pt ->
|
||||
waypoints[selectedWaypointId]?.waypoint?.let { pt ->
|
||||
val geoPoint = GeoPoint((pt.latitude_i ?: 0) * 1e-7, (pt.longitude_i ?: 0) * 1e-7)
|
||||
map.controller.setCenter(geoPoint)
|
||||
map.controller.setZoom(WAYPOINT_ZOOM)
|
||||
|
|
@ -496,7 +495,7 @@ fun MapView(
|
|||
fun showMarkerLongPressDialog(id: Int) {
|
||||
performHapticFeedback()
|
||||
Logger.d { "marker long pressed id=$id" }
|
||||
val waypoint = waypoints[id]?.data?.waypoint ?: return
|
||||
val waypoint = waypoints[id]?.waypoint ?: return
|
||||
// edit only when unlocked or lockedTo myNodeNum
|
||||
if ((waypoint.locked_to ?: 0) in setOf(0, mapViewModel.myNodeNum ?: 0) && isConnected) {
|
||||
showEditWaypointDialog = waypoint
|
||||
|
|
@ -512,13 +511,13 @@ fun MapView(
|
|||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun MapView.onWaypointChanged(waypoints: Collection<Packet>, selectedWaypointId: Int?): List<MarkerWithLabel> {
|
||||
fun MapView.onWaypointChanged(waypoints: Collection<DataPacket>, selectedWaypointId: Int?): List<MarkerWithLabel> {
|
||||
return waypoints.mapNotNull { waypoint ->
|
||||
val pt = waypoint.data.waypoint ?: return@mapNotNull null
|
||||
val pt = waypoint.waypoint ?: return@mapNotNull null
|
||||
if (!mapFilterState.showWaypoints) return@mapNotNull null // Use collected mapFilterState
|
||||
val lock = if ((pt.locked_to ?: 0) != 0) "\uD83D\uDD12" else ""
|
||||
val time = DateFormatter.formatDateTime(waypoint.received_time)
|
||||
val label = (pt.name ?: "") + " " + formatAgo((waypoint.received_time / 1000).toInt())
|
||||
val time = DateFormatter.formatDateTime(waypoint.time)
|
||||
val label = (pt.name ?: "") + " " + formatAgo((waypoint.time / 1000).toInt())
|
||||
val emoji = String(Character.toChars(if ((pt.icon ?: 0) == 0) 128205 else pt.icon!!))
|
||||
val now = nowMillis
|
||||
val expireTimeMillis = (pt.expire ?: 0) * 1000L
|
||||
|
|
@ -530,7 +529,7 @@ fun MapView(
|
|||
}
|
||||
MarkerWithLabel(this, label, emoji).apply {
|
||||
id = "${pt.id}"
|
||||
title = "${pt.name} (${getUsername(waypoint.data.from)}$lock)"
|
||||
title = "${pt.name} (${getUsername(waypoint.from)}$lock)"
|
||||
snippet = "[$time] ${pt.description} " + getString(Res.string.expires) + ": $expireTimeStr"
|
||||
position = GeoPoint((pt.latitude_i ?: 0) * 1e-7, (pt.longitude_i ?: 0) * 1e-7)
|
||||
if (selectedWaypointId == pt.id) {
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import org.meshtastic.core.common.BuildConfigProvider
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.navigation.MapRoutes
|
||||
import org.meshtastic.core.prefs.map.MapPrefs
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.proto.LocalConfig
|
||||
import javax.inject.Inject
|
||||
|
|
@ -41,12 +41,12 @@ class MapViewModel
|
|||
constructor(
|
||||
mapPrefs: MapPrefs,
|
||||
packetRepository: PacketRepository,
|
||||
private val nodeRepository: NodeRepository,
|
||||
serviceRepository: ServiceRepository,
|
||||
override val nodeRepository: NodeRepository,
|
||||
radioController: RadioController,
|
||||
radioConfigRepository: RadioConfigRepository,
|
||||
buildConfigProvider: BuildConfigProvider,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, serviceRepository) {
|
||||
) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, radioController) {
|
||||
|
||||
private val _selectedWaypointId = MutableStateFlow(savedStateHandle.toRoute<MapRoutes.Map>().waypointId)
|
||||
val selectedWaypointId: StateFlow<Int?> = _selectedWaypointId.asStateFlow()
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ import org.jetbrains.compose.resources.stringResource
|
|||
import org.json.JSONObject
|
||||
import org.meshtastic.core.common.util.nowMillis
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.util.metersIn
|
||||
import org.meshtastic.core.model.util.mpsToKmph
|
||||
import org.meshtastic.core.model.util.mpsToMph
|
||||
|
|
@ -272,7 +272,7 @@ fun MapView(
|
|||
|
||||
val allNodes by mapViewModel.nodesWithPosition.collectAsStateWithLifecycle(listOf())
|
||||
val waypoints by mapViewModel.waypoints.collectAsStateWithLifecycle(emptyMap())
|
||||
val displayableWaypoints = waypoints.values.mapNotNull { it.data.waypoint }
|
||||
val displayableWaypoints = waypoints.values.mapNotNull { it.waypoint }
|
||||
val selectedWaypointId by mapViewModel.selectedWaypointId.collectAsStateWithLifecycle()
|
||||
|
||||
val tracerouteSelection =
|
||||
|
|
|
|||
|
|
@ -45,14 +45,14 @@ import kotlinx.coroutines.withContext
|
|||
import kotlinx.serialization.Serializable
|
||||
import org.meshtastic.core.data.model.CustomTileProviderConfig
|
||||
import org.meshtastic.core.data.repository.CustomTileProviderRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.datastore.UiPreferencesDataSource
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.navigation.MapRoutes
|
||||
import org.meshtastic.core.prefs.map.GoogleMapsPrefs
|
||||
import org.meshtastic.core.prefs.map.MapPrefs
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.proto.Config
|
||||
import java.io.File
|
||||
|
|
@ -86,11 +86,11 @@ constructor(
|
|||
nodeRepository: NodeRepository,
|
||||
packetRepository: PacketRepository,
|
||||
radioConfigRepository: RadioConfigRepository,
|
||||
serviceRepository: ServiceRepository,
|
||||
radioController: RadioController,
|
||||
private val customTileProviderRepository: CustomTileProviderRepository,
|
||||
uiPreferencesDataSource: UiPreferencesDataSource,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, serviceRepository) {
|
||||
) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, radioController) {
|
||||
|
||||
private val _selectedWaypointId = MutableStateFlow(savedStateHandle.toRoute<MapRoutes.Map>().waypointId)
|
||||
val selectedWaypointId: StateFlow<Int?> = _selectedWaypointId.asStateFlow()
|
||||
|
|
@ -344,7 +344,7 @@ constructor(
|
|||
viewModelScope.launch {
|
||||
val wpMap = waypoints.first { it.containsKey(wpId) }
|
||||
wpMap[wpId]?.let { packet ->
|
||||
val waypoint = packet.data.waypoint!!
|
||||
val waypoint = packet.waypoint!!
|
||||
val latLng = LatLng((waypoint.latitude_i ?: 0) / 1e7, (waypoint.longitude_i ?: 0) / 1e7)
|
||||
cameraPositionState.position = CameraPosition.fromLatLngZoom(latLng, 15f)
|
||||
}
|
||||
|
|
@ -643,6 +643,9 @@ constructor(
|
|||
super.onCleared()
|
||||
(currentTileProvider as? MBTilesProvider)?.close()
|
||||
}
|
||||
|
||||
override fun getUser(userId: String?) =
|
||||
nodeRepository.getUser(userId ?: org.meshtastic.core.model.DataPacket.ID_BROADCAST)
|
||||
}
|
||||
|
||||
enum class LayerType {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.ui.component.NodeChip
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package org.meshtastic.feature.map.model
|
|||
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.maps.android.clustering.ClusterItem
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
|
||||
data class NodeClusterItem(
|
||||
val node: Node,
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@
|
|||
*/
|
||||
package org.meshtastic.feature.map
|
||||
|
||||
import android.os.RemoteException
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import co.touchlab.kermit.Logger
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -29,60 +27,45 @@ import kotlinx.coroutines.flow.mapLatest
|
|||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.model.util.TimeConstants
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.prefs.map.MapPrefs
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.any
|
||||
import org.meshtastic.core.resources.eight_hours
|
||||
import org.meshtastic.core.resources.one_day
|
||||
import org.meshtastic.core.resources.one_hour
|
||||
import org.meshtastic.core.resources.two_days
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.feature.map.model.TracerouteOverlay
|
||||
import org.meshtastic.proto.Position
|
||||
import org.meshtastic.proto.User
|
||||
import org.meshtastic.proto.Waypoint
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
sealed class LastHeardFilter(val seconds: Long, val label: StringResource) {
|
||||
data object Any : LastHeardFilter(0L, Res.string.any)
|
||||
|
||||
data object OneHour : LastHeardFilter(TimeConstants.ONE_HOUR.inWholeSeconds, Res.string.one_hour)
|
||||
|
||||
data object EightHours : LastHeardFilter(TimeConstants.EIGHT_HOURS.inWholeSeconds, Res.string.eight_hours)
|
||||
|
||||
data object OneDay : LastHeardFilter(TimeConstants.ONE_DAY.inWholeSeconds, Res.string.one_day)
|
||||
|
||||
data object TwoDays : LastHeardFilter(TimeConstants.TWO_DAYS.inWholeSeconds, Res.string.two_days)
|
||||
|
||||
companion object {
|
||||
fun fromSeconds(seconds: Long): LastHeardFilter = entries.find { it.seconds == seconds } ?: Any
|
||||
|
||||
val entries = listOf(Any, OneHour, EightHours, OneDay, TwoDays)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
abstract class BaseMapViewModel(
|
||||
protected val mapPrefs: MapPrefs,
|
||||
private val nodeRepository: NodeRepository,
|
||||
protected open val nodeRepository: NodeRepository,
|
||||
private val packetRepository: PacketRepository,
|
||||
private val serviceRepository: ServiceRepository,
|
||||
private val radioController: RadioController,
|
||||
) : ViewModel() {
|
||||
|
||||
val myNodeInfo = nodeRepository.myNodeInfo
|
||||
|
||||
val ourNodeInfo = nodeRepository.ourNodeInfo
|
||||
|
||||
val myNodeNum
|
||||
get() = myNodeInfo.value?.myNodeNum
|
||||
|
||||
val myId = nodeRepository.myId
|
||||
|
||||
val isConnected =
|
||||
radioController.connectionState
|
||||
.map { it is org.meshtastic.core.model.ConnectionState.Connected }
|
||||
.stateInWhileSubscribed(initialValue = false)
|
||||
|
||||
val nodes: StateFlow<List<Node>> =
|
||||
nodeRepository
|
||||
.getNodes()
|
||||
|
|
@ -94,79 +77,66 @@ abstract class BaseMapViewModel(
|
|||
.map { nodes -> nodes.filter { node -> node.validPosition != null } }
|
||||
.stateInWhileSubscribed(initialValue = emptyList())
|
||||
|
||||
val waypoints: StateFlow<Map<Int, Packet>> =
|
||||
val waypoints: StateFlow<Map<Int, DataPacket>> =
|
||||
packetRepository
|
||||
.getWaypoints()
|
||||
.mapLatest { list ->
|
||||
list
|
||||
.associateBy { packet -> packet.data.waypoint!!.id }
|
||||
.associateBy { packet -> packet.waypoint!!.id }
|
||||
.filterValues {
|
||||
val expire = it.data.waypoint!!.expire ?: 0
|
||||
val expire = it.waypoint?.expire ?: 0
|
||||
expire == 0 || expire.toLong() > nowSeconds
|
||||
}
|
||||
}
|
||||
.stateInWhileSubscribed(initialValue = emptyMap())
|
||||
|
||||
private val showOnlyFavorites = MutableStateFlow(mapPrefs.showOnlyFavorites)
|
||||
|
||||
private val showWaypointsOnMap = MutableStateFlow(mapPrefs.showWaypointsOnMap)
|
||||
|
||||
private val showPrecisionCircleOnMap = MutableStateFlow(mapPrefs.showPrecisionCircleOnMap)
|
||||
|
||||
private val lastHeardFilter = MutableStateFlow(LastHeardFilter.fromSeconds(mapPrefs.lastHeardFilter))
|
||||
|
||||
private val lastHeardTrackFilter = MutableStateFlow(LastHeardFilter.fromSeconds(mapPrefs.lastHeardTrackFilter))
|
||||
|
||||
fun setLastHeardFilter(filter: LastHeardFilter) {
|
||||
mapPrefs.lastHeardFilter = filter.seconds
|
||||
lastHeardFilter.value = filter
|
||||
}
|
||||
|
||||
fun setLastHeardTrackFilter(filter: LastHeardFilter) {
|
||||
mapPrefs.lastHeardTrackFilter = filter.seconds
|
||||
lastHeardTrackFilter.value = filter
|
||||
}
|
||||
|
||||
val ourNodeInfo: StateFlow<Node?> = nodeRepository.ourNodeInfo
|
||||
|
||||
fun getNodeByNum(nodeNum: Int): Node? = nodeRepository.nodeDBbyNum.value[nodeNum]
|
||||
|
||||
open fun getUser(userId: String?): User = nodeRepository.getUser(userId ?: DataPacket.ID_BROADCAST)
|
||||
|
||||
fun getUser(nodeNum: Int): User = nodeRepository.getUser(nodeNum)
|
||||
|
||||
fun getNodeOrFallback(nodeNum: Int): Node = getNodeByNum(nodeNum) ?: Node(num = nodeNum, user = getUser(nodeNum))
|
||||
|
||||
val isConnected =
|
||||
serviceRepository.connectionState.map { it.isConnected() }.stateInWhileSubscribed(initialValue = false)
|
||||
val showOnlyFavoritesOnMap = showOnlyFavorites
|
||||
|
||||
fun toggleOnlyFavorites() {
|
||||
val current = showOnlyFavorites.value
|
||||
mapPrefs.showOnlyFavorites = !current
|
||||
showOnlyFavorites.value = !current
|
||||
val newValue = !showOnlyFavorites.value
|
||||
showOnlyFavorites.value = newValue
|
||||
mapPrefs.showOnlyFavorites = newValue
|
||||
}
|
||||
|
||||
private val showWaypoints = MutableStateFlow(mapPrefs.showWaypointsOnMap)
|
||||
val showWaypointsOnMap = showWaypoints
|
||||
|
||||
fun toggleShowWaypointsOnMap() {
|
||||
val current = showWaypointsOnMap.value
|
||||
mapPrefs.showWaypointsOnMap = !current
|
||||
showWaypointsOnMap.value = !current
|
||||
val newValue = !showWaypoints.value
|
||||
showWaypoints.value = newValue
|
||||
mapPrefs.showWaypointsOnMap = newValue
|
||||
}
|
||||
|
||||
private val showPrecisionCircle = MutableStateFlow(mapPrefs.showPrecisionCircleOnMap)
|
||||
val showPrecisionCircleOnMap = showPrecisionCircle
|
||||
|
||||
fun toggleShowPrecisionCircleOnMap() {
|
||||
val current = showPrecisionCircleOnMap.value
|
||||
mapPrefs.showPrecisionCircleOnMap = !current
|
||||
showPrecisionCircleOnMap.value = !current
|
||||
val newValue = !showPrecisionCircle.value
|
||||
showPrecisionCircle.value = newValue
|
||||
mapPrefs.showPrecisionCircleOnMap = newValue
|
||||
}
|
||||
|
||||
fun generatePacketId(): Int? {
|
||||
return try {
|
||||
serviceRepository.meshService?.packetId
|
||||
} catch (ex: RemoteException) {
|
||||
Logger.e { "RemoteException: ${ex.message}" }
|
||||
return null
|
||||
}
|
||||
private val lastHeardFilterValue = MutableStateFlow(LastHeardFilter.fromSeconds(mapPrefs.lastHeardFilter))
|
||||
val lastHeardFilter = lastHeardFilterValue
|
||||
|
||||
fun setLastHeardFilter(filter: LastHeardFilter) {
|
||||
lastHeardFilterValue.value = filter
|
||||
mapPrefs.lastHeardFilter = filter.seconds
|
||||
}
|
||||
|
||||
private val lastHeardTrackFilterValue = MutableStateFlow(LastHeardFilter.fromSeconds(mapPrefs.lastHeardTrackFilter))
|
||||
val lastHeardTrackFilter = lastHeardTrackFilterValue
|
||||
|
||||
fun setLastHeardTrackFilter(filter: LastHeardFilter) {
|
||||
lastHeardTrackFilterValue.value = filter
|
||||
mapPrefs.lastHeardTrackFilter = filter.seconds
|
||||
}
|
||||
|
||||
abstract fun getUser(userId: String?): org.meshtastic.proto.User
|
||||
|
||||
fun getNodeOrFallback(nodeNum: Int): Node = nodeRepository.nodeDBbyNum.value[nodeNum] ?: Node(num = nodeNum)
|
||||
|
||||
fun deleteWaypoint(id: Int) = viewModelScope.launch(Dispatchers.IO) { packetRepository.deleteWaypoint(id) }
|
||||
|
||||
fun sendWaypoint(wpt: Waypoint, contactKey: String = "0${DataPacket.ID_BROADCAST}") {
|
||||
|
|
@ -179,13 +149,11 @@ abstract class BaseMapViewModel(
|
|||
}
|
||||
|
||||
private fun sendDataPacket(p: DataPacket) {
|
||||
try {
|
||||
serviceRepository.meshService?.send(p)
|
||||
} catch (ex: RemoteException) {
|
||||
Logger.e { "Send DataPacket error: ${ex.message}" }
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) { radioController.sendMessage(p) }
|
||||
}
|
||||
|
||||
fun generatePacketId(): Int = radioController.getPacketId()
|
||||
|
||||
data class MapFilterState(
|
||||
val onlyFavorites: Boolean,
|
||||
val showWaypoints: Boolean,
|
||||
|
|
@ -259,3 +227,17 @@ fun BaseMapViewModel.tracerouteNodeSelection(
|
|||
nodeLookup = nodesForLookup.associateBy { it.num },
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
enum class LastHeardFilter(val label: StringResource, val seconds: Long) {
|
||||
Any(Res.string.any, 0L),
|
||||
OneHour(Res.string.one_hour, 3600L),
|
||||
EightHours(Res.string.eight_hours, 28800L),
|
||||
OneDay(Res.string.one_day, 86400L),
|
||||
TwoDays(Res.string.two_days, 172800L),
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun fromSeconds(seconds: Long): LastHeardFilter = entries.find { it.seconds == seconds } ?: Any
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ import kotlinx.coroutines.flow.mapLatest
|
|||
import kotlinx.coroutines.flow.toList
|
||||
import org.meshtastic.core.common.BuildConfigProvider
|
||||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.entity.MeshLog
|
||||
import org.meshtastic.core.navigation.NodesRoutes
|
||||
import org.meshtastic.core.prefs.map.MapPrefs
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.ui.util.toPosition
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.feature.map.model.CustomTileSource
|
||||
|
|
|
|||
|
|
@ -40,14 +40,14 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.meshtastic.core.data.model.CustomTileProviderConfig
|
||||
import org.meshtastic.core.data.repository.CustomTileProviderRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.datastore.UiPreferencesDataSource
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.prefs.map.GoogleMapsPrefs
|
||||
import org.meshtastic.core.prefs.map.MapPrefs
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
|
@ -60,7 +60,7 @@ class MapViewModelTest {
|
|||
private val nodeRepository = mockk<NodeRepository>(relaxed = true)
|
||||
private val packetRepository = mockk<PacketRepository>(relaxed = true)
|
||||
private val radioConfigRepository = mockk<RadioConfigRepository>(relaxed = true)
|
||||
private val serviceRepository = mockk<ServiceRepository>(relaxed = true)
|
||||
private val radioController = mockk<RadioController>(relaxed = true)
|
||||
private val customTileProviderRepository = mockk<CustomTileProviderRepository>(relaxed = true)
|
||||
private val uiPreferencesDataSource = mockk<UiPreferencesDataSource>(relaxed = true)
|
||||
private val savedStateHandle = SavedStateHandle(mapOf("waypointId" to null))
|
||||
|
|
@ -81,7 +81,7 @@ class MapViewModelTest {
|
|||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(emptyMap())
|
||||
every { nodeRepository.getNodes() } returns flowOf(emptyList())
|
||||
every { packetRepository.getWaypoints() } returns flowOf(emptyList())
|
||||
every { serviceRepository.connectionState } returns MutableStateFlow(ConnectionState.Disconnected)
|
||||
every { radioController.connectionState } returns MutableStateFlow(ConnectionState.Disconnected)
|
||||
|
||||
viewModel =
|
||||
MapViewModel(
|
||||
|
|
@ -91,7 +91,7 @@ class MapViewModelTest {
|
|||
nodeRepository,
|
||||
packetRepository,
|
||||
radioConfigRepository,
|
||||
serviceRepository,
|
||||
radioController,
|
||||
customTileProviderRepository,
|
||||
uiPreferencesDataSource,
|
||||
savedStateHandle,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue