mirror of
https://github.com/otaviocc/Triton.git
synced 2026-01-29 19:54:27 +00:00
Publish Weblog entry with the specified status
This commit is contained in:
parent
3365b19b8f
commit
d840caa026
8 changed files with 74 additions and 20 deletions
|
|
@ -5,25 +5,33 @@ public extension String {
|
|||
/// Creates a weblog entry body with frontmatter from the string content.
|
||||
///
|
||||
/// This method formats the string as a weblog entry by adding frontmatter
|
||||
/// with the specified publication date. The resulting format follows the
|
||||
/// with the specified publication date and status. The resulting format follows the
|
||||
/// OMG.LOL weblog API requirements with ISO 8601 date formatting.
|
||||
///
|
||||
/// The output format is:
|
||||
/// ```
|
||||
/// ---
|
||||
/// Date: YYYY-MM-DD HH:MM
|
||||
/// Status: [status value]
|
||||
/// ---
|
||||
///
|
||||
/// [string content]
|
||||
/// ```
|
||||
///
|
||||
/// - Parameter date: The publication date to include in the frontmatter
|
||||
/// - Parameters:
|
||||
/// - date: The publication date to include in the frontmatter
|
||||
/// - status: The publication status to include in the frontmatter (e.g., "Draft", "Live", "Feed Only", "Web
|
||||
/// Only", "Unlisted")
|
||||
/// - Returns: UTF-8 encoded data containing the formatted weblog entry body
|
||||
func weblogEntryBody(with date: Date) -> Data {
|
||||
func weblogEntryBody(
|
||||
date: Date,
|
||||
status: String
|
||||
) -> Data {
|
||||
let formattedString = DateFormatter.iso8601WithShortTime.string(from: date)
|
||||
let body = """
|
||||
---
|
||||
Date: \(formattedString)
|
||||
Status: \(status)
|
||||
---
|
||||
|
||||
\(self)
|
||||
|
|
|
|||
|
|
@ -83,13 +83,14 @@ public enum WeblogRequestFactory {
|
|||
/// Creates a request to create a new weblog entry.
|
||||
///
|
||||
/// This method builds a POST request to create a new weblog entry with the
|
||||
/// specified content and publication date. The request formats the content
|
||||
/// with frontmatter containing the date and sends it as raw data to the API.
|
||||
/// specified content, publication date, and status. The request formats the content
|
||||
/// with frontmatter containing the date and status, then sends it as raw data to the API.
|
||||
///
|
||||
/// The content is formatted as:
|
||||
/// ```
|
||||
/// ---
|
||||
/// Date: YYYY-MM-DD HH:MM
|
||||
/// Status: [status value]
|
||||
/// ---
|
||||
///
|
||||
/// [content goes here]
|
||||
|
|
@ -97,19 +98,25 @@ public enum WeblogRequestFactory {
|
|||
///
|
||||
/// This request requires authentication as it creates content on behalf
|
||||
/// of the authenticated user. The API will generate a unique entry ID
|
||||
/// and URL slug based on the content title.
|
||||
/// and URL slug based on the content title. The entry's visibility and
|
||||
/// distribution will be controlled by the specified status.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - address: The user address (username) to create the entry for
|
||||
/// - content: The markdown content body of the weblog entry
|
||||
/// - status: The publication status of the entry (e.g., "Draft", "Live", "Feed Only", "Web Only", "Unlisted")
|
||||
/// - date: The publication date for the entry
|
||||
/// - Returns: A configured network request for creating a weblog entry
|
||||
public static func makeCreateWeblogEntryRequest(
|
||||
address: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) -> NetworkRequest<Data, CreateOrUpdateWeblogEntryResponse> {
|
||||
let body = content.weblogEntryBody(with: date)
|
||||
let body = content.weblogEntryBody(
|
||||
date: date,
|
||||
status: status
|
||||
)
|
||||
|
||||
return .init(
|
||||
path: "/address/\(address)/weblog/entry",
|
||||
|
|
@ -122,12 +129,13 @@ public enum WeblogRequestFactory {
|
|||
///
|
||||
/// This method builds a POST request to update an existing weblog entry
|
||||
/// identified by its entry ID. The request formats the updated content
|
||||
/// with frontmatter containing the new date and sends it as raw data.
|
||||
/// with frontmatter containing the new date and status, then sends it as raw data.
|
||||
///
|
||||
/// The content is formatted as:
|
||||
/// ```
|
||||
/// ---
|
||||
/// Date: YYYY-MM-DD HH:MM
|
||||
/// Status: [status value]
|
||||
/// ---
|
||||
///
|
||||
/// [updated content goes here]
|
||||
|
|
@ -135,21 +143,28 @@ public enum WeblogRequestFactory {
|
|||
///
|
||||
/// This request requires authentication and the user must own the entry
|
||||
/// being updated. The entry's URL and slug will remain unchanged, but
|
||||
/// the content and metadata will be updated with the new values.
|
||||
/// the content, publication date, status, and metadata will be updated
|
||||
/// with the new values.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - address: The user address (username) who owns the entry
|
||||
/// - entryID: The unique identifier of the entry to update
|
||||
/// - content: The updated markdown content body of the weblog entry
|
||||
/// - status: The updated publication status of the entry (e.g., "Draft", "Live", "Feed Only", "Web Only",
|
||||
/// "Unlisted")
|
||||
/// - date: The updated publication date for the entry
|
||||
/// - Returns: A configured network request for updating the weblog entry
|
||||
public static func makeUpdateWeblogEntryRequest(
|
||||
address: String,
|
||||
entryID: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) -> NetworkRequest<Data, CreateOrUpdateWeblogEntryResponse> {
|
||||
let body = content.weblogEntryBody(with: date)
|
||||
let body = content.weblogEntryBody(
|
||||
date: date,
|
||||
status: status
|
||||
)
|
||||
|
||||
return .init(
|
||||
path: "/address/\(address)/weblog/entry/\(entryID)",
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@
|
|||
EntryResponseMother.makeEntryResponses(count: 2)
|
||||
}
|
||||
|
||||
func createWeblogEntry(address: String, content: String, date: Date) async throws -> EntryResponse {
|
||||
func createWeblogEntry(
|
||||
address: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws -> EntryResponse {
|
||||
EntryResponseMother.makeEntryResponse()
|
||||
}
|
||||
|
||||
|
|
@ -28,6 +33,7 @@
|
|||
address: String,
|
||||
entryID: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws -> EntryResponse {
|
||||
EntryResponseMother.makeEntryResponse()
|
||||
|
|
|
|||
|
|
@ -39,7 +39,13 @@
|
|||
// MARK: - Public
|
||||
|
||||
func fetchEntries() async throws {}
|
||||
func createOrUpdateEntry(address: String, entryID: String?, body: String, date: Date) async throws {}
|
||||
func createOrUpdateEntry(
|
||||
address: String,
|
||||
entryID: String?,
|
||||
body: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws {}
|
||||
func deleteEntry(address: String, entryID: String) async throws {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ struct EditorView: View {
|
|||
.gridColumnAlignment(.trailing)
|
||||
|
||||
Picker(
|
||||
selection: $viewModel.selectedStatus,
|
||||
selection: $viewModel.status,
|
||||
content: {
|
||||
ForEach(WeblogEntryStatus.allCases) { status in
|
||||
Text(status.displayName)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ final class EditorViewModel {
|
|||
var body: String
|
||||
var entryID: String?
|
||||
var date: Date
|
||||
var selectedStatus: WeblogEntryStatus
|
||||
var status: WeblogEntryStatus
|
||||
var shouldDismiss = false
|
||||
private(set) var isSubmitting = false
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ final class EditorViewModel {
|
|||
self.body = body
|
||||
self.date = date
|
||||
self.entryID = entryID
|
||||
selectedStatus = status
|
||||
self.status = status
|
||||
self.repository = repository
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +63,7 @@ final class EditorViewModel {
|
|||
address: address,
|
||||
entryID: entryID,
|
||||
body: body,
|
||||
status: status.rawValue,
|
||||
date: date
|
||||
)
|
||||
shouldDismiss = true
|
||||
|
|
|
|||
|
|
@ -41,22 +41,24 @@ public protocol WeblogNetworkServiceProtocol: AnyObject, Sendable {
|
|||
/// Creates a new weblog entry for the specified address.
|
||||
///
|
||||
/// This method sends a POST request to the OMG.LOL API to create a new weblog entry.
|
||||
/// The content is formatted with frontmatter including the publication date and
|
||||
/// sent as raw data to the API endpoint.
|
||||
/// The content is formatted with frontmatter including the publication date, status,
|
||||
/// and sent as raw data to the API endpoint.
|
||||
///
|
||||
/// The request requires authentication and will create a new entry with a
|
||||
/// system-generated unique identifier. The entry will be immediately available
|
||||
/// at the user's weblog URL.
|
||||
/// at the user's weblog URL according to the specified status.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - address: The user address (username) to create the entry for
|
||||
/// - content: The markdown content body of the weblog entry
|
||||
/// - status: The publication status of the entry (e.g., "Draft", "Live", "Feed Only", "Web Only", "Unlisted")
|
||||
/// - date: The publication date for the entry
|
||||
/// - Returns: The created weblog entry with metadata and generated ID
|
||||
/// - Throws: Network errors, authentication errors, or API-specific errors.
|
||||
func createWeblogEntry(
|
||||
address: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws -> EntryResponse
|
||||
|
||||
|
|
@ -64,16 +66,18 @@ public protocol WeblogNetworkServiceProtocol: AnyObject, Sendable {
|
|||
///
|
||||
/// This method sends a POST request to the OMG.LOL API to update an existing
|
||||
/// weblog entry identified by its entry ID. The content is formatted with
|
||||
/// frontmatter including the updated publication date and sent as raw data.
|
||||
/// frontmatter including the updated publication date, status, and sent as raw data.
|
||||
///
|
||||
/// The request requires authentication and the user must own the entry being
|
||||
/// updated. The entry's URL and slug will remain unchanged, but the content,
|
||||
/// publication date, and metadata will be updated.
|
||||
/// publication date, status, and metadata will be updated.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - address: The user address (username) who owns the entry
|
||||
/// - entryID: The unique identifier of the entry to update
|
||||
/// - content: The updated markdown content body of the weblog entry
|
||||
/// - status: The updated publication status of the entry (e.g., "Draft", "Live", "Feed Only", "Web Only",
|
||||
/// "Unlisted")
|
||||
/// - date: The updated publication date for the entry
|
||||
/// - Returns: The updated weblog entry with new content and metadata
|
||||
/// - Throws: Network errors, authentication errors, or API-specific errors if the entry is not found.
|
||||
|
|
@ -81,6 +85,7 @@ public protocol WeblogNetworkServiceProtocol: AnyObject, Sendable {
|
|||
address: String,
|
||||
entryID: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws -> EntryResponse
|
||||
|
||||
|
|
@ -143,12 +148,14 @@ actor WeblogNetworkService: WeblogNetworkServiceProtocol {
|
|||
func createWeblogEntry(
|
||||
address: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws -> EntryResponse {
|
||||
let response = try await networkClient.run(
|
||||
WeblogRequestFactory.makeCreateWeblogEntryRequest(
|
||||
address: address,
|
||||
content: content,
|
||||
status: status,
|
||||
date: date
|
||||
)
|
||||
)
|
||||
|
|
@ -163,6 +170,7 @@ actor WeblogNetworkService: WeblogNetworkServiceProtocol {
|
|||
address: String,
|
||||
entryID: String,
|
||||
content: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws -> EntryResponse {
|
||||
let response = try await networkClient.run(
|
||||
|
|
@ -170,6 +178,7 @@ actor WeblogNetworkService: WeblogNetworkServiceProtocol {
|
|||
address: address,
|
||||
entryID: entryID,
|
||||
content: content,
|
||||
status: status,
|
||||
date: date
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public protocol WeblogRepositoryProtocol: Sendable {
|
|||
/// - address: The address for which to create or update the weblog entry.
|
||||
/// - entryID: The unique identifier of the entry to update. If nil, creates a new entry.
|
||||
/// - body: The content body of the weblog entry in markdown format
|
||||
/// - status: The publication status of the entry (e.g., "Draft", "Live", "Feed Only", "Web Only", "Unlisted")
|
||||
/// - date: The publication date for the entry
|
||||
/// - Throws: Network errors from the remote operation or persistence errors
|
||||
/// from the local storage operations.
|
||||
|
|
@ -67,6 +68,7 @@ public protocol WeblogRepositoryProtocol: Sendable {
|
|||
address: String,
|
||||
entryID: String?,
|
||||
body: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws
|
||||
|
||||
|
|
@ -139,6 +141,7 @@ actor WeblogRepository: WeblogRepositoryProtocol {
|
|||
address: String,
|
||||
entryID: String? = nil,
|
||||
body: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws {
|
||||
if let entryID {
|
||||
|
|
@ -146,12 +149,14 @@ actor WeblogRepository: WeblogRepositoryProtocol {
|
|||
address: address,
|
||||
entryID: entryID,
|
||||
body: body,
|
||||
status: status,
|
||||
date: date
|
||||
)
|
||||
} else {
|
||||
try await createEntry(
|
||||
address: address,
|
||||
body: body,
|
||||
status: status,
|
||||
date: date
|
||||
)
|
||||
}
|
||||
|
|
@ -162,6 +167,7 @@ actor WeblogRepository: WeblogRepositoryProtocol {
|
|||
private func createEntry(
|
||||
address: String,
|
||||
body: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws {
|
||||
guard await authSessionService.isLoggedIn else {
|
||||
|
|
@ -171,6 +177,7 @@ actor WeblogRepository: WeblogRepositoryProtocol {
|
|||
_ = try await networkService.createWeblogEntry(
|
||||
address: address,
|
||||
content: body,
|
||||
status: status,
|
||||
date: date
|
||||
)
|
||||
|
||||
|
|
@ -181,6 +188,7 @@ actor WeblogRepository: WeblogRepositoryProtocol {
|
|||
address: String,
|
||||
entryID: String,
|
||||
body: String,
|
||||
status: String,
|
||||
date: Date
|
||||
) async throws {
|
||||
guard await authSessionService.isLoggedIn else {
|
||||
|
|
@ -191,6 +199,7 @@ actor WeblogRepository: WeblogRepositoryProtocol {
|
|||
address: address,
|
||||
entryID: entryID,
|
||||
content: body,
|
||||
status: status,
|
||||
date: date
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue