|
@@ -35,6 +35,7 @@ struct ContentView: View {
|
|
@StateObject private var releaseHelper = UTMReleaseHelper()
|
|
@StateObject private var releaseHelper = UTMReleaseHelper()
|
|
@State private var newPopupPresented = false
|
|
@State private var newPopupPresented = false
|
|
@State private var openSheetPresented = false
|
|
@State private var openSheetPresented = false
|
|
|
|
+ @State private var alertItem: AlertItem?
|
|
@Environment(\.openURL) var openURL
|
|
@Environment(\.openURL) var openURL
|
|
@AppStorage("ServerAutostart") private var isServerAutostart: Bool = false
|
|
@AppStorage("ServerAutostart") private var isServerAutostart: Bool = false
|
|
|
|
|
|
@@ -50,6 +51,14 @@ struct ContentView: View {
|
|
}, content: {
|
|
}, content: {
|
|
VMReleaseNotesView(helper: releaseHelper).padding()
|
|
VMReleaseNotesView(helper: releaseHelper).padding()
|
|
})
|
|
})
|
|
|
|
+ .alert(item: $alertItem) { item in
|
|
|
|
+ switch item {
|
|
|
|
+ case .downloadUrl(let url):
|
|
|
|
+ return Alert(title: Text("Download VM"), message: Text("Do you want to download '\(url)'?"), primaryButton: .cancel(), secondaryButton: .default(Text("Download")) {
|
|
|
|
+ data.downloadUTMZip(from: url)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
.onReceive(NSNotification.ShowReleaseNotes) { _ in
|
|
.onReceive(NSNotification.ShowReleaseNotes) { _ in
|
|
Task {
|
|
Task {
|
|
await releaseHelper.fetchReleaseNotes(force: true)
|
|
await releaseHelper.fetchReleaseNotes(force: true)
|
|
@@ -115,13 +124,17 @@ struct ContentView: View {
|
|
}
|
|
}
|
|
|
|
|
|
private func handleURL(url: URL) {
|
|
private func handleURL(url: URL) {
|
|
- data.busyWorkAsync {
|
|
|
|
- if url.isFileURL {
|
|
|
|
|
|
+ if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
|
|
|
|
+ components.scheme?.lowercased() == "utm",
|
|
|
|
+ components.host == "downloadVM",
|
|
|
|
+ let urlParameter = components.queryItems?.first(where: { $0.name == "url" })?.value,
|
|
|
|
+ let url = URL(string: urlParameter) {
|
|
|
|
+ if alertItem == nil {
|
|
|
|
+ alertItem = .downloadUrl(url)
|
|
|
|
+ }
|
|
|
|
+ } else if url.isFileURL {
|
|
|
|
+ data.busyWorkAsync {
|
|
try await importUTM(url: url)
|
|
try await importUTM(url: url)
|
|
- } else if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
|
|
|
|
- let scheme = components.scheme,
|
|
|
|
- scheme.lowercased() == "utm" {
|
|
|
|
- try await handleUTMURL(with: components)
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -197,9 +210,6 @@ struct ContentView: View {
|
|
data.automationSendMouse(to: vm, urlComponents: components)
|
|
data.automationSendMouse(to: vm, urlComponents: components)
|
|
}
|
|
}
|
|
break
|
|
break
|
|
- case "downloadVM":
|
|
|
|
- await data.downloadUTMZip(from: components)
|
|
|
|
- break
|
|
|
|
default:
|
|
default:
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -246,6 +256,19 @@ extension ContentView: DropDelegate {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+extension ContentView {
|
|
|
|
+ private enum AlertItem: Identifiable {
|
|
|
|
+ case downloadUrl(URL)
|
|
|
|
+
|
|
|
|
+ var id: Int {
|
|
|
|
+ switch self {
|
|
|
|
+ case .downloadUrl(let url):
|
|
|
|
+ return url.hashValue
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
struct ContentView_Previews: PreviewProvider {
|
|
struct ContentView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
static var previews: some View {
|
|
ContentView()
|
|
ContentView()
|