2024-12-05 09:17:33 +01:00

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())
}