Adds a Share Extension so users can share URLs from Safari (or any app) to open the main app with the ImportURLSheet pre-filled. Uses a custom URL scheme (nextcloud-cookbook://) as the bridge between the extension and the main app. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
88 lines
2.7 KiB
Swift
88 lines
2.7 KiB
Swift
//
|
|
// ImportURLSheet.swift
|
|
// Nextcloud Cookbook iOS Client
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct ImportURLSheet: View {
|
|
@EnvironmentObject var appState: AppState
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
var onImport: (RecipeDetail) -> Void
|
|
var initialURL: String = ""
|
|
|
|
@State private var url: String = ""
|
|
@State private var isLoading: Bool = false
|
|
@State private var presentAlert: Bool = false
|
|
@State private var alertMessage: String = ""
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
Form {
|
|
Section {
|
|
TextField("Recipe URL", text: $url)
|
|
.keyboardType(.URL)
|
|
.textContentType(.URL)
|
|
.autocorrectionDisabled()
|
|
.textInputAutocapitalization(.never)
|
|
} footer: {
|
|
Text("Paste the URL of a recipe you would like to import.")
|
|
}
|
|
|
|
Section {
|
|
Button {
|
|
Task {
|
|
await importRecipe()
|
|
}
|
|
} label: {
|
|
HStack {
|
|
Spacer()
|
|
if isLoading {
|
|
ProgressView()
|
|
} else {
|
|
Text("Import")
|
|
}
|
|
Spacer()
|
|
}
|
|
}
|
|
.disabled(url.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isLoading)
|
|
}
|
|
}
|
|
.navigationTitle("Import Recipe")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Cancel") {
|
|
dismiss()
|
|
}
|
|
}
|
|
}
|
|
.alert("Import Failed", isPresented: $presentAlert) {
|
|
Button("OK", role: .cancel) { }
|
|
} message: {
|
|
Text(alertMessage)
|
|
}
|
|
.onAppear {
|
|
if !initialURL.isEmpty {
|
|
url = initialURL
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func importRecipe() async {
|
|
isLoading = true
|
|
let (recipeDetail, error) = await appState.importRecipe(url: url)
|
|
isLoading = false
|
|
|
|
if let recipeDetail {
|
|
dismiss()
|
|
onImport(recipeDetail)
|
|
} else {
|
|
alertMessage = error?.localizedDescription ?? String(localized: "The recipe could not be imported. Please check the URL and try again.")
|
|
presentAlert = true
|
|
}
|
|
}
|
|
}
|