Create page from post

This commit is contained in:
Christoph Hagen 2025-01-18 12:02:06 +01:00
parent 1d4b3c266c
commit 51eff690d2
7 changed files with 88 additions and 24 deletions

View File

@ -11,7 +11,6 @@ import SFSafeSymbols
- Page Content: Show all results of `PageGenerationResults`
- Files: Show usages of file
- Buttons to insert special commands (images, page links, ...)
- Post: Create page from information of post
**Features**
- Posts: Generate separate pages for posts to link to

View File

@ -6,35 +6,42 @@ protocol DateItem {
var hasEndDate: Bool { get }
var endDate: Date { get }
var potentialEndDate: Date { get }
}
extension DateItem {
private func datePrefixString(in language: ContentLanguage) -> String {
guard Calendar.current.isDate(startDate, equalTo: endDate, toGranularity: .year) else {
// Different year, return full string
return DateItemStorage.dateString(for: startDate, in: language)
}
guard Calendar.current.isDate(startDate, equalTo: endDate, toGranularity: .month) else {
// Different month
return DateItemStorage.dayAndMonth(of: startDate, in: language)
}
return DateItemStorage.day.string(from: startDate)
var endDate: Date? {
hasEndDate ? potentialEndDate : nil
}
func dateText(in language: ContentLanguage) -> String {
guard hasEndDate else {
guard let endDate else {
return DateItemStorage.dateString(for: startDate, in: language)
}
let endText = DateItemStorage.dateString(for: endDate, in: language)
return "\(datePrefixString(in: language)) - \(endText)"
let endText = DateItemStorage.dateString(for: potentialEndDate, in: language)
let prefix = DateItemStorage.datePrefixString(from: startDate, to: endDate, in: language)
return prefix + " - " + endText
}
}
private enum DateItemStorage {
static func datePrefixString(from start: Date, to end: Date, in language: ContentLanguage) -> String {
guard Calendar.current.isDate(start, equalTo: end, toGranularity: .year) else {
// Different year, return full string
return DateItemStorage.dateString(for: start, in: language)
}
guard Calendar.current.isDate(start, equalTo: end, toGranularity: .month) else {
// Different month
return DateItemStorage.dayAndMonth(of: start, in: language)
}
return DateItemStorage.day.string(from: start)
}
static let englishDate: DateFormatter = {
let df = DateFormatter()
df.locale = .init(identifier: "en")

View File

@ -54,6 +54,16 @@ final class LocalizedPost: ObservableObject {
linkPreview.remove(file)
}
func makePage(urlString: String) -> LocalizedPage {
.init(content: content,
urlString: urlString,
title: title ?? "Title",
lastModified: lastModified,
originalUrl: nil,
linkPreview: linkPreview,
hideTitle: false)
}
// MARK: Images
var hasImages: Bool {

View File

@ -29,7 +29,7 @@ final class Page: Item, DateItem, LocalizedItem {
var hasEndDate: Bool
@Published
var endDate: Date
var potentialEndDate: Date
@Published
var german: LocalizedPage
@ -62,7 +62,7 @@ final class Page: Item, DateItem, LocalizedItem {
self.hideDate = hideDate
self.startDate = startDate
self.hasEndDate = endDate != nil
self.endDate = endDate ?? startDate
self.potentialEndDate = endDate ?? startDate
self.german = german
self.english = english
self.tags = tags
@ -227,7 +227,7 @@ extension Page {
hideDate: hideDate ? true : nil,
createdDate: createdDate,
startDate: startDate,
endDate: hasEndDate ? endDate : nil,
endDate: endDate,
german: german.data,
english: english.data,
requiredFiles: requiredFiles.nonEmpty?.map { $0.id }.sorted())

View File

@ -17,7 +17,7 @@ final class Post: Item, DateItem, LocalizedItem {
var hasEndDate: Bool
@Published
var endDate: Date
var potentialEndDate: Date
/**
The tags associated with the post
@ -52,7 +52,7 @@ final class Post: Item, DateItem, LocalizedItem {
self.createdDate = createdDate
self.startDate = startDate
self.hasEndDate = endDate != nil
self.endDate = endDate ?? startDate
self.potentialEndDate = endDate ?? startDate
self.tags = tags
self.german = german
self.english = english
@ -143,6 +143,34 @@ final class Post: Item, DateItem, LocalizedItem {
english.remove(file)
german.remove(file)
}
func makePage() -> Page {
var id = self.id
var number = 2
while !content.isNewIdForPage(id) {
id += "\(self.id)-\(number)"
number += 1
}
// Move tags to page
let tags = self.tags
self.tags = []
let german = english.makePage(urlString: id + "-de")
let english = english.makePage(urlString: id + "-en")
return Page(
content: content,
id: id,
externalLink: nil,
isDraft: true,
createdDate: .now,
hideDate: false,
startDate: startDate,
endDate: endDate,
german: german,
english: english,
tags: tags,
requiredFiles: [])
}
}
extension Post {
@ -177,7 +205,7 @@ extension Post {
isDraft: isDraft,
createdDate: createdDate,
startDate: startDate,
endDate: hasEndDate ? endDate : nil,
endDate: endDate,
tags: tags.map { $0.id },
german: german.data,
english: english.data,

View File

@ -93,7 +93,7 @@ struct PageDetailView: View {
OptionalDatePropertyView(
title: "End date",
isEnabled: $page.hasEndDate,
date: $page.endDate,
date: $page.potentialEndDate,
footer: "The date when the page content ended")
.disabled(page.isExternalUrl)

View File

@ -33,6 +33,12 @@ struct PostDetailView: View {
@Environment(\.language)
private var language
@EnvironmentObject
private var content: Content
@EnvironmentObject
private var selection: SelectedContent
@ObservedObject
private var post: Post
@ -54,6 +60,10 @@ struct PostDetailView: View {
title: "Post",
text: "Posts capture quick updates and can link to pages")
if post.linkedPage == nil {
Button("Create page", action: createPageFromPost)
}
IdPropertyView(
id: $post.id,
footer: "The id is used to link to post and store them",
@ -73,7 +83,7 @@ struct PostDetailView: View {
OptionalDatePropertyView(
title: "End date",
isEnabled: $post.hasEndDate,
date: $post.endDate,
date: $post.potentialEndDate,
footer: "The date when the post content ended")
PagePropertyView(
@ -98,6 +108,16 @@ struct PostDetailView: View {
.padding()
}
}
private func createPageFromPost() {
let page = post.makePage()
DispatchQueue.main.async {
content.pages.insert(page, at: 0)
post.linkedPage = page
selection.page = page
selection.tab = .pages
}
}
}
extension PostDetailView: MainContentView {