Move NodeMapScreen to :feature:map (#3443)

This commit is contained in:
Phil Oliver 2025-10-12 16:27:27 -04:00 committed by GitHub
parent e4ecf1d483
commit 3984c97e39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 3 additions and 11 deletions

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.meshtastic.feature.map.node
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.meshtastic.feature.map.addCopyright
import org.meshtastic.feature.map.addPolyline
import org.meshtastic.feature.map.addPositionMarkers
import org.meshtastic.feature.map.addScaleBarOverlay
import org.meshtastic.feature.map.rememberMapViewWithLifecycle
import org.osmdroid.util.BoundingBox
import org.osmdroid.util.GeoPoint
private const val DEG_D = 1e-7
@Composable
fun NodeMapScreen(nodeMapViewModel: NodeMapViewModel, onNavigateUp: () -> Unit) {
val density = LocalDensity.current
val positionLogs by nodeMapViewModel.positionLogs.collectAsStateWithLifecycle()
val geoPoints = positionLogs.map { GeoPoint(it.latitudeI * DEG_D, it.longitudeI * DEG_D) }
val cameraView = remember { BoundingBox.fromGeoPoints(geoPoints) }
val mapView =
rememberMapViewWithLifecycle(
applicationId = nodeMapViewModel.applicationId,
box = cameraView,
tileSource = nodeMapViewModel.tileSource,
)
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { mapView },
update = { map ->
map.overlays.clear()
map.addCopyright()
map.addScaleBarOverlay(density)
map.addPolyline(density, geoPoints) {}
map.addPositionMarkers(positionLogs) {}
},
)
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.meshtastic.feature.map.node
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.meshtastic.core.ui.component.MainAppBar
import org.meshtastic.feature.map.MapView
@Composable
fun NodeMapScreen(nodeMapViewModel: NodeMapViewModel, onNavigateUp: () -> Unit) {
val node by nodeMapViewModel.node.collectAsStateWithLifecycle()
val positions by nodeMapViewModel.positionLogs.collectAsStateWithLifecycle()
val destNum = node?.num
Scaffold(
topBar = {
MainAppBar(
title = node?.user?.longName ?: "",
ourNode = null,
showNodeChip = false,
canNavigateUp = true,
onNavigateUp = onNavigateUp,
actions = {},
onClickChip = {},
)
},
) { paddingValues ->
Box(modifier = Modifier.padding(paddingValues)) {
MapView(focusedNodeNum = destNum, nodeTracks = positions, navigateToNodeDetails = {})
}
}
}

View file

@ -17,15 +17,9 @@
<ID>LambdaParameterInRestartableEffect:MessageList.kt$onUnreadChanged</ID>
<ID>LongParameterList:MessageViewModel.kt$MessageViewModel$( private val nodeRepository: NodeRepository, radioConfigRepository: RadioConfigRepository, quickChatActionRepository: QuickChatActionRepository, private val serviceRepository: ServiceRepository, private val packetRepository: PacketRepository, private val uiPrefs: UiPrefs, private val meshServiceNotifications: MeshServiceNotifications, )</ID>
<ID>ModifierMissing:Message.kt$MessageScreen</ID>
<ID>ModifierMissing:MessageActions.kt$MessageStatusButton</ID>
<ID>ModifierMissing:MessageActions.kt$ReactionButton</ID>
<ID>ModifierMissing:MessageActions.kt$ReplyButton</ID>
<ID>ModifierMissing:Reaction.kt$ReactionDialog</ID>
<ID>ModifierNotUsedAtRoot:QuickChat.kt$modifier = modifier.fillMaxSize().padding(innerPadding)</ID>
<ID>MutableStateParam:MessageList.kt$selectedIds</ID>
<ID>ParameterNaming:MessageList.kt$onUnreadChanged</ID>
<ID>PreviewPublic:Reaction.kt$ReactionItemPreview</ID>
<ID>PreviewPublic:Reaction.kt$ReactionRowPreview</ID>
<ID>TooManyFunctions:MessageViewModel.kt$MessageViewModel : ViewModel</ID>
<ID>Wrapping:Message.kt${ event -&gt; when (event) { is MessageScreenEvent.SendMessage -&gt; { viewModel.sendMessage(event.text, contactKey, event.replyingToPacketId) if (event.replyingToPacketId != null) replyingToPacketId = null messageInputState.clearText() } is MessageScreenEvent.SendReaction -&gt; viewModel.sendReaction(event.emoji, event.messageId, contactKey) is MessageScreenEvent.DeleteMessages -&gt; { viewModel.deleteMessages(event.ids) selectedMessageIds.value = emptySet() showDeleteDialog = false } is MessageScreenEvent.ClearUnreadCount -&gt; viewModel.clearUnreadCount(contactKey, event.lastReadMessageId) is MessageScreenEvent.NodeDetails -&gt; navigateToNodeDetails(event.node.num) is MessageScreenEvent.SetTitle -&gt; viewModel.setTitle(event.title) is MessageScreenEvent.NavigateToMessages -&gt; navigateToMessages(event.contactKey) is MessageScreenEvent.NavigateToNodeDetails -&gt; navigateToNodeDetails(event.nodeNum) MessageScreenEvent.NavigateBack -&gt; onNavigateBack() is MessageScreenEvent.CopyToClipboard -&gt; { clipboardManager.nativeClipboard.setPrimaryClip(ClipData.newPlainText(event.text, event.text)) selectedMessageIds.value = emptySet() } } }</ID>
</CurrentIssues>