Improve post entry views, add post link data

This commit is contained in:
Christoph Hagen
2024-11-30 08:34:31 +01:00
parent fd1f1f4c40
commit f1e1538167
18 changed files with 567 additions and 101 deletions

View File

@@ -5,51 +5,96 @@ struct PostList: View {
@EnvironmentObject
private var content: Content
@State
private var showNewPostIdSheet = false
@Environment(\.language)
private var language: ContentLanguage
@State
private var newPostId = ""
@State
private var selected: Post? = nil
@State
private var showNewPostView = false
@State
private var newPostIdIsValid = false
private let allowedCharactersInPostId = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-")).inverted
private var cleanPostId: String {
newPostId.trimmingCharacters(in: .whitespacesAndNewlines)
}
var body: some View {
List {
if content.posts.isEmpty {
HorizontalCenter {
Text("No posts yet.")
.padding()
}
.listRowSeparator(.hidden)
NavigationSplitView {
List(content.posts, selection: $selected) { post in
Text(post.localized(in: language).title)
.tag(post)
}
HorizontalCenter {
Button(action: { showNewPostIdSheet = true }) {
Text("Add post")
.frame(minWidth: 200)
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: { showNewPostView = true }) {
Label("New post", systemSymbol: .plus)
}
}
.padding()
.listRowSeparator(.hidden)
}
ForEach(content.posts) { post in
HorizontalCenter {
PostView(post: post)
.frame(maxWidth: 600)
}
.listRowSeparator(.hidden)
.listRowInsets(.init(top: 0, leading: 0, bottom: 30, trailing: 0))
} content: {
if let selected {
PostContentView(post: selected)
.layoutPriority(1)
} else {
HStack {
Spacer()
Text("Select a post to show the content")
.font(.largeTitle)
.foregroundColor(.secondary)
Spacer()
}.layoutPriority(1)
}
} detail: {
if let selected {
PostDetailView(post: selected)
.frame(minWidth: 280)
} else {
Text("No post selected")
.frame(minWidth: 280)
}
}
.listStyle(.plain)
.sheet(isPresented: $showNewPostIdSheet, onDismiss: addNewPost) {
TextEntrySheet(title: "Enter the new post id", text: $newPostId)
.sheet(isPresented: $showNewPostView,
onDismiss: addNewPost) {
TextEntrySheet(
title: "Enter the id for the new post",
text: $newPostId,
isValid: $newPostIdIsValid)
}
.onChange(of: newPostId) { _, newValue in
newPostIdIsValid = isValid(id: newValue)
}
.onAppear {
if selected == nil {
selected = content.posts.first
}
}
}
private func addNewPost() {
let id = newPostId.trimmingCharacters(in: .whitespacesAndNewlines)
private func isValid(id: String) -> Bool {
let id = cleanPostId
guard id != "" else {
return
return false
}
guard !content.posts.contains(where: { $0.id == id }) else {
print("ID \(id) already exists")
return false
}
// Only allow alphanumeric characters and hyphens
return id.rangeOfCharacter(from: allowedCharactersInPostId) == nil
}
private func addNewPost() {
let id = cleanPostId
guard isValid(id: id) else {
return
}
@@ -63,6 +108,7 @@ struct PostList: View {
german: .init(title: "Titel", content: "Text"),
english: .init(title: "Title", content: "Text"))
content.posts.insert(post, at: 0)
selected = post
}
}