Fix attachments not being posted in the correct order.

This commit is contained in:
Shadowfacts 2020-09-14 23:29:31 -04:00
parent 2c1ba7926e
commit be5a4c03a6
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
1 changed files with 31 additions and 9 deletions

View File

@ -229,36 +229,57 @@ struct ComposeView: View {
private func uploadAttachments(_ completion: @escaping (Result<[Attachment], AttachmentUploadError>) -> Void) { private func uploadAttachments(_ completion: @escaping (Result<[Attachment], AttachmentUploadError>) -> Void) {
let group = DispatchGroup() let group = DispatchGroup()
var anyFailed = false var attachmentDatas = [(Data, String)?]()
var uploadedAttachments = [Result<Attachment, Error>?]()
for (index, compAttachment) in draft.attachments.enumerated() { for (index, compAttachment) in draft.attachments.enumerated() {
group.enter() group.enter()
uploadedAttachments.append(nil) attachmentDatas.append(nil)
compAttachment.data.getData { (data, mimeType) in compAttachment.data.getData { (data, mimeType) in
postProgress += 1 postProgress += 1
attachmentDatas[index] = (data, mimeType)
group.leave()
}
}
group.notify(queue: .global(qos: .userInitiated)) {
var anyFailed = false
var uploadedAttachments = [Result<Attachment, Error>?]()
// Mastodon does not respect the order of the `media_ids` parameter in the create post request,
// it determines attachment order by which was uploaded first. Since the upload attachment request
// does not include any timestamp data, and requests may arrive at the server out-of-order,
// attachments need to be uploaded serially in order to ensure the order of attachments in the
// posted status reflects order the user set.
// Pleroma does respect the order of the `media_ids` parameter.
for (index, (data, mimeType)) in attachmentDatas.map(\.unsafelyUnwrapped).enumerated() {
group.enter()
let compAttachment = draft.attachments[index]
let formAttachment = FormAttachment(mimeType: mimeType, data: data, fileName: "file") let formAttachment = FormAttachment(mimeType: mimeType, data: data, fileName: "file")
let request = Client.upload(attachment: formAttachment, description: compAttachment.attachmentDescription) let request = Client.upload(attachment: formAttachment, description: compAttachment.attachmentDescription)
self.mastodonController.run(request) { (response) in self.mastodonController.run(request) { (response) in
switch response { switch response {
case let .failure(error): case let .failure(error):
uploadedAttachments[index] = .failure(error) uploadedAttachments.append(.failure(error))
anyFailed = true anyFailed = true
case let .success(attachment, _): case let .success(attachment, _):
postProgress += 1 self.postProgress += 1
uploadedAttachments[index] = .success(attachment) uploadedAttachments.append(.success(attachment))
} }
group.leave() group.leave()
} }
}
}
group.notify(queue: .main) { group.wait()
}
if anyFailed { if anyFailed {
let errors = uploadedAttachments.map { (result) -> Error? in let errors = uploadedAttachments.map { (result) -> Error? in
if case let .failure(error) = result { if case let .failure(error) = result {
@ -274,6 +295,7 @@ struct ComposeView: View {
} }
completion(.success(uploadedAttachments)) completion(.success(uploadedAttachments))
} }
} }
} }
} }