fix: resolve crashes and debug filter issues in Metrics and MapView (#4824)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich
2026-03-17 09:04:41 -05:00
committed by GitHub
parent 9ad28e924f
commit a10fe61d0f
6 changed files with 27 additions and 26 deletions

View File

@@ -28,7 +28,6 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.rememberScrollState
@@ -97,7 +96,6 @@ import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.common.util.nowSeconds
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
import org.meshtastic.core.resources.cancel
@@ -107,10 +105,7 @@ import org.meshtastic.core.resources.delete_for_everyone
import org.meshtastic.core.resources.delete_for_me
import org.meshtastic.core.resources.expires
import org.meshtastic.core.resources.getString
import org.meshtastic.core.resources.heading
import org.meshtastic.core.resources.latitude
import org.meshtastic.core.resources.location_disabled
import org.meshtastic.core.resources.longitude
import org.meshtastic.core.resources.map_cache_info
import org.meshtastic.core.resources.map_cache_manager
import org.meshtastic.core.resources.map_cache_size
@@ -142,7 +137,6 @@ import org.meshtastic.core.ui.util.showToast
import org.meshtastic.feature.map.LastHeardFilter
import org.meshtastic.feature.map.model.TracerouteOverlay
import org.meshtastic.feature.map.tracerouteNodeSelection
import org.meshtastic.proto.Config.DisplayConfig.DisplayUnits
import org.meshtastic.proto.Position
import org.meshtastic.proto.Waypoint
import org.osmdroid.bonuspack.utils.BonusPackHelper.getBitmapFromVectorDrawable
@@ -444,7 +438,9 @@ fun MapView(
if (node.batteryStr != "") node.batteryStr else "?",
)
ourNode?.distanceStr(node, displayUnits)?.let { dist ->
subDescription = getString(Res.string.map_subDescription, ourNode.bearing(node).toString(), dist)
ourNode.bearing(node)?.let { bearing ->
subDescription = getString(Res.string.map_subDescription, bearing, dist)
}
}
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
position = nodePosition

View File

@@ -22,7 +22,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.koin.core.annotation.KoinViewModel
import org.meshtastic.core.common.BuildConfigProvider
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.RadioController
import org.meshtastic.core.repository.MapPrefs
import org.meshtastic.core.repository.NodeRepository
@@ -37,7 +36,7 @@ import org.meshtastic.proto.LocalConfig
class MapViewModel(
mapPrefs: MapPrefs,
packetRepository: PacketRepository,
override val nodeRepository: NodeRepository,
nodeRepository: NodeRepository,
radioController: RadioController,
radioConfigRepository: RadioConfigRepository,
buildConfigProvider: BuildConfigProvider,
@@ -65,6 +64,4 @@ class MapViewModel(
get() = localConfig.value
val applicationId = buildConfigProvider.applicationId
override fun getUser(userId: String?) = nodeRepository.getUser(userId ?: DataPacket.ID_BROADCAST)
}

View File

@@ -34,6 +34,7 @@ import androidx.navigation3.runtime.NavKey
import kotlinx.coroutines.flow.Flow
import org.jetbrains.compose.resources.StringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
import org.meshtastic.app.map.node.NodeMapScreen
import org.meshtastic.app.ui.node.AdaptiveNodeListScreen
import org.meshtastic.core.navigation.ContactsRoutes
@@ -115,7 +116,8 @@ fun EntryProviderScope<NavKey>.nodeDetailGraph(
}
entry<NodeDetailRoutes.TracerouteLog> { args ->
val metricsViewModel = koinViewModel<MetricsViewModel>()
val metricsViewModel =
koinViewModel<MetricsViewModel>(key = "metrics-${args.destNum}") { parametersOf(args.destNum) }
metricsViewModel.setNodeId(args.destNum)
TracerouteLogScreen(
@@ -134,7 +136,8 @@ fun EntryProviderScope<NavKey>.nodeDetailGraph(
}
entry<NodeDetailRoutes.TracerouteMap> { args ->
val metricsViewModel = koinViewModel<MetricsViewModel>()
val metricsViewModel =
koinViewModel<MetricsViewModel>(key = "metrics-${args.destNum}") { parametersOf(args.destNum) }
metricsViewModel.setNodeId(args.destNum)
TracerouteMapScreen(
@@ -176,8 +179,8 @@ private inline fun <reified R : Route> EntryProviderScope<NavKey>.addNodeDetailS
crossinline getDestNum: (R) -> Int,
) {
entry<R> { args ->
val metricsViewModel = koinViewModel<MetricsViewModel>()
val destNum = getDestNum(args)
val metricsViewModel = koinViewModel<MetricsViewModel>(key = "metrics-$destNum") { parametersOf(destNum) }
metricsViewModel.setNodeId(destNum)
routeInfo.screenComposable(metricsViewModel) { backStack.removeLastOrNull() }

View File

@@ -32,6 +32,7 @@ import org.koin.test.verify.injectedParameters
import org.koin.test.verify.verify
import org.meshtastic.app.map.MapViewModel
import org.meshtastic.core.model.util.NodeIdLookup
import org.meshtastic.feature.node.metrics.MetricsViewModel
class KoinVerificationTest {
@@ -54,7 +55,11 @@ class KoinVerificationTest {
HttpClientEngine::class,
OkHttpClient::class,
),
injections = injectedParameters(definition<MapViewModel>(SavedStateHandle::class)),
injections =
injectedParameters(
definition<MapViewModel>(SavedStateHandle::class),
definition<MetricsViewModel>(Int::class),
),
)
}
}

View File

@@ -47,7 +47,7 @@ import org.meshtastic.proto.Waypoint
@Suppress("TooManyFunctions")
open class BaseMapViewModel(
protected val mapPrefs: MapPrefs,
protected open val nodeRepository: NodeRepository,
protected val nodeRepository: NodeRepository,
private val packetRepository: PacketRepository,
private val radioController: RadioController,
) : ViewModel() {

View File

@@ -193,19 +193,19 @@ class LogFilterManager {
return logs.filter { logItem ->
when (filterMode) {
FilterMode.OR ->
filterTexts.any {
it.contains(logItem.logMessage, ignoreCase = true) ||
it.contains(logItem.messageType, ignoreCase = true) ||
it.contains(logItem.formattedReceivedDate, ignoreCase = true) ||
(logItem.decodedPayload?.contains(it, ignoreCase = true) == true)
filterTexts.any { filter ->
logItem.logMessage.contains(filter, ignoreCase = true) ||
logItem.messageType.contains(filter, ignoreCase = true) ||
logItem.formattedReceivedDate.contains(filter, ignoreCase = true) ||
(logItem.decodedPayload?.contains(filter, ignoreCase = true) == true)
}
FilterMode.AND ->
filterTexts.all {
it.contains(logItem.logMessage, ignoreCase = true) ||
it.contains(logItem.messageType, ignoreCase = true) ||
it.contains(logItem.formattedReceivedDate, ignoreCase = true) ||
(logItem.decodedPayload?.contains(it, ignoreCase = true) == true)
filterTexts.all { filter ->
logItem.logMessage.contains(filter, ignoreCase = true) ||
logItem.messageType.contains(filter, ignoreCase = true) ||
logItem.formattedReceivedDate.contains(filter, ignoreCase = true) ||
(logItem.decodedPayload?.contains(filter, ignoreCase = true) == true)
}
}
}