Show the Weblog Entry Status in the Editor

This commit is contained in:
Otavio Cordeiro 2025-12-21 11:55:48 +01:00 committed by Otávio
parent 958d410ddc
commit 3365b19b8f
9 changed files with 86 additions and 5 deletions

View file

@ -30,17 +30,22 @@ public struct EditWeblogEntry: Codable, Hashable {
/// The unique identifier for the weblog entry, if it already exists.
public let entryID: String?
/// The publication status of the weblog entry.
public let status: String?
// MARK: - Lifecycle
public init(
address: String,
body: String,
date: Date,
entryID: String?
entryID: String?,
status: String?
) {
self.address = address
self.body = body
self.date = date
self.entryID = entryID
self.status = status
}
}

View file

@ -63,13 +63,15 @@ final class ViewModelFactory: Sendable {
address: String,
body: String,
date: Date,
entryID: String?
entryID: String?,
status: WeblogEntryStatus
) -> EditorViewModel {
.init(
address: address,
body: body,
date: date,
entryID: entryID,
status: status,
repository: container.resolve()
)
}

View file

@ -13,6 +13,7 @@
body: "# This is the title\n\nThis is the body...",
date: .init(),
entryID: nil,
status: .draft,
repository: WeblogRepositoryMother.makeWeblogRepository()
)
}

View file

@ -0,0 +1,48 @@
import Foundation
/// Represents the publication status of a weblog entry.
///
/// Status values control how entries are displayed and distributed across
/// the weblog and its feeds. Each status provides different visibility
/// and accessibility options for entries.
enum WeblogEntryStatus: String, CaseIterable, Hashable, Identifiable {
/// Draft status marks an entry as unpublished.
///
/// Entries with this status are not publicly accessible and are
/// typically used for work-in-progress content.
case draft = "Draft"
/// Live status makes an entry fully published and accessible.
///
/// Entries with this status appear on the weblog, in post lists,
/// on tag pages, and are included in RSS, Atom, and JSON feeds.
case live
/// Feed Only status hides the entry from the web but includes it in feeds.
///
/// Entries with this status are treated as unlisted on the web (not
/// appearing in post lists, tag pages, or as landing pages) but are
/// included in RSS, Atom, and JSON feeds.
case liveRSSOnly = "Feed Only"
/// Web Only status hides the entry from feeds but keeps it on the web.
///
/// Entries with this status are accessible on the weblog and appear
/// in post lists and tag pages, but are completely hidden from RSS,
/// Atom, and JSON feeds.
case liveWebOnly = "Web Only"
/// Unlisted status makes an entry accessible only via direct URL.
///
/// Entries with this status are not served as default/landing pages,
/// do not appear in post lists or recent posts, and are not included
/// on tag pages. They are only accessible to people who know the
/// entry's direct URL.
case unlisted = "Unlisted"
// MARK: - Properties
var id: Self { self }
var displayName: String { rawValue.capitalized }
}

View file

@ -27,6 +27,7 @@ struct EditWeblogEntryScene: Scene {
body: entry?.body ?? "",
date: entry?.date ?? .init(),
entryID: entry?.entryID,
status: entry?.status.flatMap(WeblogEntryStatus.init) ?? .draft,
address: entry?.address ?? ""
)
}
@ -44,6 +45,7 @@ struct EditWeblogEntryScene: Scene {
body: String,
date: Date,
entryID: String?,
status: WeblogEntryStatus,
address: String
) -> some View {
let viewModel = environment.viewModelFactory
@ -51,7 +53,8 @@ struct EditWeblogEntryScene: Scene {
address: address,
body: body,
date: date,
entryID: entryID
entryID: entryID,
status: status
)
EditorView(

View file

@ -88,7 +88,8 @@ struct WeblogApp: View {
address: address,
body: "# Title of your post\n\nThis is the body of your post...",
date: .init(),
entryID: nil
entryID: nil,
status: nil
)
)
} label: {

View file

@ -70,6 +70,23 @@ struct EditorView: View {
) {}
.help("Select publication time")
}
GridRow {
Text("Status")
.gridColumnAlignment(.trailing)
Picker(
selection: $viewModel.selectedStatus,
content: {
ForEach(WeblogEntryStatus.allCases) { status in
Text(status.displayName)
}
},
label: { EmptyView() }
)
.pickerStyle(.radioGroup)
.labelsHidden()
}
}
.padding()
}

View file

@ -11,6 +11,7 @@ final class EditorViewModel {
var body: String
var entryID: String?
var date: Date
var selectedStatus: WeblogEntryStatus
var shouldDismiss = false
private(set) var isSubmitting = false
@ -38,12 +39,14 @@ final class EditorViewModel {
body: String,
date: Date,
entryID: String?,
status: WeblogEntryStatus,
repository: any WeblogRepositoryProtocol
) {
self.address = address
self.body = body
self.date = date
self.entryID = entryID
selectedStatus = status
self.repository = repository
}

View file

@ -171,7 +171,8 @@ struct WeblogEntryView: View {
address: viewModel.address,
body: viewModel.body,
date: viewModel.publishedDate,
entryID: viewModel.id
entryID: viewModel.id,
status: viewModel.status
)
)
}