mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: Display relay node information for messages (#3574)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
7d1c5cba4c
commit
453dd398d4
10 changed files with 840 additions and 16 deletions
|
|
@ -18,6 +18,7 @@
|
|||
package org.meshtastic.feature.messaging
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
|
|
@ -40,6 +41,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
|
|
@ -50,6 +52,7 @@ import kotlinx.coroutines.FlowPreview
|
|||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.database.entity.Reaction
|
||||
import org.meshtastic.core.database.model.Message
|
||||
import org.meshtastic.core.database.model.Node
|
||||
|
|
@ -62,6 +65,7 @@ import org.meshtastic.feature.messaging.component.ReactionDialog
|
|||
fun DeliveryInfo(
|
||||
@StringRes title: Int,
|
||||
@StringRes text: Int? = null,
|
||||
relayNodeName: String? = null,
|
||||
onConfirm: (() -> Unit) = {},
|
||||
onDismiss: () -> Unit = {},
|
||||
resendOption: Boolean,
|
||||
|
|
@ -88,13 +92,22 @@ fun DeliveryInfo(
|
|||
)
|
||||
},
|
||||
text = {
|
||||
text?.let {
|
||||
Text(
|
||||
text = stringResource(id = it),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
text?.let {
|
||||
Text(
|
||||
text = stringResource(id = it),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
}
|
||||
relayNodeName?.let {
|
||||
Text(
|
||||
text = stringResource(R.string.relayed_by, it),
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
|
|
@ -127,9 +140,16 @@ internal fun MessageList(
|
|||
if (showStatusDialog != null) {
|
||||
val msg = showStatusDialog ?: return
|
||||
val (title, text) = msg.getStatusStringRes()
|
||||
val relayNodeName by
|
||||
remember(msg.relayNode, nodes) {
|
||||
derivedStateOf {
|
||||
msg.relayNode?.let { relayNodeId -> Packet.getRelayNode(relayNodeId, nodes)?.user?.longName }
|
||||
}
|
||||
}
|
||||
DeliveryInfo(
|
||||
title = title,
|
||||
text = text,
|
||||
relayNodeName = relayNodeName,
|
||||
onConfirm = {
|
||||
val deleteList: List<Long> = listOf(msg.uuid)
|
||||
onDeleteMessages(deleteList)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import kotlinx.coroutines.launch
|
|||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.entity.MeshLog
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.model.getTracerouteResponse
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.proto.AdminProtos
|
||||
|
|
@ -181,6 +182,7 @@ class LogFilterManager {
|
|||
log.formattedReceivedDate.contains(filterText, ignoreCase = true) ||
|
||||
(log.decodedPayload?.contains(filterText, ignoreCase = true) == true)
|
||||
}
|
||||
|
||||
FilterMode.AND ->
|
||||
filterTexts.all { filterText ->
|
||||
log.logMessage.contains(filterText, ignoreCase = true) ||
|
||||
|
|
@ -281,14 +283,40 @@ constructor(
|
|||
val decoded = if (hasDecoded) builder.decoded else null
|
||||
if (hasDecoded) builder.clearDecoded()
|
||||
val baseText = builder.build().toString().trimEnd()
|
||||
val result =
|
||||
var result =
|
||||
if (hasDecoded && decoded != null) {
|
||||
val decodedText = decoded.toString().trimEnd().prependIndent(" ")
|
||||
"$baseText\ndecoded {\n$decodedText\n}"
|
||||
} else {
|
||||
baseText
|
||||
}
|
||||
return annotateRawMessage(result, packet.from, packet.to)
|
||||
|
||||
val relayNode = packet.relayNode
|
||||
var relayNodeAnnotation: String? = null
|
||||
val placeholder = "___RELAY_NODE___"
|
||||
|
||||
if (relayNode != 0) {
|
||||
Packet.getRelayNode(relayNode, nodeRepository.nodeDBbyNum.value.values.toList())?.let { node ->
|
||||
val relayId = node.user.id
|
||||
val relayName = node.user.longName
|
||||
val regex = Regex("""\brelay_node: ${relayNode.toUInt()}\b""")
|
||||
if (regex.containsMatchIn(result)) {
|
||||
relayNodeAnnotation = "relay_node: $relayName ($relayId)"
|
||||
result = regex.replace(result, placeholder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = annotateRawMessage(result, packet.from, packet.to)
|
||||
|
||||
if (relayNodeAnnotation != null) {
|
||||
result = result.replace(placeholder, relayNodeAnnotation)
|
||||
} else {
|
||||
// Not annotated with name, so use hex.
|
||||
result = annotateRawMessage(result, relayNode)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/** Annotate the raw message string with the node IDs provided, in hex, if they are present. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue