Improve post entry views, add post link data
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user