2025-01-07 10:34:36 +01:00

147 lines
3.1 KiB
Swift

import Foundation
final class Post: Item {
@Published
var isDraft: Bool
@Published
var createdDate: Date
@Published
var startDate: Date
@Published
var hasEndDate: Bool
@Published
var endDate: Date
/**
The tags associated with the post
This list is only used if ``linkedPage`` is `nil`,
otherwise the tag list of the linked page is used.
*/
@Published
var tags: [Tag]
@Published
var german: LocalizedPost
@Published
var english: LocalizedPost
/// The page linked to by this post
@Published
var linkedPage: Page?
init(content: Content,
id: String,
isDraft: Bool,
createdDate: Date,
startDate: Date,
endDate: Date?,
tags: [Tag],
german: LocalizedPost,
english: LocalizedPost,
linkedPage: Page? = nil) {
self.isDraft = isDraft
self.createdDate = createdDate
self.startDate = startDate
self.hasEndDate = endDate != nil
self.endDate = endDate ?? startDate
self.tags = tags
self.german = german
self.english = english
self.linkedPage = linkedPage
super.init(content: content, id: id)
}
// MARK: Tags
func usedTags() -> [Tag] {
linkedPage?.tags ?? tags
}
/**
Check if a tag is associated with this post.
If the post is linked to a page, then the tags of the page are checked.
*/
func contains(_ tag: Tag) -> Bool {
guard let linkedPage else {
return tags.contains(tag)
}
return linkedPage.tags.contains(tag)
}
func toggle(_ tag: Tag) {
if let linkedPage {
linkedPage.toggle(tag)
return
}
guard let index = tags.firstIndex(of: tag) else {
tags.append(tag)
return
}
tags.remove(at: index)
}
func remove(_ tag: Tag) {
if let linkedPage {
linkedPage.remove(tag)
return
}
tags.remove(tag)
}
func associate(_ tag: Tag) {
if let linkedPage {
linkedPage.associate(tag)
return
}
guard !tags.contains(tag) else {
return
}
tags.append(tag)
}
/**
A title for the UI, not the generation.
*/
override func title(in language: ContentLanguage) -> String {
localized(in: language).title ?? id
}
func contains(_ string: String) -> Bool {
id.contains(string) ||
german.contains(string) ||
english.contains(string)
}
func isValid(id: String) -> Bool {
!id.isEmpty &&
content.isValidIdForTagOrPageOrPost(id) &&
content.isNewIdForPost(id)
}
@discardableResult
func update(id newId: String) -> Bool {
guard content.storage.move(post: id, to: newId) else {
print("Failed to move file of post \(id)")
return false
}
id = newId
return true
}
}
extension Post: DateItem {
}
extension Post: LocalizedItem {
}