Refactor to MVVM architecture

This commit is contained in:
世界
2025-11-26 22:25:48 +08:00
parent 61f1036f57
commit b71cbae382
31 changed files with 1551 additions and 1229 deletions
@@ -5,57 +5,38 @@ import SwiftUI
@MainActor
public struct ClashModeView: View {
@Environment(\.scenePhase) private var scenePhase
@StateObject private var commandClient = CommandClient(.clashMode)
@State private var clashMode = ""
@State private var alert: Alert?
@StateObject private var viewModel = ClashModeViewModel()
public init() {}
public var body: some View {
VStack {
if commandClient.clashModeList.count > 1 {
if viewModel.shouldShowPicker {
Picker("", selection: Binding(get: {
clashMode
viewModel.clashMode
}, set: { newMode in
clashMode = newMode
viewModel.clashMode = newMode
Task {
await setClashMode(newMode)
await viewModel.setClashMode(newMode)
}
}), content: {
ForEach(commandClient.clashModeList, id: \.self) { it in
Text(it)
ForEach(viewModel.clashModeList, id: \.self) { mode in
Text(mode)
}
})
.pickerStyle(.segmented)
.padding([.top], 8)
}
}
.onReceive(commandClient.$clashMode) { newMode in
clashMode = newMode
}
.padding([.leading, .trailing])
.onAppear {
commandClient.connect()
viewModel.connect()
}
.onDisappear {
commandClient.disconnect()
viewModel.disconnect()
}
.onChangeCompat(of: scenePhase) { newValue in
if newValue == .active {
commandClient.connect()
} else {
commandClient.disconnect()
}
}
.alertBinding($alert)
}
private nonisolated func setClashMode(_ newMode: String) async {
do {
try LibboxNewStandaloneCommandClient()!.setClashMode(newMode)
} catch {
await MainActor.run {
alert = Alert(error)
}
viewModel.handleScenePhase(newValue)
}
.alertBinding($viewModel.alert)
}
}