refactor: finish transition from `NodeInfo` to `NodeEntity`

pull/1307/head
andrekir 2024-10-12 07:05:25 -03:00
rodzic ed2703c77a
commit b503c10789
5 zmienionych plików z 36 dodań i 21 usunięć

Wyświetl plik

@ -4,6 +4,7 @@ import android.graphics.Color
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig
import com.geeksville.mesh.DeviceMetrics import com.geeksville.mesh.DeviceMetrics
import com.geeksville.mesh.EnvironmentMetrics import com.geeksville.mesh.EnvironmentMetrics
import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.MeshProtos
@ -13,7 +14,10 @@ import com.geeksville.mesh.PaxcountProtos
import com.geeksville.mesh.Position import com.geeksville.mesh.Position
import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.TelemetryProtos
import com.geeksville.mesh.copy import com.geeksville.mesh.copy
import com.geeksville.mesh.util.bearing
import com.geeksville.mesh.util.GPSFormat
import com.geeksville.mesh.util.latLongToMeter import com.geeksville.mesh.util.latLongToMeter
import com.geeksville.mesh.util.toDistanceString
import com.google.protobuf.ByteString import com.google.protobuf.ByteString
@Suppress("MagicNumber") @Suppress("MagicNumber")
@ -108,6 +112,26 @@ data class NodeEntity(
else latLongToMeter(latitude, longitude, o.latitude, o.longitude).toInt() else latLongToMeter(latitude, longitude, o.latitude, o.longitude).toInt()
} }
// @return a nice human readable string for the distance, or null for unknown
fun distanceStr(o: NodeEntity, displayUnits: Int = 0): String? = distance(o)?.let { dist ->
val system = DisplayConfig.DisplayUnits.forNumber(displayUnits)
return if (dist > 0) dist.toDistanceString(system) else null
}
// @return bearing to the other position in degrees
fun bearing(o: NodeEntity?): Int? {
return if (validPosition == null || o?.validPosition == null) null
else bearing(latitude, longitude, o.latitude, o.longitude).toInt()
}
fun gpsString(gpsFormat: Int): String = when (gpsFormat) {
DisplayConfig.GpsCoordinateFormat.DEC_VALUE -> GPSFormat.toDEC(latitude, longitude)
DisplayConfig.GpsCoordinateFormat.DMS_VALUE -> GPSFormat.toDMS(latitude, longitude)
DisplayConfig.GpsCoordinateFormat.UTM_VALUE -> GPSFormat.toUTM(latitude, longitude)
DisplayConfig.GpsCoordinateFormat.MGRS_VALUE -> GPSFormat.toMGRS(latitude, longitude)
else -> GPSFormat.toDEC(latitude, longitude)
}
private fun TelemetryProtos.EnvironmentMetrics.getDisplayString(isFahrenheit: Boolean): String { private fun TelemetryProtos.EnvironmentMetrics.getDisplayString(isFahrenheit: Boolean): String {
val temp = if (temperature != 0f) { val temp = if (temperature != 0f) {
if (isFahrenheit) { if (isFahrenheit) {

Wyświetl plik

@ -186,8 +186,8 @@ class UIViewModel @Inject constructor(
private val _quickChatActions = MutableStateFlow<List<QuickChatAction>>(emptyList()) private val _quickChatActions = MutableStateFlow<List<QuickChatAction>>(emptyList())
val quickChatActions: StateFlow<List<QuickChatAction>> = _quickChatActions val quickChatActions: StateFlow<List<QuickChatAction>> = _quickChatActions
private val _focusedNode = MutableStateFlow<NodeInfo?>(null) private val _focusedNode = MutableStateFlow<NodeEntity?>(null)
val focusedNode: StateFlow<NodeInfo?> = _focusedNode val focusedNode: StateFlow<NodeEntity?> = _focusedNode
private val nodeFilterText = MutableStateFlow("") private val nodeFilterText = MutableStateFlow("")
private val nodeSortOption = MutableStateFlow(NodeSortOption.LAST_HEARD) private val nodeSortOption = MutableStateFlow(NodeSortOption.LAST_HEARD)
@ -747,7 +747,7 @@ class UIViewModel @Inject constructor(
_currentTab.value = tab _currentTab.value = tab
} }
fun focusUserNode(node: NodeInfo?) { fun focusUserNode(node: NodeEntity?) {
_currentTab.value = 1 _currentTab.value = 1
_focusedNode.value = node _focusedNode.value = node
} }

Wyświetl plik

@ -26,7 +26,6 @@ import com.geeksville.mesh.DataPacket
import com.geeksville.mesh.android.Logging import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.R import com.geeksville.mesh.R
import com.geeksville.mesh.database.entity.QuickChatAction import com.geeksville.mesh.database.entity.QuickChatAction
import com.geeksville.mesh.database.entity.toNodeInfo
import com.geeksville.mesh.databinding.MessagesFragmentBinding import com.geeksville.mesh.databinding.MessagesFragmentBinding
import com.geeksville.mesh.model.Message import com.geeksville.mesh.model.Message
import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.model.UIViewModel
@ -297,7 +296,7 @@ class MessagesFragment : Fragment(), Logging {
private fun openNodeInfo(msg: Message) = lifecycleScope.launch { private fun openNodeInfo(msg: Message) = lifecycleScope.launch {
model.nodeList.firstOrNull()?.find { it.user.id == msg.user.id }?.let { node -> model.nodeList.firstOrNull()?.find { it.user.id == msg.user.id }?.let { node ->
parentFragmentManager.popBackStack() parentFragmentManager.popBackStack()
model.focusUserNode(node.toNodeInfo()) model.focusUserNode(node)
} }
} }
} }

Wyświetl plik

@ -26,7 +26,6 @@ import com.geeksville.mesh.DataPacket
import com.geeksville.mesh.R import com.geeksville.mesh.R
import com.geeksville.mesh.android.Logging import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.database.entity.toNodeInfo
import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.components.NodeFilterTextField import com.geeksville.mesh.ui.components.NodeFilterTextField
import com.geeksville.mesh.ui.components.rememberTimeTickWithLifecycle import com.geeksville.mesh.ui.components.rememberTimeTickWithLifecycle
@ -175,7 +174,6 @@ fun NodesScreen(
} }
items(nodes, key = { it.num }) { node -> items(nodes, key = { it.num }) { node ->
val nodeInfo = node.toNodeInfo()
NodeItem( NodeItem(
thisNode = ourNode, thisNode = ourNode,
thatNode = node, thatNode = node,
@ -187,7 +185,7 @@ fun NodesScreen(
focusManager.clearFocus() focusManager.clearFocus()
chipClicked(node) chipClicked(node)
}, },
blinking = nodeInfo == focusedNode, blinking = node == focusedNode,
expanded = state.showDetails, expanded = state.showDetails,
currentTimeMillis = currentTimeMillis, currentTimeMillis = currentTimeMillis,
) )

Wyświetl plik

@ -38,7 +38,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.geeksville.mesh.BuildConfig import com.geeksville.mesh.BuildConfig
import com.geeksville.mesh.DataPacket import com.geeksville.mesh.DataPacket
import com.geeksville.mesh.MeshProtos.Waypoint import com.geeksville.mesh.MeshProtos.Waypoint
import com.geeksville.mesh.NodeInfo
import com.geeksville.mesh.R import com.geeksville.mesh.R
import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.android.BuildUtils.debug
import com.geeksville.mesh.android.Logging import com.geeksville.mesh.android.Logging
@ -47,8 +46,8 @@ import com.geeksville.mesh.android.gpsDisabled
import com.geeksville.mesh.android.hasGps import com.geeksville.mesh.android.hasGps
import com.geeksville.mesh.android.hasLocationPermission import com.geeksville.mesh.android.hasLocationPermission
import com.geeksville.mesh.copy import com.geeksville.mesh.copy
import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.database.entity.Packet import com.geeksville.mesh.database.entity.Packet
import com.geeksville.mesh.database.entity.toNodeInfo
import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.model.map.CustomTileSource import com.geeksville.mesh.model.map.CustomTileSource
import com.geeksville.mesh.model.map.MarkerWithLabel import com.geeksville.mesh.model.map.MarkerWithLabel
@ -61,8 +60,6 @@ import com.geeksville.mesh.util.zoomIn
import com.geeksville.mesh.waypoint import com.geeksville.mesh.waypoint
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.mapLatest
import org.osmdroid.bonuspack.utils.BonusPackHelper.getBitmapFromVectorDrawable import org.osmdroid.bonuspack.utils.BonusPackHelper.getBitmapFromVectorDrawable
import org.osmdroid.config.Configuration import org.osmdroid.config.Configuration
import org.osmdroid.events.DelayedMapListener import org.osmdroid.events.DelayedMapListener
@ -330,10 +327,7 @@ fun MapView(
if (permissions.entries.all { it.value }) map.toggleMyLocation() if (permissions.entries.all { it.value }) map.toggleMyLocation()
} }
@OptIn(ExperimentalCoroutinesApi::class) val nodes by model.nodeList.collectAsStateWithLifecycle()
val nodes by model.nodeList
.mapLatest { list -> list.map { it.toNodeInfo() } }
.collectAsStateWithLifecycle(emptyList())
val waypoints by model.waypoints.collectAsStateWithLifecycle(emptyMap()) val waypoints by model.waypoints.collectAsStateWithLifecycle(emptyMap())
var showDownloadButton: Boolean by remember { mutableStateOf(false) } var showDownloadButton: Boolean by remember { mutableStateOf(false) }
@ -344,21 +338,21 @@ fun MapView(
AppCompatResources.getDrawable(context, R.drawable.ic_baseline_location_on_24) AppCompatResources.getDrawable(context, R.drawable.ic_baseline_location_on_24)
} }
fun MapView.onNodesChanged(nodes: Collection<NodeInfo>): List<MarkerWithLabel> { fun MapView.onNodesChanged(nodes: Collection<NodeEntity>): List<MarkerWithLabel> {
val nodesWithPosition = nodes.filter { it.validPosition != null } val nodesWithPosition = nodes.filter { it.validPosition != null }
val ourNode = model.ourNodeInfo.value?.toNodeInfo() val ourNode = model.ourNodeInfo.value
val gpsFormat = model.config.display.gpsFormat.number val gpsFormat = model.config.display.gpsFormat.number
val displayUnits = model.config.display.units.number val displayUnits = model.config.display.units.number
return nodesWithPosition.map { node -> return nodesWithPosition.map { node ->
val (p, u) = node.position!! to node.user!! val (p, u) = node.position to node.user
val nodePosition = GeoPoint(p.latitude, p.longitude) val nodePosition = GeoPoint(node.latitude, node.longitude)
MarkerWithLabel( MarkerWithLabel(
mapView = this, mapView = this,
label = "${u.shortName} ${formatAgo(p.time)}" label = "${u.shortName} ${formatAgo(p.time)}"
).apply { ).apply {
id = u.id id = u.id
title = "${u.longName} ${node.batteryStr}" title = "${u.longName} ${node.batteryStr}"
snippet = p.gpsString(gpsFormat) snippet = node.gpsString(gpsFormat)
ourNode?.distanceStr(node, displayUnits)?.let { dist -> ourNode?.distanceStr(node, displayUnits)?.let { dist ->
subDescription = subDescription =
context.getString(R.string.map_subDescription, ourNode.bearing(node), dist) context.getString(R.string.map_subDescription, ourNode.bearing(node), dist)