157 lines
3.8 KiB
Swift
157 lines
3.8 KiB
Swift
import Foundation
|
|
|
|
final class Post: ObservableObject {
|
|
|
|
@Published
|
|
var id: String
|
|
|
|
@Published
|
|
var isDraft: Bool
|
|
|
|
@Published
|
|
var createdDate: Date
|
|
|
|
@Published
|
|
var startDate: Date
|
|
|
|
@Published
|
|
var hasEndDate: Bool
|
|
|
|
@Published
|
|
var endDate: Date
|
|
|
|
@Published
|
|
var tags: [Tag]
|
|
|
|
@Published
|
|
var german: LocalizedPost
|
|
|
|
@Published
|
|
var english: LocalizedPost
|
|
|
|
/// The page linked to by this post
|
|
@Published
|
|
var linkedPage: Page?
|
|
|
|
init(id: String,
|
|
isDraft: Bool,
|
|
createdDate: Date,
|
|
startDate: Date,
|
|
endDate: Date?,
|
|
tags: [Tag],
|
|
german: LocalizedPost,
|
|
english: LocalizedPost,
|
|
linkedPage: Page? = nil) {
|
|
self.id = id
|
|
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
|
|
}
|
|
|
|
func localized(in language: ContentLanguage) -> LocalizedPost {
|
|
switch language {
|
|
case .english: return english
|
|
case .german: return german
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Post: Identifiable {
|
|
|
|
}
|
|
|
|
extension Post: Equatable {
|
|
|
|
static func == (lhs: Post, rhs: Post) -> Bool {
|
|
lhs.id == rhs.id
|
|
}
|
|
}
|
|
|
|
extension Post: Hashable {
|
|
|
|
func hash(into hasher: inout Hasher) {
|
|
hasher.combine(id)
|
|
}
|
|
}
|
|
|
|
|
|
// MARK: Feed entry
|
|
|
|
extension Post {
|
|
|
|
private static let englishDate: DateFormatter = {
|
|
let df = DateFormatter()
|
|
df.locale = .init(identifier: "en")
|
|
df.dateFormat = "d. MMMM yyyy"
|
|
return df
|
|
}()
|
|
|
|
private static let germanDate: DateFormatter = {
|
|
let df = DateFormatter()
|
|
df.locale = .init(identifier: "de")
|
|
df.dateFormat = "d. MMMM yyyy"
|
|
return df
|
|
}()
|
|
|
|
private static let englishDayAndMonth: DateFormatter = {
|
|
let df = DateFormatter()
|
|
df.locale = .init(identifier: "en")
|
|
df.dateFormat = "d. MMMM"
|
|
return df
|
|
}()
|
|
|
|
private static let germanDayAndMonth: DateFormatter = {
|
|
let df = DateFormatter()
|
|
df.locale = .init(identifier: "de")
|
|
df.dateFormat = "d. MMMM"
|
|
return df
|
|
}()
|
|
|
|
private static let day: DateFormatter = {
|
|
let df = DateFormatter()
|
|
df.dateFormat = "d."
|
|
return df
|
|
}()
|
|
|
|
private static func dayAndMonth(of date: Date, in language: ContentLanguage) -> String {
|
|
switch language {
|
|
case .english: return englishDayAndMonth.string(from: date)
|
|
case .german: return germanDayAndMonth.string(from: date)
|
|
}
|
|
}
|
|
|
|
private static func dateString(for date: Date, in language: ContentLanguage) -> String {
|
|
switch language {
|
|
case .english: return englishDate.string(from: date)
|
|
case .german: return germanDate.string(from: date)
|
|
}
|
|
}
|
|
|
|
private func datePrefixString(in language: ContentLanguage) -> String {
|
|
guard Calendar.current.isDate(startDate, equalTo: endDate, toGranularity: .year) else {
|
|
// Different year, return full string
|
|
return startDate.formatted(date: .long, time: .omitted)
|
|
}
|
|
guard Calendar.current.isDate(startDate, equalTo: endDate, toGranularity: .month) else {
|
|
// Different month
|
|
return Post.dayAndMonth(of: startDate, in: language)
|
|
}
|
|
|
|
return Post.day.string(from: startDate)
|
|
}
|
|
|
|
func dateText(in language: ContentLanguage) -> String {
|
|
guard hasEndDate else {
|
|
return Post.dateString(for: startDate, in: language)
|
|
}
|
|
let endText = Post.dateString(for: endDate, in: language)
|
|
return "\(datePrefixString(in: language)) - \(endText)"
|
|
}
|
|
}
|