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. /// The unique identifier for the weblog entry, if it already exists.
public let entryID: String? public let entryID: String?
/// The publication status of the weblog entry.
public let status: String?
// MARK: - Lifecycle // MARK: - Lifecycle
public init( public init(
address: String, address: String,
body: String, body: String,
date: Date, date: Date,
entryID: String? entryID: String?,
status: String?
) { ) {
self.address = address self.address = address
self.body = body self.body = body
self.date = date self.date = date
self.entryID = entryID self.entryID = entryID
self.status = status
} }
} }

View file

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

View file

@ -13,6 +13,7 @@
body: "# This is the title\n\nThis is the body...", body: "# This is the title\n\nThis is the body...",
date: .init(), date: .init(),
entryID: nil, entryID: nil,
status: .draft,
repository: WeblogRepositoryMother.makeWeblogRepository() 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 ?? "", body: entry?.body ?? "",
date: entry?.date ?? .init(), date: entry?.date ?? .init(),
entryID: entry?.entryID, entryID: entry?.entryID,
status: entry?.status.flatMap(WeblogEntryStatus.init) ?? .draft,
address: entry?.address ?? "" address: entry?.address ?? ""
) )
} }
@ -44,6 +45,7 @@ struct EditWeblogEntryScene: Scene {
body: String, body: String,
date: Date, date: Date,
entryID: String?, entryID: String?,
status: WeblogEntryStatus,
address: String address: String
) -> some View { ) -> some View {
let viewModel = environment.viewModelFactory let viewModel = environment.viewModelFactory
@ -51,7 +53,8 @@ struct EditWeblogEntryScene: Scene {
address: address, address: address,
body: body, body: body,
date: date, date: date,
entryID: entryID entryID: entryID,
status: status
) )
EditorView( EditorView(

View file

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

View file

@ -70,6 +70,23 @@ struct EditorView: View {
) {} ) {}
.help("Select publication time") .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() .padding()
} }

View file

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

View file

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