Add connection info footer
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package com.hiddify.hiddify
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.Gson
|
||||
import com.hiddify.hiddify.utils.CommandClient
|
||||
import com.hiddify.hiddify.utils.ParsedOutboundGroup
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.nekohasekai.libbox.OutboundGroup
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
|
||||
class ActiveGroupsChannel(private val scope: CoroutineScope) : FlutterPlugin,
|
||||
CommandClient.Handler {
|
||||
companion object {
|
||||
const val TAG = "A/ActiveGroupsChannel"
|
||||
const val CHANNEL = "com.hiddify.app/active-groups"
|
||||
val gson = Gson()
|
||||
}
|
||||
|
||||
private val client =
|
||||
CommandClient(scope, CommandClient.ConnectionType.GroupOnly, this)
|
||||
|
||||
private var channel: EventChannel? = null
|
||||
private var event: EventChannel.EventSink? = null
|
||||
|
||||
override fun updateGroups(groups: List<OutboundGroup>) {
|
||||
MainActivity.instance.runOnUiThread {
|
||||
val parsedGroups = groups.map { group -> ParsedOutboundGroup.fromOutbound(group) }
|
||||
event?.success(gson.toJson(parsedGroups))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel = EventChannel(
|
||||
flutterPluginBinding.binaryMessenger,
|
||||
CHANNEL
|
||||
)
|
||||
|
||||
channel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
event = events
|
||||
Log.d(TAG, "connecting active groups command client")
|
||||
client.connect()
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
event = null
|
||||
Log.d(TAG, "disconnecting active groups command client")
|
||||
client.disconnect()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
event = null
|
||||
client.disconnect()
|
||||
channel?.setStreamHandler(null)
|
||||
}
|
||||
}
|
||||
@@ -2,85 +2,57 @@ package com.hiddify.hiddify
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.hiddify.hiddify.utils.CommandClient
|
||||
import com.hiddify.hiddify.utils.ParsedOutboundGroup
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.nekohasekai.libbox.OutboundGroup
|
||||
import io.nekohasekai.libbox.OutboundGroupItem
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
class GroupsChannel(private val scope: CoroutineScope) : FlutterPlugin, CommandClient.Handler {
|
||||
companion object {
|
||||
const val TAG = "A/GroupsChannel"
|
||||
const val GROUP_CHANNEL = "com.hiddify.app/groups"
|
||||
const val CHANNEL = "com.hiddify.app/groups"
|
||||
val gson = Gson()
|
||||
}
|
||||
|
||||
private val commandClient =
|
||||
private val client =
|
||||
CommandClient(scope, CommandClient.ConnectionType.Groups, this)
|
||||
|
||||
private var groupsChannel: EventChannel? = null
|
||||
|
||||
private var groupsEvent: EventChannel.EventSink? = null
|
||||
private var channel: EventChannel? = null
|
||||
private var event: EventChannel.EventSink? = null
|
||||
|
||||
override fun updateGroups(groups: List<OutboundGroup>) {
|
||||
MainActivity.instance.runOnUiThread {
|
||||
val kGroups = groups.map { group -> KOutboundGroup.fromOutbound(group) }
|
||||
groupsEvent?.success(gson.toJson(kGroups))
|
||||
val parsedGroups = groups.map { group -> ParsedOutboundGroup.fromOutbound(group) }
|
||||
event?.success(gson.toJson(parsedGroups))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
groupsChannel = EventChannel(
|
||||
channel = EventChannel(
|
||||
flutterPluginBinding.binaryMessenger,
|
||||
GROUP_CHANNEL
|
||||
CHANNEL
|
||||
)
|
||||
|
||||
groupsChannel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
channel!!.setStreamHandler(object : EventChannel.StreamHandler {
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
groupsEvent = events
|
||||
event = events
|
||||
Log.d(TAG, "connecting groups command client")
|
||||
commandClient.connect()
|
||||
client.connect()
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
groupsEvent = null
|
||||
event = null
|
||||
Log.d(TAG, "disconnecting groups command client")
|
||||
commandClient.disconnect()
|
||||
client.disconnect()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
groupsEvent = null
|
||||
commandClient.disconnect()
|
||||
groupsChannel?.setStreamHandler(null)
|
||||
}
|
||||
|
||||
data class KOutboundGroup(
|
||||
@SerializedName("tag") val tag: String,
|
||||
@SerializedName("type") val type: String,
|
||||
@SerializedName("selected") val selected: String,
|
||||
@SerializedName("items") val items: List<KOutboundGroupItem>
|
||||
) {
|
||||
companion object {
|
||||
fun fromOutbound(group: OutboundGroup): KOutboundGroup {
|
||||
val outboundItems = group.items
|
||||
val items = mutableListOf<KOutboundGroupItem>()
|
||||
while (outboundItems.hasNext()) {
|
||||
items.add(KOutboundGroupItem(outboundItems.next()))
|
||||
}
|
||||
return KOutboundGroup(group.tag, group.type, group.selected, items)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class KOutboundGroupItem(
|
||||
@SerializedName("tag") val tag: String,
|
||||
@SerializedName("type") val type: String,
|
||||
@SerializedName("url-test-delay") val urlTestDelay: Int,
|
||||
) {
|
||||
constructor(item: OutboundGroupItem) : this(item.tag, item.type, item.urlTestDelay)
|
||||
event = null
|
||||
client.disconnect()
|
||||
channel?.setStreamHandler(null)
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ class MainActivity : FlutterFragmentActivity(), ServiceConnection.Callback {
|
||||
flutterEngine.plugins.add(EventHandler())
|
||||
flutterEngine.plugins.add(LogHandler())
|
||||
flutterEngine.plugins.add(GroupsChannel(lifecycleScope))
|
||||
flutterEngine.plugins.add(ActiveGroupsChannel(lifecycleScope))
|
||||
flutterEngine.plugins.add(StatsChannel(lifecycleScope))
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ open class CommandClient(
|
||||
) {
|
||||
|
||||
enum class ConnectionType {
|
||||
Status, Groups, Log, ClashMode
|
||||
Status, Groups, Log, ClashMode, GroupOnly
|
||||
}
|
||||
|
||||
interface Handler {
|
||||
@@ -50,6 +50,7 @@ open class CommandClient(
|
||||
ConnectionType.Groups -> Libbox.CommandGroup
|
||||
ConnectionType.Log -> Libbox.CommandLog
|
||||
ConnectionType.ClashMode -> Libbox.CommandClashMode
|
||||
ConnectionType.GroupOnly -> Libbox.CommandGroupInfoOnly
|
||||
}
|
||||
options.statusInterval = 2 * 1000 * 1000 * 1000
|
||||
val commandClient = CommandClient(clientHandler, options)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.hiddify.hiddify.utils
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import io.nekohasekai.libbox.OutboundGroup
|
||||
import io.nekohasekai.libbox.OutboundGroupItem
|
||||
|
||||
data class ParsedOutboundGroup(
|
||||
@SerializedName("tag") val tag: String,
|
||||
@SerializedName("type") val type: String,
|
||||
@SerializedName("selected") val selected: String,
|
||||
@SerializedName("items") val items: List<ParsedOutboundGroupItem>
|
||||
) {
|
||||
companion object {
|
||||
fun fromOutbound(group: OutboundGroup): ParsedOutboundGroup {
|
||||
val outboundItems = group.items
|
||||
val items = mutableListOf<ParsedOutboundGroupItem>()
|
||||
while (outboundItems.hasNext()) {
|
||||
items.add(ParsedOutboundGroupItem(outboundItems.next()))
|
||||
}
|
||||
return ParsedOutboundGroup(group.tag, group.type, group.selected, items)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class ParsedOutboundGroupItem(
|
||||
@SerializedName("tag") val tag: String,
|
||||
@SerializedName("type") val type: String,
|
||||
@SerializedName("url-test-delay") val urlTestDelay: Int,
|
||||
) {
|
||||
constructor(item: OutboundGroupItem) : this(item.tag, item.type, item.urlTestDelay)
|
||||
}
|
||||
Reference in New Issue
Block a user