Show talk group next to nodes in list (v1.0.4)

- SvxService tracks node->TG mapping learned from talker events
- Own callsign always shown with its current TG
- Protocol carries no TG in join/leave, so others appear once they talk
This commit is contained in:
ua1zbe
2026-08-14 13:32:41 +03:00
parent 9790f9d69c
commit d0c055fec9
3 changed files with 23 additions and 6 deletions

View File

@@ -400,14 +400,21 @@ class MainActivity : Activity(), SvxService.Listener {
} }
private fun showNodesDialog() { private fun showNodesDialog() {
val nodes = (svc?.nodeList() ?: emptyList()).sorted() val nodes = svc?.nodeList().orEmpty()
if (nodes.isEmpty()) { if (nodes.isEmpty()) {
toast(getString(R.string.toast_nodes_empty)) toast(getString(R.string.toast_nodes_empty))
return return
} }
val myCs = settings.callsign.trim()
val items = nodes
.map { (cs, tg) ->
val t = tg ?: if (cs.equals(myCs, ignoreCase = true)) settings.talkGroup else null
if (t != null) getString(R.string.node_with_tg, cs, t) else cs
}
.sorted()
AlertDialog.Builder(this) AlertDialog.Builder(this)
.setTitle(getString(R.string.nodes_title, nodes.size)) .setTitle(getString(R.string.nodes_title, items.size))
.setItems(nodes.toTypedArray(), null) .setItems(items.toTypedArray(), null)
.show() .show()
} }

View File

@@ -121,9 +121,12 @@ class SvxService : Service(), ReflectorClient.Callbacks {
} }
private val nodeSet = LinkedHashSet<String>() private val nodeSet = LinkedHashSet<String>()
private val nodeTgs = HashMap<String, Long>()
/** Текущий список подключенных узлов (копия для UI). */ /** Текущий список узлов и известные группы (копия для UI). */
fun nodeList(): List<String> = synchronized(nodeSet) { nodeSet.toList() } fun nodeList(): List<Pair<String, Long?>> = synchronized(nodeSet) {
nodeSet.map { it to nodeTgs[it] }
}
override fun onNodeJoined(callsign: String, tg: Long?) { override fun onNodeJoined(callsign: String, tg: Long?) {
synchronized(nodeSet) { nodeSet.add(callsign) } synchronized(nodeSet) { nodeSet.add(callsign) }
@@ -131,11 +134,17 @@ class SvxService : Service(), ReflectorClient.Callbacks {
} }
override fun onNodeLeft(callsign: String, tg: Long?) { override fun onNodeLeft(callsign: String, tg: Long?) {
synchronized(nodeSet) { nodeSet.remove(callsign) } synchronized(nodeSet) {
nodeSet.remove(callsign)
nodeTgs.remove(callsign)
}
listener?.onNodeLeft(callsign, tg) listener?.onNodeLeft(callsign, tg)
} }
override fun onTalkerStart(tg: Long, callsign: String) { override fun onTalkerStart(tg: Long, callsign: String) {
synchronized(nodeSet) {
if (callsign in nodeSet) nodeTgs[callsign] = tg
}
updateNotification(getString(R.string.notif_talking, callsign)) updateNotification(getString(R.string.notif_talking, callsign))
listener?.onTalkerStart(tg, callsign) listener?.onTalkerStart(tg, callsign)
} }

View File

@@ -18,6 +18,7 @@
<string name="toast_node_joined">Подключился: %1$s%2$s</string> <string name="toast_node_joined">Подключился: %1$s%2$s</string>
<string name="toast_node_left">Отключился: %1$s%2$s</string> <string name="toast_node_left">Отключился: %1$s%2$s</string>
<string name="node_tg_suffix"> (группа %1$d)</string> <string name="node_tg_suffix"> (группа %1$d)</string>
<string name="node_with_tg">%1$s — TG%2$d</string>
<string name="btn_save">Сохранить</string> <string name="btn_save">Сохранить</string>
<string name="app_version">SVXhomyak — v1.0.4</string> <string name="app_version">SVXhomyak — v1.0.4</string>
<string name="saved">Сохранено</string> <string name="saved">Сохранено</string>