116 lines
3.1 KiB
Swift
116 lines
3.1 KiB
Swift
import SwiftUI
|
|
|
|
struct PageListView: View {
|
|
|
|
@Environment(\.language)
|
|
private var language
|
|
|
|
@EnvironmentObject
|
|
private var content: Content
|
|
|
|
@State
|
|
private var selected: Page?
|
|
|
|
@State
|
|
private var showNewPageView = false
|
|
|
|
@State
|
|
private var newPageId = ""
|
|
|
|
@State
|
|
private var newPageIdIsValid = false
|
|
|
|
private let allowedCharactersInPageId = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-")).inverted
|
|
|
|
private var cleanPageId: String {
|
|
newPageId.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationSplitView {
|
|
List(content.pages, selection: $selected) { page in
|
|
Text(page.localized(in: language).title)
|
|
.tag(page)
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .primaryAction) {
|
|
Button(action: { showNewPageView = true }) {
|
|
Label("New post", systemSymbol: .plus)
|
|
}
|
|
}
|
|
}
|
|
.navigationSplitViewColumnWidth(min: 300, ideal: 300, max: 300)
|
|
} content: {
|
|
if let selected {
|
|
PageDetailView(page: selected)
|
|
.id(selected.id)
|
|
.layoutPriority(1)
|
|
} else {
|
|
// Fallback if no item is selected
|
|
Text("Select a page from the list")
|
|
.font(.largeTitle)
|
|
.foregroundColor(.secondary)
|
|
}
|
|
} detail: {
|
|
if let selected {
|
|
EmptyView()
|
|
.frame(maxWidth: 350)
|
|
} else {
|
|
EmptyView()
|
|
.frame(maxWidth: 350)
|
|
}
|
|
}
|
|
.onAppear {
|
|
if selected == nil {
|
|
selected = content.pages.first
|
|
}
|
|
}
|
|
.sheet(isPresented: $showNewPageView,
|
|
onDismiss: addNewPage) {
|
|
TextEntrySheet(
|
|
title: "Enter the id for the new page",
|
|
text: $newPageId,
|
|
isValid: $newPageIdIsValid)
|
|
}
|
|
}
|
|
|
|
private func isValid(id: String) -> Bool {
|
|
let id = cleanPageId
|
|
guard id != "" else {
|
|
return false
|
|
}
|
|
|
|
guard !content.pages.contains(where: { $0.id == id }) else {
|
|
return false
|
|
}
|
|
// Only allow alphanumeric characters and hyphens
|
|
return id.rangeOfCharacter(from: allowedCharactersInPageId) == nil
|
|
}
|
|
|
|
private func addNewPage() {
|
|
let id = cleanPageId
|
|
guard isValid(id: id) else {
|
|
return
|
|
}
|
|
|
|
let page = Page(
|
|
id: id,
|
|
isDraft: true,
|
|
createdDate: .now,
|
|
startDate: .now,
|
|
endDate: nil,
|
|
german: .init(urlString: "seite",
|
|
title: "Ein Titel"),
|
|
english: .init(urlString: "page",
|
|
title: "A Title"),
|
|
tags: [])
|
|
content.pages.insert(page, at: 0)
|
|
selected = page
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
PageListView()
|
|
.environmentObject(Content())
|
|
}
|