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:
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user