From 0eb000224ee591cb660fc9cc48cb3bad8695a3c4 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 8 Jul 2023 15:24:36 -0700 Subject: [PATCH] Fix double posting in poor network conditions Closes #421 --- .../Sources/ComposeUI/API/PostService.swift | 3 +- .../Pachyderm/Sources/Pachyderm/Client.swift | 32 +++++++++++-------- .../Sources/Pachyderm/Request/Request.swift | 1 + 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Packages/ComposeUI/Sources/ComposeUI/API/PostService.swift b/Packages/ComposeUI/Sources/ComposeUI/API/PostService.swift index 94704e38..5a202928 100644 --- a/Packages/ComposeUI/Sources/ComposeUI/API/PostService.swift +++ b/Packages/ComposeUI/Sources/ComposeUI/API/PostService.swift @@ -77,7 +77,8 @@ class PostService: ObservableObject { pollOptions: draft.poll?.pollOptions.map(\.text), pollExpiresIn: draft.poll == nil ? nil : Int(draft.poll!.duration), pollMultiple: draft.poll?.multiple, - localOnly: mastodonController.instanceFeatures.localOnlyPosts ? draft.localOnly : nil + localOnly: mastodonController.instanceFeatures.localOnlyPosts ? draft.localOnly : nil, + idempotencyKey: draft.id.uuidString ) } diff --git a/Packages/Pachyderm/Sources/Pachyderm/Client.swift b/Packages/Pachyderm/Sources/Pachyderm/Client.swift index f34e423a..fad780d8 100644 --- a/Packages/Pachyderm/Sources/Pachyderm/Client.swift +++ b/Packages/Pachyderm/Sources/Pachyderm/Client.swift @@ -113,6 +113,9 @@ public class Client { var urlRequest = URLRequest(url: url, timeoutInterval: timeoutInterval) urlRequest.httpMethod = request.method.name urlRequest.httpBody = request.body.data + for (name, value) in request.headers { + urlRequest.setValue(value, forHTTPHeaderField: name) + } if let mimeType = request.body.mimeType { urlRequest.setValue(mimeType, forHTTPHeaderField: "Content-Type") } @@ -397,19 +400,22 @@ public class Client { pollOptions: [String]? = nil, pollExpiresIn: Int? = nil, pollMultiple: Bool? = nil, - localOnly: Bool? = nil /* hometown only, not glitch */) -> Request { - return Request(method: .post, path: "/api/v1/statuses", body: ParametersBody([ - "status" => text, - "content_type" => contentType.mimeType, - "in_reply_to_id" => inReplyTo, - "sensitive" => sensitive, - "spoiler_text" => spoilerText, - "visibility" => visibility?.rawValue, - "language" => language, - "poll[expires_in]" => pollExpiresIn, - "poll[multiple]" => pollMultiple, - "local_only" => localOnly, - ] + "media_ids" => mediaIDs + "poll[options]" => pollOptions)) + localOnly: Bool? = nil, /* hometown only, not glitch */ + idempotencyKey: String) -> Request { + var req = Request(method: .post, path: "/api/v1/statuses", body: ParametersBody([ + "status" => text, + "content_type" => contentType.mimeType, + "in_reply_to_id" => inReplyTo, + "sensitive" => sensitive, + "spoiler_text" => spoilerText, + "visibility" => visibility?.rawValue, + "language" => language, + "poll[expires_in]" => pollExpiresIn, + "poll[multiple]" => pollMultiple, + "local_only" => localOnly, + ] + "media_ids" => mediaIDs + "poll[options]" => pollOptions)) + req.headers["Idempotency-Key"] = idempotencyKey + return req } public static func editStatus( diff --git a/Packages/Pachyderm/Sources/Pachyderm/Request/Request.swift b/Packages/Pachyderm/Sources/Pachyderm/Request/Request.swift index 22f30b2f..d7ca78d0 100644 --- a/Packages/Pachyderm/Sources/Pachyderm/Request/Request.swift +++ b/Packages/Pachyderm/Sources/Pachyderm/Request/Request.swift @@ -13,6 +13,7 @@ public struct Request: Sendable { let endpoint: Endpoint let body: Body var queryParameters: [Parameter] + var headers: [String: String] = [:] var additionalAcceptableHTTPCodes: [Int] = [] init(method: Method, path: Endpoint, body: Body = EmptyBody(), queryParameters: [Parameter] = []) {