Skip to content

Commit a6eae01

Browse files
committed
fix(discovery): map routing and missing parameters
- Add the Map icon to the DiscoveryHistoryDetailScreen so users can view the map of past sessions - Use @InjectedParam for sessionId in DiscoverySummaryViewModel, DiscoveryHistoryDetailViewModel, and DiscoveryMapViewModel to fix empty screens when using Navigation 3 - Populate userLatitude and userLongitude in the DiscoveryScanEngine so the Map functionality has a valid center anchor.
1 parent c80c982 commit a6eae01

6 files changed

Lines changed: 41 additions & 16 deletions

File tree

feature/discovery/src/commonMain/kotlin/org/meshtastic/feature/discovery/DiscoveryHistoryDetailViewModel.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,18 @@ package org.meshtastic.feature.discovery
1919
import androidx.lifecycle.SavedStateHandle
2020
import androidx.lifecycle.ViewModel
2121
import kotlinx.coroutines.flow.StateFlow
22+
import org.koin.core.annotation.InjectedParam
2223
import org.koin.core.annotation.KoinViewModel
2324
import org.meshtastic.core.database.dao.DiscoveryDao
2425
import org.meshtastic.core.database.entity.DiscoveryPresetResultEntity
2526
import org.meshtastic.core.database.entity.DiscoverySessionEntity
2627
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
2728

2829
@KoinViewModel
29-
class DiscoveryHistoryDetailViewModel(discoveryDao: DiscoveryDao, savedStateHandle: SavedStateHandle) : ViewModel() {
30-
31-
private val sessionId: Long = savedStateHandle.get<Long>("sessionId") ?: 0L
30+
class DiscoveryHistoryDetailViewModel(
31+
@InjectedParam private val sessionId: Long,
32+
discoveryDao: DiscoveryDao,
33+
) : ViewModel() {
3234

3335
val session: StateFlow<DiscoverySessionEntity?> =
3436
discoveryDao.getSessionFlow(sessionId).stateInWhileSubscribed(initialValue = null)

feature/discovery/src/commonMain/kotlin/org/meshtastic/feature/discovery/DiscoveryMapViewModel.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.lifecycle.ViewModel
2121
import kotlinx.coroutines.flow.MutableStateFlow
2222
import kotlinx.coroutines.flow.StateFlow
2323
import kotlinx.coroutines.flow.asStateFlow
24+
import org.koin.core.annotation.InjectedParam
2425
import org.koin.core.annotation.KoinViewModel
2526
import org.meshtastic.core.database.dao.DiscoveryDao
2627
import org.meshtastic.core.database.entity.DiscoveredNodeEntity
@@ -29,9 +30,10 @@ import org.meshtastic.core.ui.viewmodel.safeLaunch
2930
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
3031

3132
@KoinViewModel
32-
class DiscoveryMapViewModel(private val discoveryDao: DiscoveryDao, savedStateHandle: SavedStateHandle) : ViewModel() {
33-
34-
private val sessionId: Long = savedStateHandle.get<Long>("sessionId") ?: 0L
33+
class DiscoveryMapViewModel(
34+
@InjectedParam private val sessionId: Long,
35+
private val discoveryDao: DiscoveryDao,
36+
) : ViewModel() {
3537

3638
val session: StateFlow<DiscoverySessionEntity?> =
3739
discoveryDao.getSessionFlow(sessionId).stateInWhileSubscribed(initialValue = null)

feature/discovery/src/commonMain/kotlin/org/meshtastic/feature/discovery/DiscoveryScanEngine.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,20 @@ class DiscoveryScanEngine(
152152
ChannelOption.entries.firstOrNull { it.modemPreset == modemPreset }
153153
} ?: ChannelOption.DEFAULT
154154

155+
val myNodeNum = nodeRepository.myNodeInfo.value?.myNodeNum
156+
val myPosition = myNodeNum?.let { nodeRepository.nodeDBbyNum.value[it]?.position }
157+
val latDouble = (myPosition?.latitude_i ?: 0).toDouble() / POSITION_DIVISOR
158+
val lonDouble = (myPosition?.longitude_i ?: 0).toDouble() / POSITION_DIVISOR
159+
155160
// Create the DB session
156161
val session =
157162
DiscoverySessionEntity(
158163
timestamp = nowMillis,
159164
presetsScanned = presets.joinToString(",") { it.name },
160165
homePreset = homePreset?.name ?: ChannelOption.DEFAULT.name,
161166
completionStatus = "in_progress",
167+
userLatitude = latDouble,
168+
userLongitude = lonDouble,
162169
)
163170
sessionId = discoveryDao.insertSession(session)
164171
_currentSession.value = session.copy(id = sessionId)

feature/discovery/src/commonMain/kotlin/org/meshtastic/feature/discovery/DiscoverySummaryViewModel.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import androidx.lifecycle.ViewModel
2121
import kotlinx.coroutines.flow.MutableStateFlow
2222
import kotlinx.coroutines.flow.StateFlow
2323
import kotlinx.coroutines.flow.asStateFlow
24+
import org.koin.core.annotation.InjectedParam
2425
import org.koin.core.annotation.KoinViewModel
2526
import org.meshtastic.core.database.dao.DiscoveryDao
2627
import org.meshtastic.core.database.entity.DiscoveredNodeEntity
@@ -35,15 +36,13 @@ import org.meshtastic.feature.discovery.export.ExportResult
3536

3637
@KoinViewModel
3738
class DiscoverySummaryViewModel(
39+
@InjectedParam private val sessionId: Long,
3840
private val discoveryDao: DiscoveryDao,
3941
private val summaryGenerator: DiscoverySummaryGenerator,
4042
private val aiProvider: DiscoverySummaryAiProvider,
4143
private val exporter: DiscoveryExporter,
42-
savedStateHandle: SavedStateHandle,
4344
) : ViewModel() {
4445

45-
private val sessionId: Long = savedStateHandle.get<Long>("sessionId") ?: 0L
46-
4746
val session: StateFlow<DiscoverySessionEntity?> =
4847
discoveryDao.getSessionFlow(sessionId).stateInWhileSubscribed(initialValue = null)
4948

feature/discovery/src/commonMain/kotlin/org/meshtastic/feature/discovery/navigation/DiscoveryNavigation.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.navigation3.runtime.EntryProviderScope
2222
import androidx.navigation3.runtime.NavBackStack
2323
import androidx.navigation3.runtime.NavKey
2424
import org.koin.compose.viewmodel.koinViewModel
25+
import org.koin.core.parameter.parametersOf
2526
import org.meshtastic.core.navigation.DiscoveryRoute
2627
import org.meshtastic.feature.discovery.DiscoveryHistoryDetailViewModel
2728
import org.meshtastic.feature.discovery.DiscoveryHistoryViewModel
@@ -38,16 +39,16 @@ import org.meshtastic.feature.discovery.ui.DiscoverySummaryScreen
3839
fun EntryProviderScope<NavKey>.discoveryGraph(backStack: NavBackStack<NavKey>) {
3940
entry<DiscoveryRoute.DiscoveryGraph> { DiscoveryScanScreenEntry(backStack) }
4041
entry<DiscoveryRoute.DiscoveryScan> { DiscoveryScanScreenEntry(backStack) }
41-
entry<DiscoveryRoute.DiscoverySummary> {
42-
val viewModel = koinViewModel<DiscoverySummaryViewModel>()
42+
entry<DiscoveryRoute.DiscoverySummary> { route ->
43+
val viewModel = koinViewModel<DiscoverySummaryViewModel> { parametersOf(route.sessionId) }
4344
DiscoverySummaryScreen(
4445
viewModel = viewModel,
4546
onNavigateUp = dropUnlessResumed { backStack.removeLastOrNull() },
4647
onNavigateToMap = { sessionId -> backStack.add(DiscoveryRoute.DiscoveryMap(sessionId)) },
4748
)
4849
}
49-
entry<DiscoveryRoute.DiscoveryMap> {
50-
val viewModel = koinViewModel<DiscoveryMapViewModel>()
50+
entry<DiscoveryRoute.DiscoveryMap> { route ->
51+
val viewModel = koinViewModel<DiscoveryMapViewModel> { parametersOf(route.sessionId) }
5152
DiscoveryMapScreen(viewModel = viewModel, onNavigateUp = dropUnlessResumed { backStack.removeLastOrNull() })
5253
}
5354
entry<DiscoveryRoute.DiscoveryHistory> {
@@ -61,11 +62,12 @@ fun EntryProviderScope<NavKey>.discoveryGraph(backStack: NavBackStack<NavKey>) {
6162
onNavigateToDetail = navigateToDetail,
6263
)
6364
}
64-
entry<DiscoveryRoute.DiscoveryHistoryDetail> {
65-
val viewModel = koinViewModel<DiscoveryHistoryDetailViewModel>()
65+
entry<DiscoveryRoute.DiscoveryHistoryDetail> { route ->
66+
val viewModel = koinViewModel<DiscoveryHistoryDetailViewModel> { parametersOf(route.sessionId) }
6667
DiscoveryHistoryDetailScreen(
6768
viewModel = viewModel,
6869
onNavigateUp = dropUnlessResumed { backStack.removeLastOrNull() },
70+
onNavigateToMap = { sessionId -> backStack.add(DiscoveryRoute.DiscoveryMap(sessionId)) },
6971
)
7072
}
7173
}

feature/discovery/src/commonMain/kotlin/org/meshtastic/feature/discovery/ui/DiscoveryHistoryDetailScreen.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,17 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
4545
import org.meshtastic.core.database.entity.DiscoverySessionEntity
4646
import org.meshtastic.core.ui.icon.ArrowBack
4747
import org.meshtastic.core.ui.icon.MeshtasticIcons
48+
import org.meshtastic.core.ui.icon.Map
4849
import org.meshtastic.feature.discovery.DiscoveryHistoryDetailViewModel
4950
import org.meshtastic.feature.discovery.ui.component.PresetResultCard
5051

5152
@OptIn(ExperimentalMaterial3Api::class)
5253
@Composable
53-
fun DiscoveryHistoryDetailScreen(viewModel: DiscoveryHistoryDetailViewModel, onNavigateUp: () -> Unit) {
54+
fun DiscoveryHistoryDetailScreen(
55+
viewModel: DiscoveryHistoryDetailViewModel,
56+
onNavigateUp: () -> Unit,
57+
onNavigateToMap: (Long) -> Unit,
58+
) {
5459
val session by viewModel.session.collectAsStateWithLifecycle()
5560
val presetResults by viewModel.presetResults.collectAsStateWithLifecycle()
5661

@@ -61,6 +66,14 @@ fun DiscoveryHistoryDetailScreen(viewModel: DiscoveryHistoryDetailViewModel, onN
6166
navigationIcon = {
6267
IconButton(onClick = onNavigateUp) { Icon(MeshtasticIcons.ArrowBack, contentDescription = "Back") }
6368
},
69+
actions = {
70+
val s = session
71+
if (s != null && s.userLatitude != 0.0 && s.userLongitude != 0.0) {
72+
IconButton(onClick = { onNavigateToMap(s.id) }) {
73+
Icon(MeshtasticIcons.Map, contentDescription = "View map")
74+
}
75+
}
76+
},
6477
)
6578
},
6679
) { padding ->

0 commit comments

Comments
 (0)