Skip to content

Commit

Permalink
feat: show lock icon for nodes with public keys 🔒
Browse files Browse the repository at this point in the history
  • Loading branch information
andrekir committed Sep 16, 2024
1 parent 092ed32 commit 2488699
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 28 deletions.
5 changes: 3 additions & 2 deletions app/src/main/java/com/geeksville/mesh/model/UIState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.database.MeshLogRepository
import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.database.QuickChatActionRepository
import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.database.entity.Packet
import com.geeksville.mesh.database.entity.QuickChatAction
import com.geeksville.mesh.database.entity.toNodeInfo
Expand Down Expand Up @@ -229,9 +230,9 @@ class UIViewModel @Inject constructor(
)

@OptIn(ExperimentalCoroutinesApi::class)
val nodeList: StateFlow<List<NodeInfo>> = nodesUiState.flatMapLatest { state ->
val nodeList: StateFlow<List<NodeEntity>> = nodesUiState.flatMapLatest { state ->
nodeDB.getNodes(state.sort, state.filter, state.includeUnknown)
}.mapLatest { list -> list.map { it.toNodeInfo() } }.stateIn(
}.stateIn(
scope = viewModelScope,
started = Eagerly,
initialValue = emptyList(),
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ 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
Expand Down Expand Up @@ -294,9 +295,9 @@ class MessagesFragment : Fragment(), Logging {
}

private fun openNodeInfo(msg: Message) = lifecycleScope.launch {
model.nodeList.firstOrNull()?.find { it.user?.id == msg.user.id }?.let { node ->
model.nodeList.firstOrNull()?.find { it.user.id == msg.user.id }?.let { node ->
parentFragmentManager.popBackStack()
model.focusUserNode(node)
model.focusUserNode(node.toNodeInfo())
}
}
}
8 changes: 5 additions & 3 deletions app/src/main/java/com/geeksville/mesh/ui/NodeInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ fun NodeInfo(
blinking: Boolean = false,
expanded: Boolean = false,
currentTimeMillis: Long,
hasPublicKey: Boolean = false,
) {
val isUnknownUser = thatNodeInfo.user?.hwModel == MeshProtos.HardwareModel.UNSET
val unknownShortName = stringResource(id = R.string.unknown_node_short_name)
val unknownLongName = stringResource(id = R.string.unknown_username)
val longName = thatNodeInfo.user?.longName ?: stringResource(id = R.string.unknown_username)

val nodeName = thatNodeInfo.user?.longName ?: unknownLongName
val nodeName = if (hasPublicKey) "🔒 $longName" else longName
val isThisNode = thisNodeInfo?.num == thatNodeInfo.num
val distance = thisNodeInfo?.distanceStr(thatNodeInfo, distanceUnits)
val (textColor, nodeColor) = thatNodeInfo.colors
Expand All @@ -101,7 +103,7 @@ fun NodeInfo(
label = "blinking node"
)

val style = if (thatNodeInfo.user?.hwModel == MeshProtos.HardwareModel.UNSET) {
val style = if (isUnknownUser) {
LocalTextStyle.current.copy(fontStyle = FontStyle.Italic)
} else {
LocalTextStyle.current
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/com/geeksville/mesh/ui/NodeMenu.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import android.view.Gravity
import android.view.MenuItem
import android.view.View
import androidx.appcompat.widget.PopupMenu
import com.geeksville.mesh.NodeInfo
import com.geeksville.mesh.R
import com.geeksville.mesh.database.entity.NodeEntity
import com.google.android.material.dialog.MaterialAlertDialogBuilder

internal fun View.nodeMenu(
node: NodeInfo,
node: NodeEntity,
ignoreIncomingList: List<Int>,
isOurNode: Boolean = false,
isManaged: Boolean = false,
Expand Down Expand Up @@ -43,7 +43,7 @@ internal fun View.nodeMenu(
val message = if (isIgnored) R.string.ignore_remove else R.string.ignore_add
MaterialAlertDialogBuilder(context)
.setTitle(R.string.ignore)
.setMessage(context.getString(message, node.user?.longName))
.setMessage(context.getString(message, node.user.longName))
.setNeutralButton(R.string.cancel) { _, _ -> }
.setPositiveButton(R.string.send) { _, _ ->
item.onMenuItemAction()
Expand Down
39 changes: 22 additions & 17 deletions app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import androidx.compose.ui.unit.dp
import androidx.fragment.app.activityViewModels
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.NodeInfo
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
Expand All @@ -36,7 +38,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {

private val model: UIViewModel by activityViewModels()

private fun popup(node: NodeInfo) {
private fun popup(node: NodeEntity) {
if (!model.isConnected()) return
val isOurNode = node.num == model.myNodeNum
val ignoreIncomingList = model.ignoreIncomingList
Expand Down Expand Up @@ -77,30 +79,31 @@ class UsersFragment : ScreenFragment("Users"), Logging {
}

R.id.remote_admin -> {
navigateToRadioConfig(node)
navigateToRadioConfig(node.num)
}

R.id.metrics -> {
navigateToMetrics(node)
navigateToMetrics(node.num)
}
}
}
}

private fun navigateToMessages(node: NodeInfo) = node.user?.let { user ->
val contactKey = "${node.channel}${user.id}"
private fun navigateToMessages(node: NodeEntity) = node.user.let { user ->
val channel = if (user.publicKey.isEmpty) node.channel else DataPacket.PKC_CHANNEL_INDEX
val contactKey = "$channel${user.id}"
info("calling MessagesFragment filter: $contactKey")
parentFragmentManager.navigateToMessages(contactKey, user.longName)
}

private fun navigateToRadioConfig(node: NodeInfo) {
info("calling RadioConfig --> destNum: ${node.num}")
parentFragmentManager.navigateToRadioConfig(node.num)
private fun navigateToRadioConfig(nodeNum: Int) {
info("calling RadioConfig --> destNum: $nodeNum")
parentFragmentManager.navigateToRadioConfig(nodeNum)
}

private fun navigateToMetrics(node: NodeInfo) {
info("calling Metrics --> destNum: ${node.num}")
parentFragmentManager.navigateToMetrics(node.num)
private fun navigateToMetrics(nodeNum: Int) {
info("calling Metrics --> destNum: $nodeNum")
parentFragmentManager.navigateToMetrics(nodeNum)
}


Expand All @@ -124,7 +127,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {
@Composable
fun NodesScreen(
model: UIViewModel = hiltViewModel(),
chipClicked: (NodeInfo) -> Unit,
chipClicked: (NodeEntity) -> Unit,
) {
val focusManager = LocalFocusManager.current
val state by model.nodesUiState.collectAsStateWithLifecycle()
Expand All @@ -136,7 +139,7 @@ fun NodesScreen(
val focusedNode by model.focusedNode.collectAsStateWithLifecycle()
LaunchedEffect(focusedNode) {
focusedNode?.let { node ->
val index = nodes.indexOfFirst { it == node }
val index = nodes.indexOfFirst { it.num == node.num }
if (index != -1) {
listState.animateScrollToItem(index)
}
Expand Down Expand Up @@ -167,9 +170,10 @@ fun NodesScreen(
}

items(nodes, key = { it.num }) { node ->
val nodeInfo = node.toNodeInfo()
NodeInfo(
thisNodeInfo = ourNodeInfo,
thatNodeInfo = node,
thatNodeInfo = nodeInfo,
gpsFormat = state.gpsFormat,
distanceUnits = state.distanceUnits,
tempInFahrenheit = state.tempInFahrenheit,
Expand All @@ -178,9 +182,10 @@ fun NodesScreen(
focusManager.clearFocus()
chipClicked(node)
},
blinking = node == focusedNode,
blinking = nodeInfo == focusedNode,
expanded = state.showDetails,
currentTimeMillis = currentTimeMillis
currentTimeMillis = currentTimeMillis,
hasPublicKey = !node.user.publicKey.isEmpty
)
}
}
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/java/com/geeksville/mesh/ui/map/MapFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.geeksville.mesh.android.hasGps
import com.geeksville.mesh.android.hasLocationPermission
import com.geeksville.mesh.copy
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
Expand All @@ -59,6 +60,8 @@ 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.MapEventsReceiver
Expand Down Expand Up @@ -299,7 +302,10 @@ fun MapView(
if (permissions.entries.all { it.value }) map.toggleMyLocation()
}

val nodes by model.nodeList.collectAsStateWithLifecycle()
@OptIn(ExperimentalCoroutinesApi::class)
val nodes by model.nodeList
.mapLatest { list -> list.map { it.toNodeInfo() } }
.collectAsStateWithLifecycle(emptyList())
val waypoints by model.waypoints.collectAsStateWithLifecycle(emptyMap())

var showDownloadButton: Boolean by remember { mutableStateOf(false) }
Expand Down

0 comments on commit 2488699

Please sign in to comment.