From af8e1daa5dd339a0821339012ef0be476518566b Mon Sep 17 00:00:00 2001 From: Phil Oliver <3497406+poliver@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:34:36 -0400 Subject: [PATCH] Decouple `MapView` from `UiViewModel` (#3213) --- .../com/geeksville/mesh/ui/map/MapView.kt | 50 +++++++++---------- .../geeksville/mesh/ui/map/MapViewModel.kt | 21 +++++++- .../com/geeksville/mesh/ui/map/MapView.kt | 18 +++---- .../geeksville/mesh/ui/map/MapViewModel.kt | 4 ++ .../com/geeksville/mesh/ui/node/NodeMap.kt | 7 +-- .../java/com/geeksville/mesh/model/UIState.kt | 31 ------------ .../mesh/navigation/MapNavigation.kt | 4 +- .../main/java/com/geeksville/mesh/ui/Main.kt | 2 +- .../mesh/ui/map/BaseMapViewModel.kt | 43 +++++++++++++++- .../com/geeksville/mesh/ui/map/MapScreen.kt | 8 +-- 10 files changed, 102 insertions(+), 86 deletions(-) diff --git a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt index f7b476818..8b1de274f 100644 --- a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt +++ b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt @@ -19,6 +19,7 @@ package com.geeksville.mesh.ui.map import android.Manifest // Added for Accompanist import android.content.Context +import android.widget.Toast import androidx.appcompat.content.res.AppCompatResources import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement @@ -61,13 +62,11 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.lifecycle.viewmodel.compose.viewModel import com.geeksville.mesh.MeshProtos.Waypoint import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.android.gpsDisabled import com.geeksville.mesh.android.hasGps import com.geeksville.mesh.copy -import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.ui.map.components.CacheLayout import com.geeksville.mesh.ui.map.components.DownloadButton import com.geeksville.mesh.ui.map.components.EditWaypointDialog @@ -204,21 +203,17 @@ private fun Context.purgeTileSource(onResult: (String) -> Unit) { * Main composable for displaying the map view, including nodes, waypoints, and user location. It handles user * interactions for map manipulation, filtering, and offline caching. * - * @param model The [UIViewModel] providing data and state for the map. + * @param mapViewModel The [MapViewModel] providing data and state for the map. * @param navigateToNodeDetails Callback to navigate to the details screen of a selected node. */ @OptIn(ExperimentalPermissionsApi::class) // Added for Accompanist @Suppress("CyclomaticComplexMethod", "LongMethod") @Composable -fun MapView( - uiViewModel: UIViewModel = viewModel(), - mapViewModel: MapViewModel = hiltViewModel(), - navigateToNodeDetails: (Int) -> Unit, -) { +fun MapView(mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails: (Int) -> Unit) { var mapFilterExpanded by remember { mutableStateOf(false) } val mapFilterState by mapViewModel.mapFilterStateFlow.collectAsStateWithLifecycle() - val isConnected by uiViewModel.isConnectedStateFlow.collectAsStateWithLifecycle() + val isConnected by mapViewModel.isConnected.collectAsStateWithLifecycle() var cacheEstimate by remember { mutableStateOf("") } @@ -267,7 +262,7 @@ fun MapView( fun MapView.toggleMyLocation() { if (context.gpsDisabled()) { debug("Telling user we need location turned on for MyLocationNewOverlay") - uiViewModel.showSnackBar(R.string.location_disabled) + Toast.makeText(context, R.string.location_disabled, Toast.LENGTH_SHORT).show() return } debug("user clicked MyLocationNewOverlay ${myLocationOverlay == null}") @@ -313,8 +308,8 @@ fun MapView( fun MapView.onNodesChanged(nodes: Collection): List { val nodesWithPosition = nodes.filter { it.validPosition != null } - val ourNode = uiViewModel.ourNodeInfo.value - val displayUnits = uiViewModel.config.display.units + val ourNode = mapViewModel.ourNodeInfo.value + val displayUnits = mapViewModel.config.display.units val mapFilterStateValue = mapViewModel.mapFilterStateFlow.value // Access mapFilterState directly return nodesWithPosition.mapNotNull { node -> if (mapFilterStateValue.onlyFavorites && !node.isFavorite && !node.equals(ourNode)) { @@ -360,13 +355,13 @@ fun MapView( builder.setNeutralButton(R.string.cancel) { _, _ -> debug("User canceled marker delete dialog") } builder.setNegativeButton(R.string.delete_for_me) { _, _ -> debug("User deleted waypoint ${waypoint.id} for me") - uiViewModel.deleteWaypoint(waypoint.id) + mapViewModel.deleteWaypoint(waypoint.id) } - if (waypoint.lockedTo in setOf(0, uiViewModel.myNodeNum ?: 0) && isConnected) { + if (waypoint.lockedTo in setOf(0, mapViewModel.myNodeNum ?: 0) && isConnected) { builder.setPositiveButton(R.string.delete_for_everyone) { _, _ -> debug("User deleted waypoint ${waypoint.id} for everyone") - uiViewModel.sendWaypoint(waypoint.copy { expire = 1 }) - uiViewModel.deleteWaypoint(waypoint.id) + mapViewModel.sendWaypoint(waypoint.copy { expire = 1 }) + mapViewModel.deleteWaypoint(waypoint.id) } } val dialog = builder.show() @@ -390,7 +385,7 @@ fun MapView( debug("marker long pressed id=$id") val waypoint = waypoints[id]?.data?.waypoint ?: return // edit only when unlocked or lockedTo myNodeNum - if (waypoint.lockedTo in setOf(0, uiViewModel.myNodeNum ?: 0) && isConnected) { + if (waypoint.lockedTo in setOf(0, mapViewModel.myNodeNum ?: 0) && isConnected) { showEditWaypointDialog = waypoint } else { showDeleteMarkerDialog(waypoint) @@ -400,7 +395,7 @@ fun MapView( fun getUsername(id: String?) = if (id == DataPacket.ID_LOCAL) { context.getString(R.string.you) } else { - uiViewModel.getUser(id).longName + mapViewModel.getUser(id).longName } @Composable @@ -451,7 +446,7 @@ fun MapView( LaunchedEffect(showCurrentCacheInfo) { if (!showCurrentCacheInfo) return@LaunchedEffect - uiViewModel.showSnackBar(R.string.calculating) + Toast.makeText(context, R.string.calculating, Toast.LENGTH_SHORT).show() val cacheManager = CacheManager(map) val cacheCapacity = cacheManager.cacheCapacity() val currentCacheUsage = cacheManager.currentCacheUsage() @@ -560,11 +555,16 @@ fun MapView( zoomLevelMax.toInt(), cacheManagerCallback( onTaskComplete = { - uiViewModel.showSnackBar(R.string.map_download_complete) + Toast.makeText(context, R.string.map_download_complete, Toast.LENGTH_SHORT).show() writer.onDetach() }, onTaskFailed = { errors -> - uiViewModel.showSnackBar(context.getString(R.string.map_download_errors, errors)) + Toast.makeText( + context, + context.getString(R.string.map_download_errors, errors), + Toast.LENGTH_SHORT, + ) + .show() writer.onDetach() }, ), @@ -609,7 +609,7 @@ fun MapView( dialog.dismiss() } - 2 -> purgeTileSource { uiViewModel.showSnackBar(it) } + 2 -> purgeTileSource { Toast.makeText(this, it, Toast.LENGTH_SHORT).show() } else -> dialog.dismiss() } } @@ -770,12 +770,12 @@ fun MapView( onSendClicked = { waypoint -> debug("User clicked send waypoint ${waypoint.id}") showEditWaypointDialog = null - uiViewModel.sendWaypoint( + mapViewModel.sendWaypoint( waypoint.copy { - if (id == 0) id = uiViewModel.generatePacketId() ?: return@EditWaypointDialog + if (id == 0) id = mapViewModel.generatePacketId() ?: return@EditWaypointDialog if (name == "") name = "Dropped Pin" if (expire == 0) expire = Int.MAX_VALUE - lockedTo = if (waypoint.lockedTo != 0) uiViewModel.myNodeNum ?: 0 else 0 + lockedTo = if (waypoint.lockedTo != 0) mapViewModel.myNodeNum ?: 0 else 0 if (waypoint.icon == 0) icon = 128205 }, ) diff --git a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt index a92702834..f88b4d4ea 100644 --- a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt +++ b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt @@ -17,10 +17,16 @@ package com.geeksville.mesh.ui.map +import androidx.lifecycle.viewModelScope +import com.geeksville.mesh.LocalOnlyProtos.LocalConfig import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.PacketRepository +import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.service.ServiceRepository import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.stateIn +import org.meshtastic.core.model.DataPacket import org.meshtastic.core.prefs.map.MapPrefs import javax.inject.Inject @@ -30,8 +36,9 @@ class MapViewModel constructor( mapPrefs: MapPrefs, packetRepository: PacketRepository, - nodeRepository: NodeRepository, + private val nodeRepository: NodeRepository, serviceRepository: ServiceRepository, + radioConfigRepository: RadioConfigRepository, ) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, serviceRepository) { var mapStyleId: Int @@ -39,4 +46,16 @@ constructor( set(value) { mapPrefs.mapStyle = value } + + val localConfig = + radioConfigRepository.localConfigFlow.stateIn( + viewModelScope, + SharingStarted.WhileSubscribed(5_000L), + LocalConfig.getDefaultInstance(), + ) + + val config + get() = localConfig.value + + fun getUser(userId: String?) = nodeRepository.getUser(userId ?: DataPacket.ID_BROADCAST) } diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt index 6781c22b2..c784e5d37 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt @@ -71,7 +71,6 @@ import com.geeksville.mesh.MeshProtos.Waypoint import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.android.BuildUtils.warn import com.geeksville.mesh.copy -import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.ui.map.components.ClusterItemsListDialog import com.geeksville.mesh.ui.map.components.CustomMapLayersSheet import com.geeksville.mesh.ui.map.components.CustomTileProviderManagerSheet @@ -178,7 +177,6 @@ private fun filterNodeTrack(nodeTrack: List?): List { @OptIn(MapsComposeExperimentalApi::class, ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class) @Composable fun MapView( - uiViewModel: UIViewModel, mapViewModel: MapViewModel = hiltViewModel(), navigateToNodeDetails: (Int) -> Unit, focusedNodeNum: Int? = null, @@ -208,7 +206,7 @@ fun MapView( var mapFilterMenuExpanded by remember { mutableStateOf(false) } val mapFilterState by mapViewModel.mapFilterStateFlow.collectAsStateWithLifecycle() - val ourNodeInfo by uiViewModel.ourNodeInfo.collectAsStateWithLifecycle() + val ourNodeInfo by mapViewModel.ourNodeInfo.collectAsStateWithLifecycle() var editingWaypoint by remember { mutableStateOf(null) } val selectedGoogleMapType by mapViewModel.selectedGoogleMapType.collectAsStateWithLifecycle() @@ -319,8 +317,8 @@ fun MapView( nodeSnippet = "${node.user.longName}", ) } - val isConnected by uiViewModel.isConnectedStateFlow.collectAsStateWithLifecycle() - val theme by uiViewModel.theme.collectAsStateWithLifecycle() + val isConnected by mapViewModel.isConnected.collectAsStateWithLifecycle() + val theme by mapViewModel.theme.collectAsStateWithLifecycle() val dark = when (theme) { AppCompatDelegate.MODE_NIGHT_YES -> true @@ -531,7 +529,7 @@ fun MapView( WaypointMarkers( displayableWaypoints = displayableWaypoints, mapFilterState = mapFilterState, - myNodeNum = uiViewModel.myNodeNum ?: 0, + myNodeNum = mapViewModel.myNodeNum ?: 0, isConnected = isConnected, unicodeEmojiToBitmapProvider = ::unicodeEmojiToBitmap, onEditWaypointRequest = { waypointToEdit -> editingWaypoint = waypointToEdit }, @@ -577,21 +575,21 @@ fun MapView( onSendClicked = { updatedWp -> var finalWp = updatedWp if (updatedWp.id == 0) { - finalWp = finalWp.copy { id = uiViewModel.generatePacketId() ?: 0 } + finalWp = finalWp.copy { id = mapViewModel.generatePacketId() ?: 0 } } if (updatedWp.icon == 0) { finalWp = finalWp.copy { icon = 0x1F4CD } } - uiViewModel.sendWaypoint(finalWp) + mapViewModel.sendWaypoint(finalWp) editingWaypoint = null }, onDeleteClicked = { wpToDelete -> if (wpToDelete.lockedTo == 0 && isConnected && wpToDelete.id != 0) { val deleteMarkerWp = wpToDelete.copy { expire = 1 } - uiViewModel.sendWaypoint(deleteMarkerWp) + mapViewModel.sendWaypoint(deleteMarkerWp) } - uiViewModel.deleteWaypoint(wpToDelete.id) + mapViewModel.deleteWaypoint(wpToDelete.id) editingWaypoint = null }, onDismissRequest = { editingWaypoint = null }, diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt b/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt index 880e80fbb..44002d329 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt @@ -52,6 +52,7 @@ import kotlinx.serialization.Serializable import org.json.JSONObject import org.meshtastic.core.data.model.CustomTileProviderConfig import org.meshtastic.core.data.repository.CustomTileProviderRepository +import org.meshtastic.core.datastore.UiPreferencesDataSource import org.meshtastic.core.prefs.map.GoogleMapsPrefs import org.meshtastic.core.prefs.map.MapPrefs import timber.log.Timber @@ -88,8 +89,11 @@ constructor( radioConfigRepository: RadioConfigRepository, serviceRepository: ServiceRepository, private val customTileProviderRepository: CustomTileProviderRepository, + uiPreferencesDataSource: UiPreferencesDataSource, ) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, serviceRepository) { + val theme: StateFlow = uiPreferencesDataSource.theme + private val _errorFlow = MutableSharedFlow() val errorFlow: SharedFlow = _errorFlow.asSharedFlow() diff --git a/app/src/google/java/com/geeksville/mesh/ui/node/NodeMap.kt b/app/src/google/java/com/geeksville/mesh/ui/node/NodeMap.kt index 3f10d002d..5abad9568 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/node/NodeMap.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/node/NodeMap.kt @@ -61,12 +61,7 @@ fun NodeMapScreen( }, ) { paddingValues -> Box(modifier = Modifier.padding(paddingValues)) { - MapView( - uiViewModel = uiViewModel, - focusedNodeNum = destNum, - nodeTrack = positions, - navigateToNodeDetails = {}, - ) + MapView(focusedNodeNum = destNum, nodeTrack = positions, navigateToNodeDetails = {}) } } } diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index 5e0092b07..467720acb 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -386,32 +386,6 @@ constructor( initialValue = emptyList(), ) - fun generatePacketId(): Int? { - return try { - meshService?.packetId - } catch (ex: RemoteException) { - errormsg("RemoteException: ${ex.message}") - return null - } - } - - fun sendWaypoint(wpt: MeshProtos.Waypoint, contactKey: String = "0${DataPacket.ID_BROADCAST}") { - // contactKey: unique contact key filter (channel)+(nodeId) - val channel = contactKey[0].digitToIntOrNull() - val dest = if (channel != null) contactKey.substring(1) else contactKey - - val p = DataPacket(dest, channel ?: 0, wpt) - if (wpt.id != 0) sendDataPacket(p) - } - - private fun sendDataPacket(p: DataPacket) { - try { - meshService?.send(p) - } catch (ex: RemoteException) { - errormsg("Send DataPacket error: ${ex.message}") - } - } - private val _sharedContactRequested: MutableStateFlow = MutableStateFlow(null) val sharedContactRequested: StateFlow get() = _sharedContactRequested.asStateFlow() @@ -426,8 +400,6 @@ constructor( fun deleteContacts(contacts: List) = viewModelScope.launch(Dispatchers.IO) { packetRepository.deleteContacts(contacts) } - fun deleteWaypoint(id: Int) = viewModelScope.launch(Dispatchers.IO) { packetRepository.deleteWaypoint(id) } - // Connection state to our radio device val connectionState get() = serviceRepository.connectionState @@ -470,9 +442,6 @@ constructor( val isManaged: Boolean get() = config.device.isManaged || config.security.isManaged - val myNodeNum - get() = myNodeInfo.value?.myNodeNum - override fun onCleared() { super.onCleared() debug("ViewModel cleared") diff --git a/app/src/main/java/com/geeksville/mesh/navigation/MapNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/MapNavigation.kt index 7fcc97ffe..774350619 100644 --- a/app/src/main/java/com/geeksville/mesh/navigation/MapNavigation.kt +++ b/app/src/main/java/com/geeksville/mesh/navigation/MapNavigation.kt @@ -21,16 +21,14 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.composable import androidx.navigation.navDeepLink -import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.ui.map.MapScreen import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI import org.meshtastic.core.navigation.MapRoutes import org.meshtastic.core.navigation.NodesRoutes -fun NavGraphBuilder.mapGraph(navController: NavHostController, uiViewModel: UIViewModel) { +fun NavGraphBuilder.mapGraph(navController: NavHostController) { composable(deepLinks = listOf(navDeepLink(basePath = "$DEEP_LINK_BASE_URI/map"))) { MapScreen( - uiViewModel = uiViewModel, onClickNodeChip = { navController.navigate(NodesRoutes.NodeDetailGraph(it)) { launchSingleTop = true diff --git a/app/src/main/java/com/geeksville/mesh/ui/Main.kt b/app/src/main/java/com/geeksville/mesh/ui/Main.kt index f81a489a6..7dccf1dfe 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt @@ -412,7 +412,7 @@ fun MainScreen(uIViewModel: UIViewModel = hiltViewModel(), scanModel: BTScanMode ) { contactsGraph(navController, uiViewModel = uIViewModel) nodesGraph(navController, uiViewModel = uIViewModel) - mapGraph(navController, uiViewModel = uIViewModel) + mapGraph(navController) channelsGraph(navController, uiViewModel = uIViewModel) connectionsGraph(navController) settingsGraph(navController) diff --git a/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt index 4434cf07d..70f7c1cda 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt @@ -17,11 +17,14 @@ package com.geeksville.mesh.ui.map +import android.os.RemoteException import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.service.ServiceRepository +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -29,18 +32,26 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch import org.meshtastic.core.database.entity.Packet import org.meshtastic.core.database.model.Node +import org.meshtastic.core.model.DataPacket import org.meshtastic.core.prefs.map.MapPrefs +import timber.log.Timber @Suppress("TooManyFunctions") abstract class BaseMapViewModel( protected val mapPrefs: MapPrefs, nodeRepository: NodeRepository, - packetRepository: PacketRepository, - serviceRepository: ServiceRepository, + private val packetRepository: PacketRepository, + private val serviceRepository: ServiceRepository, ) : ViewModel() { + val myNodeInfo = nodeRepository.myNodeInfo + + val myNodeNum + get() = myNodeInfo.value?.myNodeNum + val nodes: StateFlow> = nodeRepository .getNodes() @@ -94,6 +105,34 @@ abstract class BaseMapViewModel( showPrecisionCircleOnMap.value = !current } + fun generatePacketId(): Int? { + return try { + serviceRepository.meshService?.packetId + } catch (ex: RemoteException) { + Timber.e("RemoteException: ${ex.message}") + return null + } + } + + fun deleteWaypoint(id: Int) = viewModelScope.launch(Dispatchers.IO) { packetRepository.deleteWaypoint(id) } + + fun sendWaypoint(wpt: MeshProtos.Waypoint, contactKey: String = "0${DataPacket.ID_BROADCAST}") { + // contactKey: unique contact key filter (channel)+(nodeId) + val channel = contactKey[0].digitToIntOrNull() + val dest = if (channel != null) contactKey.substring(1) else contactKey + + val p = DataPacket(dest, channel ?: 0, wpt) + if (wpt.id != 0) sendDataPacket(p) + } + + private fun sendDataPacket(p: DataPacket) { + try { + serviceRepository.meshService?.send(p) + } catch (ex: RemoteException) { + Timber.e("Send DataPacket error: ${ex.message}") + } + } + data class MapFilterState(val onlyFavorites: Boolean, val showWaypoints: Boolean, val showPrecisionCircle: Boolean) val mapFilterStateFlow: StateFlow = diff --git a/app/src/main/java/com/geeksville/mesh/ui/map/MapScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/map/MapScreen.kt index e9504a3e8..1cecaf1aa 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/map/MapScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/map/MapScreen.kt @@ -26,7 +26,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.ui.common.components.MainAppBar import com.geeksville.mesh.ui.node.components.NodeMenuAction import org.meshtastic.core.strings.R @@ -35,7 +34,6 @@ import org.meshtastic.core.strings.R fun MapScreen( onClickNodeChip: (Int) -> Unit, navigateToNodeDetails: (Int) -> Unit, - uiViewModel: UIViewModel, modifier: Modifier = Modifier, mapViewModel: MapViewModel = hiltViewModel(), ) { @@ -64,11 +62,7 @@ fun MapScreen( }, ) { paddingValues -> Box(modifier = Modifier.padding(paddingValues)) { - MapView( - uiViewModel = uiViewModel, - mapViewModel = mapViewModel, - navigateToNodeDetails = navigateToNodeDetails, - ) + MapView(mapViewModel = mapViewModel, navigateToNodeDetails = navigateToNodeDetails) } } }