mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor: move ignore node to is_ignored field in NodeInfo
This commit is contained in:
parent
4a1319a645
commit
1ea55b2209
8 changed files with 585 additions and 59 deletions
|
|
@ -59,8 +59,9 @@ import com.geeksville.mesh.database.entity.ReactionEntity
|
|||
AutoMigration(from = 11, to = 12),
|
||||
AutoMigration(from = 12, to = 13, spec = AutoMigration12to13::class),
|
||||
AutoMigration(from = 13, to = 14),
|
||||
AutoMigration(from = 14, to = 15),
|
||||
],
|
||||
version = 14,
|
||||
version = 15,
|
||||
exportSchema = true,
|
||||
)
|
||||
@TypeConverters(Converters::class)
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ data class NodeEntity(
|
|||
@ColumnInfo(name = "is_favorite")
|
||||
var isFavorite: Boolean = false,
|
||||
|
||||
@ColumnInfo(name = "is_ignored", defaultValue = "0")
|
||||
var isIgnored: Boolean = false,
|
||||
|
||||
@ColumnInfo(name = "environment_metrics", typeAffinity = ColumnInfo.BLOB)
|
||||
var environmentTelemetry: TelemetryProtos.Telemetry = TelemetryProtos.Telemetry.getDefaultInstance(),
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ data class NodesUiState(
|
|||
val gpsFormat: Int = 0,
|
||||
val distanceUnits: Int = 0,
|
||||
val tempInFahrenheit: Boolean = false,
|
||||
val ignoreIncomingList: List<Int> = emptyList(),
|
||||
val showDetails: Boolean = false,
|
||||
) {
|
||||
companion object {
|
||||
|
|
@ -227,7 +226,6 @@ class UIViewModel @Inject constructor(
|
|||
gpsFormat = profile.config.display.gpsFormat.number,
|
||||
distanceUnits = profile.config.display.units.number,
|
||||
tempInFahrenheit = profile.moduleConfig.telemetry.environmentDisplayFahrenheit,
|
||||
ignoreIncomingList = profile.config.lora.ignoreIncomingList,
|
||||
showDetails = showDetails,
|
||||
)
|
||||
}.stateIn(
|
||||
|
|
@ -486,19 +484,11 @@ class UIViewModel @Inject constructor(
|
|||
updateLoraConfig { it.copy { region = value } }
|
||||
}
|
||||
|
||||
fun ignoreNode(nodeNum: Int) = updateLoraConfig {
|
||||
it.copy {
|
||||
val list = ignoreIncoming.toMutableList().apply {
|
||||
if (contains(nodeNum)) {
|
||||
debug("removing node $nodeNum from ignore list")
|
||||
remove(nodeNum)
|
||||
} else {
|
||||
debug("adding node $nodeNum to ignore list")
|
||||
add(nodeNum)
|
||||
}
|
||||
}
|
||||
ignoreIncoming.clear()
|
||||
ignoreIncoming.addAll(list)
|
||||
fun ignoreNode(node: NodeEntity) = viewModelScope.launch {
|
||||
try {
|
||||
radioConfigRepository.onServiceAction(ServiceAction.Ignore(node))
|
||||
} catch (ex: RemoteException) {
|
||||
errormsg("Ignore node error:", ex)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ import javax.inject.Inject
|
|||
import kotlin.math.absoluteValue
|
||||
|
||||
sealed class ServiceAction {
|
||||
data class Ignore(val node: NodeEntity) : ServiceAction()
|
||||
data class Reaction(val emoji: String, val replyId: Int, val contactKey: String) : ServiceAction()
|
||||
}
|
||||
|
||||
|
|
@ -303,6 +304,7 @@ class MeshService : Service(), Logging {
|
|||
.launchIn(serviceScope)
|
||||
radioConfigRepository.serviceAction.onEach { action ->
|
||||
when (action) {
|
||||
is ServiceAction.Ignore -> ignoreNode(action.node)
|
||||
is ServiceAction.Reaction -> sendReaction(action)
|
||||
}
|
||||
}.launchIn(serviceScope)
|
||||
|
|
@ -1453,6 +1455,7 @@ class MeshService : Service(), Logging {
|
|||
-1
|
||||
}
|
||||
it.isFavorite = info.isFavorite
|
||||
it.isIgnored = info.isIgnored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1757,6 +1760,21 @@ class MeshService : Service(), Logging {
|
|||
}
|
||||
}
|
||||
|
||||
private fun ignoreNode(node: NodeEntity) = toRemoteExceptions {
|
||||
sendToRadio(newMeshPacketTo(myNodeNum).buildAdminPacket {
|
||||
if (node.isIgnored) {
|
||||
debug("removing node ${node.num} from ignore list")
|
||||
removeIgnoredNode = node.num
|
||||
} else {
|
||||
debug("adding node ${node.num} to ignore list")
|
||||
setIgnoredNode = node.num
|
||||
}
|
||||
})
|
||||
updateNodeInfo(node.num) {
|
||||
it.isIgnored = !node.isIgnored
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendReaction(reaction: ServiceAction.Reaction) = toRemoteExceptions {
|
||||
// contactKey: unique contact key filter (channel)+(nodeId)
|
||||
val channel = reaction.contactKey[0].digitToInt()
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig
|
|||
import com.geeksville.mesh.MeshProtos
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.database.entity.NodeEntity
|
||||
import com.geeksville.mesh.ui.components.MenuItemAction
|
||||
import com.geeksville.mesh.ui.components.NodeMenuAction
|
||||
import com.geeksville.mesh.ui.components.NodeKeyStatusIcon
|
||||
import com.geeksville.mesh.ui.components.NodeMenu
|
||||
import com.geeksville.mesh.ui.components.SignalInfo
|
||||
|
|
@ -79,13 +79,12 @@ fun NodeItem(
|
|||
gpsFormat: Int,
|
||||
distanceUnits: Int,
|
||||
tempInFahrenheit: Boolean,
|
||||
ignoreIncomingList: List<Int> = emptyList(),
|
||||
menuItemActionClicked: (MenuItemAction) -> Unit = {},
|
||||
onAction: (NodeMenuAction) -> Unit = {},
|
||||
expanded: Boolean = false,
|
||||
currentTimeMillis: Long,
|
||||
isConnected: Boolean = false,
|
||||
) {
|
||||
val isIgnored = ignoreIncomingList.contains(thatNode.num)
|
||||
val isIgnored = thatNode.isIgnored
|
||||
val longName = thatNode.user.longName.ifEmpty { stringResource(id = R.string.unknown_username) }
|
||||
|
||||
val isThisNode = thisNode?.num == thatNode.num
|
||||
|
|
@ -159,12 +158,10 @@ fun NodeItem(
|
|||
}
|
||||
NodeMenu(
|
||||
node = thatNode,
|
||||
ignoreIncomingList = ignoreIncomingList,
|
||||
isThisNode = isThisNode,
|
||||
onMenuItemAction = menuItemActionClicked,
|
||||
showFullMenu = !isThisNode && isConnected,
|
||||
onAction = onAction,
|
||||
expanded = menuExpanded,
|
||||
onDismissRequest = { menuExpanded = false },
|
||||
isConnected = isConnected,
|
||||
)
|
||||
}
|
||||
NodeKeyStatusIcon(
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import com.geeksville.mesh.DataPacket
|
|||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.database.entity.NodeEntity
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.ui.components.MenuItemAction
|
||||
import com.geeksville.mesh.ui.components.NodeMenuAction
|
||||
import com.geeksville.mesh.ui.components.NodeFilterTextField
|
||||
import com.geeksville.mesh.ui.components.rememberTimeTickWithLifecycle
|
||||
import com.geeksville.mesh.ui.message.navigateToMessages
|
||||
|
|
@ -131,16 +131,15 @@ fun NodesScreen(
|
|||
gpsFormat = state.gpsFormat,
|
||||
distanceUnits = state.distanceUnits,
|
||||
tempInFahrenheit = state.tempInFahrenheit,
|
||||
ignoreIncomingList = state.ignoreIncomingList,
|
||||
menuItemActionClicked = { menuItem ->
|
||||
onAction = { menuItem ->
|
||||
when (menuItem) {
|
||||
MenuItemAction.Remove -> model.removeNode(node.num)
|
||||
MenuItemAction.Ignore -> model.ignoreNode(node.num)
|
||||
MenuItemAction.DirectMessage -> navigateToMessages(node)
|
||||
MenuItemAction.RequestUserInfo -> model.requestUserInfo(node.num)
|
||||
MenuItemAction.RequestPosition -> model.requestPosition(node.num)
|
||||
MenuItemAction.TraceRoute -> model.requestTraceroute(node.num)
|
||||
MenuItemAction.MoreDetails -> navigateToNodeDetails(node.num)
|
||||
is NodeMenuAction.Remove -> model.removeNode(node.num)
|
||||
is NodeMenuAction.Ignore -> model.ignoreNode(node)
|
||||
is NodeMenuAction.DirectMessage -> navigateToMessages(node)
|
||||
is NodeMenuAction.RequestUserInfo -> model.requestUserInfo(node.num)
|
||||
is NodeMenuAction.RequestPosition -> model.requestPosition(node.num)
|
||||
is NodeMenuAction.TraceRoute -> model.requestTraceroute(node.num)
|
||||
is NodeMenuAction.MoreDetails -> navigateToNodeDetails(node.num)
|
||||
}
|
||||
},
|
||||
expanded = state.showDetails,
|
||||
|
|
|
|||
|
|
@ -42,26 +42,23 @@ import com.geeksville.mesh.database.entity.NodeEntity
|
|||
@Composable
|
||||
fun NodeMenu(
|
||||
node: NodeEntity,
|
||||
ignoreIncomingList: List<Int>,
|
||||
isThisNode: Boolean = false,
|
||||
onMenuItemAction: (MenuItemAction) -> Unit,
|
||||
showFullMenu: Boolean = false,
|
||||
onDismissRequest: () -> Unit,
|
||||
expanded: Boolean = false,
|
||||
isConnected: Boolean = false,
|
||||
onAction: (NodeMenuAction) -> Unit
|
||||
) {
|
||||
val isIgnored = ignoreIncomingList.contains(node.num)
|
||||
var displayIgnoreDialog by remember { mutableStateOf(false) }
|
||||
var displayRemoveDialog by remember { mutableStateOf(false) }
|
||||
if (displayIgnoreDialog) {
|
||||
SimpleAlertDialog(
|
||||
title = R.string.ignore,
|
||||
text = stringResource(
|
||||
id = if (isIgnored) R.string.ignore_remove else R.string.ignore_add,
|
||||
id = if (node.isIgnored) R.string.ignore_remove else R.string.ignore_add,
|
||||
node.user.longName
|
||||
),
|
||||
onConfirm = {
|
||||
displayIgnoreDialog = false
|
||||
onMenuItemAction(MenuItemAction.Ignore)
|
||||
onAction(NodeMenuAction.Ignore(node))
|
||||
},
|
||||
onDismiss = {
|
||||
displayIgnoreDialog = false
|
||||
|
|
@ -74,7 +71,7 @@ fun NodeMenu(
|
|||
text = R.string.remove_node_text,
|
||||
onConfirm = {
|
||||
displayRemoveDialog = false
|
||||
onMenuItemAction(MenuItemAction.Remove)
|
||||
onAction(NodeMenuAction.Remove(node))
|
||||
},
|
||||
onDismiss = {
|
||||
displayRemoveDialog = false
|
||||
|
|
@ -87,32 +84,32 @@ fun NodeMenu(
|
|||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
|
||||
if (!isThisNode && isConnected) {
|
||||
if (showFullMenu) {
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onMenuItemAction(MenuItemAction.DirectMessage)
|
||||
onAction(NodeMenuAction.DirectMessage(node))
|
||||
},
|
||||
content = { Text(stringResource(R.string.direct_message)) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onMenuItemAction(MenuItemAction.RequestUserInfo)
|
||||
onAction(NodeMenuAction.RequestUserInfo(node))
|
||||
},
|
||||
content = { Text(stringResource(R.string.request_userinfo)) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onMenuItemAction(MenuItemAction.RequestPosition)
|
||||
onAction(NodeMenuAction.RequestPosition(node))
|
||||
},
|
||||
content = { Text(stringResource(R.string.request_position)) }
|
||||
)
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onMenuItemAction(MenuItemAction.TraceRoute)
|
||||
onAction(NodeMenuAction.TraceRoute(node))
|
||||
},
|
||||
content = { Text(stringResource(R.string.traceroute)) }
|
||||
)
|
||||
|
|
@ -121,17 +118,15 @@ fun NodeMenu(
|
|||
onDismissRequest()
|
||||
displayIgnoreDialog = true
|
||||
},
|
||||
enabled = ignoreIncomingList.size < 3 || isIgnored
|
||||
) {
|
||||
Text(stringResource(R.string.ignore))
|
||||
Spacer(Modifier.weight(1f))
|
||||
Checkbox(
|
||||
checked = isIgnored,
|
||||
checked = node.isIgnored,
|
||||
onCheckedChange = {
|
||||
onDismissRequest()
|
||||
displayIgnoreDialog = true
|
||||
},
|
||||
enabled = isIgnored || ignoreIncomingList.size < 3,
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
}
|
||||
|
|
@ -140,25 +135,26 @@ fun NodeMenu(
|
|||
onDismissRequest()
|
||||
displayRemoveDialog = true
|
||||
},
|
||||
enabled = !node.isIgnored,
|
||||
) { Text(stringResource(R.string.remove)) }
|
||||
Divider(Modifier.padding(vertical = 8.dp))
|
||||
}
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onMenuItemAction(MenuItemAction.MoreDetails)
|
||||
onAction(NodeMenuAction.MoreDetails(node))
|
||||
},
|
||||
content = { Text(stringResource(R.string.more_details)) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
enum class MenuItemAction {
|
||||
Remove,
|
||||
Ignore,
|
||||
DirectMessage,
|
||||
RequestUserInfo,
|
||||
RequestPosition,
|
||||
TraceRoute,
|
||||
MoreDetails
|
||||
sealed class NodeMenuAction {
|
||||
data class Remove(val node: NodeEntity) : NodeMenuAction()
|
||||
data class Ignore(val node: NodeEntity) : NodeMenuAction()
|
||||
data class DirectMessage(val node: NodeEntity) : NodeMenuAction()
|
||||
data class RequestUserInfo(val node: NodeEntity) : NodeMenuAction()
|
||||
data class RequestPosition(val node: NodeEntity) : NodeMenuAction()
|
||||
data class TraceRoute(val node: NodeEntity) : NodeMenuAction()
|
||||
data class MoreDetails(val node: NodeEntity) : NodeMenuAction()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue