133 lines
4.6 KiB
Swift
133 lines
4.6 KiB
Swift
import Libbox
|
|
import Library
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
public class GroupListViewModel: BaseViewModel {
|
|
@Published public var groups: [OutboundGroup] = []
|
|
|
|
private var pendingSelections: [String: String] = [:]
|
|
|
|
override public init() {
|
|
super.init()
|
|
isLoading = true
|
|
}
|
|
|
|
public func connect() {
|
|
if Variant.screenshotMode {
|
|
groups = [
|
|
OutboundGroup(tag: "my_group", type: "selector", selected: "server", selectable: true, isExpand: true, items: [
|
|
OutboundGroupItem(tag: "server", type: "Shadowsocks", urlTestTime: .now, urlTestDelay: 10),
|
|
OutboundGroupItem(tag: "server2", type: "WireGuard", urlTestTime: .now, urlTestDelay: 20),
|
|
OutboundGroupItem(tag: "auto", type: "URLTest", urlTestTime: .now, urlTestDelay: 30),
|
|
]),
|
|
OutboundGroup(tag: "Auto", type: "urltest", selected: "Tokyo", selectable: true, isExpand: false, items: [
|
|
OutboundGroupItem(tag: "Tokyo", type: "Shadowsocks", urlTestTime: .now, urlTestDelay: 10),
|
|
OutboundGroupItem(tag: "Singapore", type: "VMess", urlTestTime: .now, urlTestDelay: 20),
|
|
OutboundGroupItem(tag: "Hong Kong", type: "Trojan", urlTestTime: .now, urlTestDelay: 15),
|
|
]),
|
|
]
|
|
isLoading = false
|
|
}
|
|
}
|
|
|
|
public func setGroups(_ goGroups: [LibboxOutboundGroup]?) {
|
|
guard let goGroups else { return }
|
|
|
|
let existingGroups = Dictionary(uniqueKeysWithValues: groups.map { ($0.tag, $0) })
|
|
|
|
var newGroups = [OutboundGroup]()
|
|
for goGroup in goGroups {
|
|
var items = [OutboundGroupItem]()
|
|
let itemIterator = goGroup.getItems()!
|
|
while itemIterator.hasNext() {
|
|
let goItem = itemIterator.next()!
|
|
items.append(OutboundGroupItem(
|
|
tag: goItem.tag,
|
|
type: goItem.type,
|
|
urlTestTime: Date(timeIntervalSince1970: Double(goItem.urlTestTime)),
|
|
urlTestDelay: UInt16(goItem.urlTestDelay)
|
|
))
|
|
}
|
|
|
|
var selected = goGroup.selected
|
|
if let pending = pendingSelections[goGroup.tag] {
|
|
if goGroup.selected == pending {
|
|
pendingSelections.removeValue(forKey: goGroup.tag)
|
|
} else {
|
|
selected = pending
|
|
}
|
|
}
|
|
|
|
let isExpand = existingGroups[goGroup.tag]?.isExpand ?? goGroup.isExpand
|
|
|
|
newGroups.append(OutboundGroup(
|
|
tag: goGroup.tag,
|
|
type: goGroup.type,
|
|
selected: selected,
|
|
selectable: goGroup.selectable,
|
|
isExpand: isExpand,
|
|
items: items
|
|
))
|
|
}
|
|
groups = newGroups
|
|
isLoading = false
|
|
}
|
|
|
|
public func selectOutbound(groupTag: String, outboundTag: String) {
|
|
if let index = groups.firstIndex(where: { $0.tag == groupTag }) {
|
|
groups[index].selected = outboundTag
|
|
}
|
|
pendingSelections[groupTag] = outboundTag
|
|
|
|
Task {
|
|
await doSelectOutbound(groupTag: groupTag, outboundTag: outboundTag)
|
|
}
|
|
}
|
|
|
|
private nonisolated func doSelectOutbound(groupTag: String, outboundTag: String) async {
|
|
do {
|
|
try await LibboxNewStandaloneCommandClient()!.selectOutbound(groupTag, outboundTag: outboundTag)
|
|
} catch {
|
|
await MainActor.run {
|
|
alert = AlertState(error: error)
|
|
}
|
|
}
|
|
}
|
|
|
|
public func toggleExpand(groupTag: String) {
|
|
guard let index = groups.firstIndex(where: { $0.tag == groupTag }) else { return }
|
|
groups[index].isExpand.toggle()
|
|
let isExpand = groups[index].isExpand
|
|
Task {
|
|
await setGroupExpand(tag: groupTag, isExpand: isExpand)
|
|
}
|
|
}
|
|
|
|
private nonisolated func setGroupExpand(tag: String, isExpand: Bool) async {
|
|
do {
|
|
try await LibboxNewStandaloneCommandClient()!.setGroupExpand(tag, isExpand: isExpand)
|
|
} catch {
|
|
await MainActor.run {
|
|
alert = AlertState(error: error)
|
|
}
|
|
}
|
|
}
|
|
|
|
public func performURLTest(_ tag: String) {
|
|
Task {
|
|
await doURLTest(tag: tag)
|
|
}
|
|
}
|
|
|
|
private nonisolated func doURLTest(tag: String) async {
|
|
do {
|
|
try await LibboxNewStandaloneCommandClient()!.urlTest(tag)
|
|
} catch {
|
|
await MainActor.run {
|
|
alert = AlertState(error: error)
|
|
}
|
|
}
|
|
}
|
|
}
|