wip
This commit is contained in:
parent
c1ce9b133d
commit
1780360fb4
|
@ -5,4 +5,9 @@ enum XMPPAction: Codable {
|
|||
case xmppMessageSent(Message)
|
||||
case xmppMessageSendFailed(msgId: String)
|
||||
case xmppMessageSendSuccess(msgId: String)
|
||||
|
||||
case xmppAttachmentUpload(Message)
|
||||
// case xmppAttachmentSlotRequestDone(String) //TODO: ???
|
||||
case xmppAttachmentUploadFailed(msgId: String, reason: String)
|
||||
case xmppAttachmentUploadSuccess(msgId: String, attachmentRemotePath: String)
|
||||
}
|
||||
|
|
|
@ -100,6 +100,20 @@ final class XMPPMiddleware {
|
|||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
case .xmppAction(.xmppAttachmentUpload(let message)):
|
||||
return Future<AppAction, Never> { [weak self] promise in
|
||||
DispatchQueue.global().async {
|
||||
self?.service.uploadAttachment(message: message) { done, remotePath in
|
||||
if done {
|
||||
promise(.success(.xmppAction(.xmppAttachmentUploadSuccess(msgId: message.id, attachmentRemotePath: remotePath))))
|
||||
} else {
|
||||
promise(.success(.xmppAction(.xmppAttachmentUploadFailed(msgId: message.id, reason: "Upload failed"))))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
default:
|
||||
return Empty().eraseToAnyPublisher()
|
||||
}
|
||||
|
|
|
@ -83,6 +83,9 @@ final class XMPPService: ObservableObject {
|
|||
client.modulesManager.register(MessageCarbonsModule())
|
||||
client.modulesManager.register(MessageArchiveManagementModule())
|
||||
|
||||
// file transfer modules
|
||||
client.modulesManager.register(HttpFileUploadModule())
|
||||
|
||||
// extensions
|
||||
client.modulesManager.register(SoftwareVersionModule())
|
||||
client.modulesManager.register(PingModule())
|
||||
|
@ -125,6 +128,65 @@ final class XMPPService: ObservableObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func uploadAttachment(message: Message, completion: @escaping (Error?, String) -> Void) {
|
||||
guard let client = getClient(for: message.from), let to = message.to else {
|
||||
completion(XMPPError.bad_request("No such client"), "")
|
||||
return
|
||||
}
|
||||
guard let fileName = message.attachmentLocalName else {
|
||||
completion(XMPPError.bad_request("No such file"), "")
|
||||
return
|
||||
}
|
||||
let url = FileProcessing.fileFolder.appendingPathComponent(fileName)
|
||||
guard let data = try? Data(contentsOf: url) else {
|
||||
completion(XMPPError.bad_request("No such file"), "")
|
||||
return
|
||||
}
|
||||
|
||||
let httpModule = client.module(HttpFileUploadModule.self)
|
||||
httpModule.findHttpUploadComponent { res in
|
||||
switch res {
|
||||
case .success(let components):
|
||||
guard let component = components.first(where: { $0.maxSize > data.count }) else {
|
||||
completion(XMPPError.bad_request("File too big"), "")
|
||||
return
|
||||
}
|
||||
httpModule.requestUploadSlot(componentJid: component.jid, filename: fileName, size: data.count, contentType: url.mimeType) { res in
|
||||
switch res {
|
||||
case .success(let slot):
|
||||
var request = URLRequest(url: slot.putUri)
|
||||
for (k, v) in slot.putHeaders {
|
||||
request.addValue(v, forHTTPHeaderField: k)
|
||||
}
|
||||
request.httpMethod = "PUT"
|
||||
request.httpBody = data
|
||||
request.addValue(String(data.count), forHTTPHeaderField: "Content-Length")
|
||||
request.addValue(url.mimeType, forHTTPHeaderField: "Content-Type")
|
||||
let session = URLSession(configuration: URLSessionConfiguration.default)
|
||||
session.dataTask(with: request) { _, response, error in
|
||||
let code = (response as? HTTPURLResponse)?.statusCode ?? 500
|
||||
guard error == nil, code == 200 || code == 201 else {
|
||||
completion(XMPPError.bad_request("Upload failed"), "")
|
||||
return
|
||||
}
|
||||
if code == 200 {
|
||||
completion(XMPPError.bad_request("Invalid response code"), "")
|
||||
} else {
|
||||
completion(nil, slot.getUri.absoluteString)
|
||||
}
|
||||
}.resume()
|
||||
|
||||
case .failure:
|
||||
completion(XMPPError.bad_request("Upload failed"), "")
|
||||
}
|
||||
}
|
||||
|
||||
case .failure:
|
||||
completion(XMPPError.bad_request("No such component"), "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// open class HTTPFileUploadHelper {
|
||||
|
|
13
ConversationsClassic/Helpers/URL+Extensions.swift
Normal file
13
ConversationsClassic/Helpers/URL+Extensions.swift
Normal file
|
@ -0,0 +1,13 @@
|
|||
import UniformTypeIdentifiers
|
||||
|
||||
extension URL {
|
||||
var mimeType: String {
|
||||
let pathExtension = self.pathExtension
|
||||
|
||||
if let uti = UTType(filenameExtension: pathExtension) {
|
||||
return uti.preferredMIMEType ?? "application/octet-stream"
|
||||
} else {
|
||||
return "application/octet-stream"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue