mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-05-07 14:16:28 -04:00
refactor: extract NodeMenu from UsersFragment
This commit is contained in:
@@ -265,6 +265,7 @@ class UIViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun requestTraceroute(destNum: Int) {
|
||||
info("Requesting traceroute for '$destNum'")
|
||||
try {
|
||||
val packetId = meshService?.packetId ?: return
|
||||
meshService?.requestTraceroute(packetId, destNum)
|
||||
@@ -274,16 +275,18 @@ class UIViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun removeNode(nodeNum: Int) = viewModelScope.launch(Dispatchers.IO) {
|
||||
info("Removing node '$nodeNum'")
|
||||
try {
|
||||
val packetId = meshService?.packetId ?: return@launch
|
||||
meshService?.removeByNodenum(packetId, nodeNum)
|
||||
nodeDB.deleteNode(nodeNum)
|
||||
} catch (ex: RemoteException) {
|
||||
errormsg("Request traceroute error: ${ex.message}")
|
||||
errormsg("Remove node error: ${ex.message}")
|
||||
}
|
||||
}
|
||||
|
||||
fun requestPosition(destNum: Int, position: Position = Position(0.0, 0.0, 0)) {
|
||||
info("Requesting position for '$destNum'")
|
||||
try {
|
||||
meshService?.requestPosition(destNum, position)
|
||||
} catch (ex: RemoteException) {
|
||||
|
||||
62
app/src/main/java/com/geeksville/mesh/ui/NodeMenu.kt
Normal file
62
app/src/main/java/com/geeksville/mesh/ui/NodeMenu.kt
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.geeksville.mesh.ui
|
||||
|
||||
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.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
||||
internal fun View.nodeMenu(
|
||||
node: NodeInfo,
|
||||
ignoreIncomingList: List<Int>,
|
||||
isOurNode: Boolean = false,
|
||||
showAdmin: Boolean = false,
|
||||
isManaged: Boolean = false,
|
||||
onMenuItemAction: MenuItem.() -> Unit,
|
||||
) = PopupMenu(context, this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0).apply {
|
||||
val isIgnored = ignoreIncomingList.contains(node.num)
|
||||
|
||||
inflate(R.menu.menu_nodes)
|
||||
menu.apply {
|
||||
setGroupVisible(R.id.group_remote, !isOurNode)
|
||||
setGroupVisible(R.id.group_admin, showAdmin)
|
||||
setGroupEnabled(R.id.group_admin, !isManaged)
|
||||
findItem(R.id.ignore).apply {
|
||||
isEnabled = isIgnored || ignoreIncomingList.size < 3
|
||||
isChecked = isIgnored
|
||||
}
|
||||
}
|
||||
setOnMenuItemClickListener { item ->
|
||||
when (item.itemId) {
|
||||
R.id.remove -> {
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.remove)
|
||||
.setMessage(R.string.remove_node_text)
|
||||
.setNeutralButton(R.string.cancel) { _, _ -> }
|
||||
.setPositiveButton(R.string.send) { _, _ ->
|
||||
item.onMenuItemAction()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
R.id.ignore -> {
|
||||
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))
|
||||
.setNeutralButton(R.string.cancel) { _, _ -> }
|
||||
.setPositiveButton(R.string.send) { _, _ ->
|
||||
item.onMenuItemAction()
|
||||
}
|
||||
.show()
|
||||
item.isChecked = !item.isChecked
|
||||
}
|
||||
|
||||
else -> item.onMenuItemAction()
|
||||
}
|
||||
true
|
||||
}
|
||||
show()
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -34,7 +31,6 @@ import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.ui.components.NodeFilterTextField
|
||||
import com.geeksville.mesh.ui.theme.AppTheme
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -43,82 +39,63 @@ class UsersFragment : ScreenFragment("Users"), Logging {
|
||||
|
||||
private val model: UIViewModel by activityViewModels()
|
||||
|
||||
private fun popup(view: View, node: NodeInfo) {
|
||||
private fun popup(node: NodeInfo) {
|
||||
if (!model.isConnected()) return
|
||||
val user = node.user ?: return
|
||||
val isOurNode = node.num == model.myNodeNum
|
||||
val showAdmin = isOurNode || model.hasAdminChannel
|
||||
val ignoreIncomingList = model.ignoreIncomingList
|
||||
val isIgnored = ignoreIncomingList.contains(node.num)
|
||||
val popup =
|
||||
PopupMenu(view.context, view, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0)
|
||||
popup.inflate(R.menu.menu_nodes)
|
||||
popup.menu.setGroupVisible(R.id.group_remote, !isOurNode)
|
||||
popup.menu.setGroupVisible(R.id.group_admin, showAdmin)
|
||||
popup.menu.setGroupEnabled(R.id.group_admin, !model.isManaged)
|
||||
popup.menu.findItem(R.id.ignore).apply {
|
||||
isEnabled = isIgnored || ignoreIncomingList.size < 3
|
||||
isChecked = isIgnored
|
||||
}
|
||||
popup.setOnMenuItemClickListener { item: MenuItem ->
|
||||
when (item.itemId) {
|
||||
|
||||
requireView().nodeMenu(
|
||||
node = node,
|
||||
ignoreIncomingList = ignoreIncomingList,
|
||||
isOurNode = isOurNode,
|
||||
showAdmin = isOurNode || model.hasAdminChannel,
|
||||
isManaged = model.isManaged,
|
||||
) {
|
||||
when (itemId) {
|
||||
R.id.direct_message -> {
|
||||
val contactKey = "${node.channel}${user.id}"
|
||||
debug("calling MessagesFragment filter: $contactKey")
|
||||
parentFragmentManager.navigateToMessages(contactKey, user.longName)
|
||||
navigateToMessages(node)
|
||||
}
|
||||
|
||||
R.id.request_position -> {
|
||||
debug("requesting position for '${user.longName}'")
|
||||
model.requestPosition(node.num)
|
||||
}
|
||||
|
||||
R.id.traceroute -> {
|
||||
debug("requesting traceroute for '${user.longName}'")
|
||||
model.requestTraceroute(node.num)
|
||||
}
|
||||
|
||||
R.id.remove -> {
|
||||
MaterialAlertDialogBuilder(view.context)
|
||||
.setTitle(R.string.remove)
|
||||
.setMessage(getString(R.string.remove_node_text))
|
||||
.setNeutralButton(R.string.cancel) { _, _ -> }
|
||||
.setPositiveButton(R.string.send) { _, _ ->
|
||||
debug("removing node '${user.longName}'")
|
||||
model.removeNode(node.num)
|
||||
}
|
||||
.show()
|
||||
model.removeNode(node.num)
|
||||
}
|
||||
|
||||
R.id.ignore -> {
|
||||
val message = if (isIgnored) R.string.ignore_remove else R.string.ignore_add
|
||||
MaterialAlertDialogBuilder(view.context)
|
||||
.setTitle(R.string.ignore)
|
||||
.setMessage(getString(message, user.longName))
|
||||
.setNeutralButton(R.string.cancel) { _, _ -> }
|
||||
.setPositiveButton(R.string.send) { _, _ ->
|
||||
model.ignoreIncomingList = ignoreIncomingList.toMutableList().apply {
|
||||
if (isIgnored) {
|
||||
debug("removed '${user.longName}' from ignore list")
|
||||
remove(node.num)
|
||||
} else {
|
||||
debug("added '${user.longName}' to ignore list")
|
||||
add(node.num)
|
||||
}
|
||||
}
|
||||
item.isChecked = !item.isChecked
|
||||
model.ignoreIncomingList = ignoreIncomingList.toMutableList().apply {
|
||||
if (contains(node.num)) {
|
||||
debug("removed '${node.num}' from ignore list")
|
||||
remove(node.num)
|
||||
} else {
|
||||
debug("added '${node.num}' to ignore list")
|
||||
add(node.num)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
R.id.remote_admin -> {
|
||||
debug("calling remote admin --> destNum: ${node.num.toUInt()}")
|
||||
parentFragmentManager.navigateToRadioConfig(node.num)
|
||||
navigateToRadioConfig(node)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
popup.show()
|
||||
}
|
||||
|
||||
private fun navigateToMessages(node: NodeInfo) = node.user?.let { user ->
|
||||
val contactKey = "${node.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)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
@@ -130,7 +107,7 @@ class UsersFragment : ScreenFragment("Users"), Logging {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setContent {
|
||||
AppTheme {
|
||||
NodesScreen(model = model, onClick = { popup(requireView(), it) })
|
||||
NodesScreen(model = model, onClick = ::popup)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user