import SwiftUI struct PageDetailView: View { @Environment(\.language) private var language @EnvironmentObject private var content: Content @ObservedObject private var page: Page @State private var isGeneratingWebsite = false @State private var newId: String init(page: Page) { self.page = page self.newId = page.id } private let allowedCharactersInPostId = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-")).inverted private var idExists: Bool { page.content.pages.contains { $0.id == newId } } private var containsInvalidCharacters: Bool { newId.rangeOfCharacter(from: allowedCharactersInPostId) != nil } var body: some View { ScrollView { VStack(alignment: .leading) { Button(action: generate) { Text("Generate") } .disabled(isGeneratingWebsite) HStack { TextField("", text: $newId) .textFieldStyle(.roundedBorder) Button("Update", action: setNewId) .disabled(newId.isEmpty || containsInvalidCharacters || idExists) } .padding(.bottom) HStack { Text("Draft") .font(.headline) Spacer() Toggle("", isOn: $page.isDraft) .toggleStyle(.switch) } .padding(.bottom) HStack { Text("Start") .font(.headline) Spacer() DatePicker("", selection: $page.startDate, displayedComponents: .date) .datePickerStyle(.compact) .padding(.bottom) } HStack(alignment: .firstTextBaseline) { Text("Has end date") .font(.headline) Spacer() Toggle("", isOn: $page.hasEndDate) .toggleStyle(.switch) .padding(.bottom) } if page.hasEndDate { HStack(alignment: .firstTextBaseline) { Text("End date") .font(.headline) Spacer() DatePicker("", selection: $page.endDate, displayedComponents: .date) .datePickerStyle(.compact) .padding(.bottom) } } LocalizedPageDetailView(page: page.localized(in: language)) } .padding() } } private func generate() { guard content.settings.outputDirectoryPath != "" else { print("Invalid output path") return } let url = URL(fileURLWithPath: content.settings.outputDirectoryPath) guard FileManager.default.fileExists(atPath: url.path) else { print("Missing output folder") return } isGeneratingWebsite = true print("Generating page") DispatchQueue.global(qos: .userInitiated).async { let generator = WebsiteGenerator( content: content, language: language) if !generator.generate(page: page) { print("Generation failed") } DispatchQueue.main.async { isGeneratingWebsite = false print("Done") } } } private func setNewId() { guard page.update(id: newId) else { newId = page.id return } page.id = newId } } extension PageDetailView: MainContentView { init(item: Page) { self.init(page: item) } static let itemDescription = "a page" } #Preview { PageDetailView(page: .empty) }