mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
8.2 KiB
Swift
177 lines
8.2 KiB
Swift
import PromiseKit
|
|
|
|
extension MessageSender {
|
|
|
|
// MARK: Durable
|
|
@objc(send:withAttachments:inThread:usingTransaction:)
|
|
public static func send(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) {
|
|
prep(attachments, for: message, using: transaction)
|
|
send(message, in: thread, using: transaction)
|
|
}
|
|
|
|
@objc(send:inThread:usingTransaction:)
|
|
public static func send(_ message: Message, in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) {
|
|
message.threadID = thread.uniqueId!
|
|
let destination = Message.Destination.from(thread)
|
|
let job = MessageSendJob(message: message, destination: destination)
|
|
JobQueue.shared.add(job, using: transaction)
|
|
}
|
|
|
|
// MARK: Non-Durable
|
|
@objc(sendNonDurably:withAttachments:inThread:usingTransaction:)
|
|
public static func objc_sendNonDurably(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise {
|
|
return AnyPromise.from(sendNonDurably(message, with: attachments, in: thread, using: transaction))
|
|
}
|
|
|
|
@objc(sendNonDurably:withAttachmentIDs:inThread:usingTransaction:)
|
|
public static func objc_sendNonDurably(_ message: VisibleMessage, with attachmentIDs: [String], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise {
|
|
return AnyPromise.from(sendNonDurably(message, with: attachmentIDs, in: thread, using: transaction))
|
|
}
|
|
|
|
@objc(sendNonDurably:inThread:usingTransaction:)
|
|
public static func objc_sendNonDurably(_ message: Message, in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise {
|
|
return AnyPromise.from(sendNonDurably(message, in: thread, using: transaction))
|
|
}
|
|
|
|
public static func sendNonDurably(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> Promise<Void> {
|
|
prep(attachments, for: message, using: transaction)
|
|
return sendNonDurably(message, with: message.attachmentIDs, in: thread, using: transaction)
|
|
}
|
|
|
|
public static func sendNonDurably(_ message: VisibleMessage, with attachmentIDs: [String], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> Promise<Void> {
|
|
let attachments = attachmentIDs.compactMap {
|
|
TSAttachment.fetch(uniqueId: $0, transaction: transaction) as? TSAttachmentStream
|
|
}
|
|
let attachmentsToUpload = attachments.filter { !$0.isUploaded }
|
|
let attachmentUploadPromises: [Promise<String>] = attachmentsToUpload.map { stream in
|
|
let storage = SNMessagingKitConfiguration.shared.storage
|
|
|
|
if let threadId: String = thread.uniqueId, let openGroup = storage.getOpenGroup(for: threadId) {
|
|
let (promise, seal) = Promise<String>.pending()
|
|
AttachmentUploadJob.upload(
|
|
stream,
|
|
using: { data in
|
|
OpenGroupAPI
|
|
.uploadFile(
|
|
data.bytes,
|
|
to: openGroup.room,
|
|
on: openGroup.server
|
|
)
|
|
.map { _, response -> String in response.id }
|
|
},
|
|
encrypt: false,
|
|
onSuccess: { fileId in seal.fulfill(fileId) },
|
|
onFailure: { seal.reject($0) }
|
|
)
|
|
|
|
return promise
|
|
}
|
|
|
|
let (promise, seal) = Promise<String>.pending()
|
|
AttachmentUploadJob.upload(
|
|
stream,
|
|
using: { data in
|
|
FileServerAPI.upload(data)
|
|
.map { response -> String in response.id }
|
|
},
|
|
encrypt: true,
|
|
onSuccess: { fileId in seal.fulfill(fileId) },
|
|
onFailure: { seal.reject($0) }
|
|
)
|
|
return promise
|
|
}
|
|
|
|
return when(resolved: attachmentUploadPromises)
|
|
.then(on: DispatchQueue.global(qos: .userInitiated)) { results -> Promise<Void> in
|
|
let errors = results.compactMap { result -> Swift.Error? in
|
|
if case .rejected(let error) = result { return error } else { return nil }
|
|
}
|
|
if let error = errors.first { return Promise(error: error) }
|
|
let fileIds: [String] = results.compactMap { result -> String? in
|
|
switch result {
|
|
case .fulfilled(let fileId): return fileId
|
|
default: return nil
|
|
}
|
|
}
|
|
|
|
return sendNonDurably(message, in: thread, with: fileIds, using: transaction)
|
|
}
|
|
}
|
|
|
|
public static func sendNonDurably(_ message: Message, in thread: TSThread, with fileIds: [String]? = nil, using transaction: YapDatabaseReadWriteTransaction) -> Promise<Void> {
|
|
message.threadID = thread.uniqueId!
|
|
let destination = Message.Destination.from(thread, fileIds: fileIds)
|
|
return MessageSender.send(message, to: destination, using: transaction)
|
|
}
|
|
|
|
public static func sendNonDurably(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread) -> Promise<Void> {
|
|
Storage.writeSync { transaction in
|
|
prep(attachments, for: message, using: transaction)
|
|
}
|
|
let attachments = message.attachmentIDs.compactMap { TSAttachment.fetch(uniqueId: $0) as? TSAttachmentStream }
|
|
let attachmentsToUpload = attachments.filter { !$0.isUploaded }
|
|
let attachmentUploadPromises: [Promise<String>] = attachmentsToUpload.map { stream in
|
|
let storage = SNMessagingKitConfiguration.shared.storage
|
|
|
|
if let openGroup = storage.getOpenGroup(for: thread.uniqueId!) {
|
|
let (promise, seal) = Promise<String>.pending()
|
|
|
|
AttachmentUploadJob.upload(
|
|
stream,
|
|
using: { data in
|
|
OpenGroupAPI
|
|
.uploadFile(
|
|
data.bytes,
|
|
to: openGroup.room,
|
|
on: openGroup.server
|
|
)
|
|
.map { _, response -> String in response.id }
|
|
},
|
|
encrypt: false,
|
|
onSuccess: { fileId in seal.fulfill(fileId) },
|
|
onFailure: { seal.reject($0) }
|
|
)
|
|
return promise
|
|
}
|
|
|
|
let (promise, seal) = Promise<String>.pending()
|
|
AttachmentUploadJob.upload(
|
|
stream,
|
|
using: { data in
|
|
FileServerAPI.upload(data)
|
|
.map { response -> String in response.id }
|
|
},
|
|
encrypt: true,
|
|
onSuccess: { fileId in seal.fulfill(fileId) },
|
|
onFailure: { seal.reject($0) }
|
|
)
|
|
|
|
return promise
|
|
}
|
|
let (promise, seal) = Promise<Void>.pending()
|
|
let results = when(resolved: attachmentUploadPromises).wait()
|
|
let errors = results.compactMap { result -> Swift.Error? in
|
|
if case .rejected(let error) = result { return error } else { return nil }
|
|
}
|
|
if let error = errors.first { seal.reject(error) }
|
|
let fileIds: [String] = results.compactMap { result -> String? in
|
|
switch result {
|
|
case .fulfilled(let fileId): return fileId
|
|
default: return nil
|
|
}
|
|
}
|
|
|
|
Storage.write { transaction in
|
|
sendNonDurably(message, in: thread, with: fileIds, using: transaction)
|
|
.done {
|
|
seal.fulfill(())
|
|
}
|
|
.catch { error in
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
|
|
return promise
|
|
}
|
|
}
|