Refactor to MVVM architecture
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import Foundation
|
||||
import Libbox
|
||||
import Library
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
public class ProfileViewModel: ObservableObject {
|
||||
@Published public var importRemoteProfileRequest: NewProfileView.ImportRequest?
|
||||
@Published public var importRemoteProfilePresented = false
|
||||
@Published public var isLoading = true
|
||||
@Published public var isUpdating = false
|
||||
@Published public var alert: Alert?
|
||||
@Published public var profileList: [ProfilePreview] = []
|
||||
|
||||
#if os(iOS) || os(tvOS)
|
||||
@Published public var editMode = EditMode.inactive
|
||||
#endif
|
||||
|
||||
private weak var environments: ExtensionEnvironments?
|
||||
|
||||
public init() {}
|
||||
|
||||
public func setEnvironments(_ environments: ExtensionEnvironments) {
|
||||
self.environments = environments
|
||||
}
|
||||
|
||||
public func createImportProfileDialog(_ profile: LibboxProfileContent) {
|
||||
alert = Alert(
|
||||
title: Text("Import Profile"),
|
||||
message: Text("Are you sure to import profile \(profile.name)?"),
|
||||
primaryButton: .default(Text("Import")) {
|
||||
Task {
|
||||
do {
|
||||
try await profile.importProfile()
|
||||
} catch {
|
||||
self.alert = Alert(error)
|
||||
return
|
||||
}
|
||||
await self.doReload()
|
||||
self.environments?.emptyProfiles = self.profileList.isEmpty
|
||||
}
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
|
||||
public func createImportRemoteProfileDialog(_ newValue: LibboxImportRemoteProfile) {
|
||||
importRemoteProfileRequest = .init(name: newValue.name, url: newValue.url)
|
||||
alert = Alert(
|
||||
title: Text("Import Remote Profile"),
|
||||
message: Text("Are you sure to import remote profile \(newValue.name)? You will connect to \(newValue.host) to download the configuration."),
|
||||
primaryButton: .default(Text("Import")) {
|
||||
self.importRemoteProfilePresented = true
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
}
|
||||
|
||||
public func doReload() async {
|
||||
defer {
|
||||
isLoading = false
|
||||
}
|
||||
if ApplicationLibrary.inPreview {
|
||||
profileList = [
|
||||
ProfilePreview(Profile(id: 0, name: "profile local", type: .local, path: "")),
|
||||
ProfilePreview(Profile(id: 1, name: "profile remote", type: .remote, path: "", lastUpdated: Date(timeIntervalSince1970: 0))),
|
||||
]
|
||||
} else {
|
||||
do {
|
||||
profileList = try await ProfileManager.list().map { ProfilePreview($0) }
|
||||
} catch {
|
||||
alert = Alert(error)
|
||||
return
|
||||
}
|
||||
}
|
||||
environments?.emptyProfiles = profileList.isEmpty
|
||||
}
|
||||
|
||||
public func updateProfile(_ profile: Profile) async {
|
||||
await updateProfileBackground(profile)
|
||||
isUpdating = false
|
||||
}
|
||||
|
||||
private nonisolated func updateProfileBackground(_ profile: Profile) async {
|
||||
do {
|
||||
_ = try await profile.updateRemoteProfile()
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
alert = Alert(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func deleteProfile(_ profile: Profile) async {
|
||||
do {
|
||||
_ = try await ProfileManager.delete(profile)
|
||||
environments?.profileUpdate.send()
|
||||
environments?.emptyProfiles = profileList.isEmpty
|
||||
} catch {
|
||||
alert = Alert(error)
|
||||
}
|
||||
}
|
||||
|
||||
public func moveProfile(from source: IndexSet, to destination: Int) {
|
||||
profileList.move(fromOffsets: source, toOffset: destination)
|
||||
for (index, profile) in profileList.enumerated() {
|
||||
profileList[index].order = UInt32(index)
|
||||
profile.origin.order = UInt32(index)
|
||||
}
|
||||
Task {
|
||||
do {
|
||||
try await ProfileManager.update(profileList.map(\.origin))
|
||||
environments?.profileUpdate.send()
|
||||
} catch {
|
||||
alert = Alert(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func deleteProfile(where profileIndex: IndexSet) {
|
||||
let profileToDelete = profileIndex.map { index in
|
||||
profileList[index].origin
|
||||
}
|
||||
profileList.remove(atOffsets: profileIndex)
|
||||
Task {
|
||||
do {
|
||||
_ = try await ProfileManager.delete(profileToDelete)
|
||||
environments?.emptyProfiles = profileList.isEmpty
|
||||
environments?.profileUpdate.send()
|
||||
} catch {
|
||||
alert = Alert(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user