feat(ios): add native app foundation and unsigned ipa build
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import Foundation
|
||||
|
||||
@MainActor
|
||||
final class FleetViewModel: ObservableObject {
|
||||
struct Row: Equatable, Identifiable {
|
||||
let id: UUID
|
||||
var instance: Instance
|
||||
var status: ConnectionStatus
|
||||
var testing: Bool
|
||||
}
|
||||
|
||||
@Published var rows: [Row] = []
|
||||
@Published var searchText = ""
|
||||
@Published var selectedIDs: Set<UUID> = []
|
||||
@Published var selectionMode = false
|
||||
@Published var isLoading = false
|
||||
@Published var errorMessage: String?
|
||||
@Published var showingForm = false
|
||||
|
||||
private let repository: any InstanceRepository
|
||||
private let probe: ConnectionProbe
|
||||
private let credentials: any CredentialStore
|
||||
|
||||
init(
|
||||
repository: any InstanceRepository,
|
||||
probe: ConnectionProbe,
|
||||
credentials: any CredentialStore
|
||||
) {
|
||||
self.repository = repository
|
||||
self.probe = probe
|
||||
self.credentials = credentials
|
||||
}
|
||||
|
||||
func refresh() async {
|
||||
isLoading = true
|
||||
errorMessage = nil
|
||||
do {
|
||||
let query = InstanceQuery(search: searchText.isEmpty ? nil : searchText)
|
||||
let instances = try await repository.list(query)
|
||||
rows = instances.map {
|
||||
Row(id: $0.id, instance: $0, status: .unknown, testing: true)
|
||||
}
|
||||
await withTaskGroup(of: Void.self) { group in
|
||||
for instance in instances {
|
||||
group.addTask { [probe] in
|
||||
let result = try? await probe.test(instance)
|
||||
await self.applyProbe(instance.id, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
errorMessage = "无法刷新节点列表"
|
||||
}
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
func add(_ input: InstanceInput) async throws {
|
||||
let created = try await repository.create(input)
|
||||
if let password = input.password, !password.isEmpty {
|
||||
try credentials.set(instanceID: created.id, password: password)
|
||||
}
|
||||
showingForm = false
|
||||
await refresh()
|
||||
}
|
||||
|
||||
func delete(_ ids: [UUID]) async {
|
||||
for id in ids {
|
||||
if let row = rows.first(where: { $0.id == id }) {
|
||||
do {
|
||||
try await repository.delete(id, expectedRevision: row.instance.configRevision)
|
||||
try credentials.remove(instanceID: id)
|
||||
} catch {
|
||||
errorMessage = "删除 \(row.instance.name) 失败"
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedIDs.removeAll()
|
||||
selectionMode = false
|
||||
await refresh()
|
||||
}
|
||||
|
||||
private func applyProbe(_ id: UUID, _ result: ConnectionResult?) {
|
||||
guard let index = rows.firstIndex(where: { $0.id == id }) else { return }
|
||||
rows[index].status = result?.status ?? .unknown
|
||||
rows[index].testing = false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user