kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor: finish transition from `NodeInfo` to `NodeEntity`
rodzic
ed2703c77a
commit
b503c10789
|
@ -4,6 +4,7 @@ import android.graphics.Color
|
|||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig
|
||||
import com.geeksville.mesh.DeviceMetrics
|
||||
import com.geeksville.mesh.EnvironmentMetrics
|
||||
import com.geeksville.mesh.MeshProtos
|
||||
|
@ -13,7 +14,10 @@ import com.geeksville.mesh.PaxcountProtos
|
|||
import com.geeksville.mesh.Position
|
||||
import com.geeksville.mesh.TelemetryProtos
|
||||
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.toDistanceString
|
||||
import com.google.protobuf.ByteString
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
|
@ -108,6 +112,26 @@ data class NodeEntity(
|
|||
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 {
|
||||
val temp = if (temperature != 0f) {
|
||||
if (isFahrenheit) {
|
||||
|
|
|
@ -186,8 +186,8 @@ class UIViewModel @Inject constructor(
|
|||
private val _quickChatActions = MutableStateFlow<List<QuickChatAction>>(emptyList())
|
||||
val quickChatActions: StateFlow<List<QuickChatAction>> = _quickChatActions
|
||||
|
||||
private val _focusedNode = MutableStateFlow<NodeInfo?>(null)
|
||||
val focusedNode: StateFlow<NodeInfo?> = _focusedNode
|
||||
private val _focusedNode = MutableStateFlow<NodeEntity?>(null)
|
||||
val focusedNode: StateFlow<NodeEntity?> = _focusedNode
|
||||
|
||||
private val nodeFilterText = MutableStateFlow("")
|
||||
private val nodeSortOption = MutableStateFlow(NodeSortOption.LAST_HEARD)
|
||||
|
@ -747,7 +747,7 @@ class UIViewModel @Inject constructor(
|
|||
_currentTab.value = tab
|
||||
}
|
||||
|
||||
fun focusUserNode(node: NodeInfo?) {
|
||||
fun focusUserNode(node: NodeEntity?) {
|
||||
_currentTab.value = 1
|
||||
_focusedNode.value = node
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import com.geeksville.mesh.DataPacket
|
|||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.database.entity.QuickChatAction
|
||||
import com.geeksville.mesh.database.entity.toNodeInfo
|
||||
import com.geeksville.mesh.databinding.MessagesFragmentBinding
|
||||
import com.geeksville.mesh.model.Message
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
|
@ -297,7 +296,7 @@ class MessagesFragment : Fragment(), Logging {
|
|||
private fun openNodeInfo(msg: Message) = lifecycleScope.launch {
|
||||
model.nodeList.firstOrNull()?.find { it.user.id == msg.user.id }?.let { node ->
|
||||
parentFragmentManager.popBackStack()
|
||||
model.focusUserNode(node.toNodeInfo())
|
||||
model.focusUserNode(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import com.geeksville.mesh.DataPacket
|
|||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.database.entity.NodeEntity
|
||||
import com.geeksville.mesh.database.entity.toNodeInfo
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.ui.components.NodeFilterTextField
|
||||
import com.geeksville.mesh.ui.components.rememberTimeTickWithLifecycle
|
||||
|
@ -175,7 +174,6 @@ fun NodesScreen(
|
|||
}
|
||||
|
||||
items(nodes, key = { it.num }) { node ->
|
||||
val nodeInfo = node.toNodeInfo()
|
||||
NodeItem(
|
||||
thisNode = ourNode,
|
||||
thatNode = node,
|
||||
|
@ -187,7 +185,7 @@ fun NodesScreen(
|
|||
focusManager.clearFocus()
|
||||
chipClicked(node)
|
||||
},
|
||||
blinking = nodeInfo == focusedNode,
|
||||
blinking = node == focusedNode,
|
||||
expanded = state.showDetails,
|
||||
currentTimeMillis = currentTimeMillis,
|
||||
)
|
||||
|
|
|
@ -38,7 +38,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
|||
import com.geeksville.mesh.BuildConfig
|
||||
import com.geeksville.mesh.DataPacket
|
||||
import com.geeksville.mesh.MeshProtos.Waypoint
|
||||
import com.geeksville.mesh.NodeInfo
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.android.BuildUtils.debug
|
||||
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.hasLocationPermission
|
||||
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.toNodeInfo
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.model.map.CustomTileSource
|
||||
import com.geeksville.mesh.model.map.MarkerWithLabel
|
||||
|
@ -61,8 +60,6 @@ import com.geeksville.mesh.util.zoomIn
|
|||
import com.geeksville.mesh.waypoint
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import org.osmdroid.bonuspack.utils.BonusPackHelper.getBitmapFromVectorDrawable
|
||||
import org.osmdroid.config.Configuration
|
||||
import org.osmdroid.events.DelayedMapListener
|
||||
|
@ -330,10 +327,7 @@ fun MapView(
|
|||
if (permissions.entries.all { it.value }) map.toggleMyLocation()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val nodes by model.nodeList
|
||||
.mapLatest { list -> list.map { it.toNodeInfo() } }
|
||||
.collectAsStateWithLifecycle(emptyList())
|
||||
val nodes by model.nodeList.collectAsStateWithLifecycle()
|
||||
val waypoints by model.waypoints.collectAsStateWithLifecycle(emptyMap())
|
||||
|
||||
var showDownloadButton: Boolean by remember { mutableStateOf(false) }
|
||||
|
@ -344,21 +338,21 @@ fun MapView(
|
|||
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 ourNode = model.ourNodeInfo.value?.toNodeInfo()
|
||||
val ourNode = model.ourNodeInfo.value
|
||||
val gpsFormat = model.config.display.gpsFormat.number
|
||||
val displayUnits = model.config.display.units.number
|
||||
return nodesWithPosition.map { node ->
|
||||
val (p, u) = node.position!! to node.user!!
|
||||
val nodePosition = GeoPoint(p.latitude, p.longitude)
|
||||
val (p, u) = node.position to node.user
|
||||
val nodePosition = GeoPoint(node.latitude, node.longitude)
|
||||
MarkerWithLabel(
|
||||
mapView = this,
|
||||
label = "${u.shortName} ${formatAgo(p.time)}"
|
||||
).apply {
|
||||
id = u.id
|
||||
title = "${u.longName} ${node.batteryStr}"
|
||||
snippet = p.gpsString(gpsFormat)
|
||||
snippet = node.gpsString(gpsFormat)
|
||||
ourNode?.distanceStr(node, displayUnits)?.let { dist ->
|
||||
subDescription =
|
||||
context.getString(R.string.map_subDescription, ourNode.bearing(node), dist)
|
||||
|
|
Ładowanie…
Reference in New Issue