137 lines
4.6 KiB
Swift
137 lines
4.6 KiB
Swift
import Foundation
|
|
import Libbox
|
|
import Library
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
public class ProfileViewModel: BaseViewModel {
|
|
@Published public var importRemoteProfileRequest: NewProfileView.ImportRequest?
|
|
@Published public var importRemoteProfilePresented = false
|
|
@Published public var isUpdating = false
|
|
@Published public var profileList: [ProfilePreview] = []
|
|
|
|
#if os(iOS) || os(tvOS)
|
|
@Published public var editMode = EditMode.inactive
|
|
#endif
|
|
|
|
private weak var environments: ExtensionEnvironments?
|
|
|
|
override public init() {
|
|
super.init()
|
|
isLoading = true
|
|
}
|
|
|
|
public func setEnvironments(_ environments: ExtensionEnvironments) {
|
|
self.environments = environments
|
|
}
|
|
|
|
public func createImportProfileDialog(_ profile: LibboxProfileContent) {
|
|
alert = AlertState(
|
|
title: String(localized: "Import Profile"),
|
|
message: String(localized: "Are you sure to import profile \(profile.name)?"),
|
|
primaryButton: .default(String(localized: "Import")) {
|
|
Task {
|
|
do {
|
|
try await profile.importProfile()
|
|
} catch {
|
|
self.alert = AlertState(error: 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 = AlertState(
|
|
title: String(localized: "Import Remote Profile"),
|
|
message: String(localized: "Are you sure to import remote profile \(newValue.name)? You will connect to \(newValue.host) to download the configuration."),
|
|
primaryButton: .default(String(localized: "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 = AlertState(error: 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 = AlertState(error: error)
|
|
}
|
|
}
|
|
}
|
|
|
|
public func deleteProfile(_ profile: Profile) async {
|
|
do {
|
|
_ = try await ProfileManager.delete(profile)
|
|
environments?.profileUpdate.send()
|
|
environments?.emptyProfiles = profileList.isEmpty
|
|
} catch {
|
|
alert = AlertState(error: 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 = AlertState(error: 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 = AlertState(error: error)
|
|
}
|
|
}
|
|
}
|
|
}
|