|
|
|
@ -2,6 +2,7 @@ import UIKit
|
|
|
|
|
import CoreServices
|
|
|
|
|
import Photos
|
|
|
|
|
import PhotosUI
|
|
|
|
|
import PromiseKit
|
|
|
|
|
import SessionUtilitiesKit
|
|
|
|
|
import SignalUtilitiesKit
|
|
|
|
|
|
|
|
|
@ -262,7 +263,15 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|
|
|
|
let linkPreviewDraft = snInputView.linkPreviewInfo?.draft
|
|
|
|
|
let tsMessage = TSOutgoingMessage.from(message, associatedWith: thread)
|
|
|
|
|
|
|
|
|
|
viewModel.appendUnsavedOutgoingTextMessage(tsMessage)
|
|
|
|
|
Storage.write(with: { transaction in
|
|
|
|
|
let promise: Promise<Void> = self.approveMessageRequestIfNeeded(
|
|
|
|
|
for: self.thread,
|
|
|
|
|
with: transaction,
|
|
|
|
|
isNewThread: !oldThreadShouldBeVisible,
|
|
|
|
|
timestamp: (sentTimestamp - 1) // Set 1ms earlier as this is used for sorting
|
|
|
|
|
)
|
|
|
|
|
.map { [weak self] _ in
|
|
|
|
|
self?.viewModel.appendUnsavedOutgoingTextMessage(tsMessage)
|
|
|
|
|
|
|
|
|
|
Storage.write(with: { transaction in
|
|
|
|
|
message.linkPreview = VisibleMessage.LinkPreview.from(linkPreviewDraft, using: transaction)
|
|
|
|
@ -280,23 +289,22 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
Storage.shared.write(
|
|
|
|
|
with: { transaction in
|
|
|
|
|
self?.approveMessageRequestIfNeeded(
|
|
|
|
|
for: self?.thread,
|
|
|
|
|
with: (transaction as! YapDatabaseReadWriteTransaction),
|
|
|
|
|
isNewThread: !oldThreadShouldBeVisible,
|
|
|
|
|
timestamp: (sentTimestamp - 1) // Set 1ms earlier as this is used for sorting
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
completion: { [weak self] in
|
|
|
|
|
Storage.shared.write { transaction in
|
|
|
|
|
MessageSender.send(message, with: [], in: thread, using: transaction as! YapDatabaseReadWriteTransaction)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self?.handleMessageSent()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Show an error indicating that approving the thread failed
|
|
|
|
|
promise.catch(on: DispatchQueue.main) { [weak self] _ in
|
|
|
|
|
let alert = UIAlertController(title: "Session", message: "An error occurred when trying to accept this message request", preferredStyle: .alert)
|
|
|
|
|
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
|
|
|
|
|
self?.present(alert, animated: true, completion: nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
promise.retainUntilComplete()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -321,21 +329,19 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|
|
|
|
let oldThreadShouldBeVisible: Bool = thread.shouldBeVisible
|
|
|
|
|
let tsMessage = TSOutgoingMessage.from(message, associatedWith: thread)
|
|
|
|
|
|
|
|
|
|
Storage.write(with: { transaction in
|
|
|
|
|
let promise: Promise<Void> = self.approveMessageRequestIfNeeded(
|
|
|
|
|
for: self.thread,
|
|
|
|
|
with: transaction,
|
|
|
|
|
isNewThread: !oldThreadShouldBeVisible,
|
|
|
|
|
timestamp: (sentTimestamp - 1) // Set 1ms earlier as this is used for sorting
|
|
|
|
|
)
|
|
|
|
|
.map { [weak self] _ in
|
|
|
|
|
Storage.write(
|
|
|
|
|
with: { transaction in
|
|
|
|
|
tsMessage.save(with: transaction)
|
|
|
|
|
// The new message cell is inserted at this point, but the TSOutgoingMessage doesn't have its attachment yet
|
|
|
|
|
},
|
|
|
|
|
completion: { [weak self] in
|
|
|
|
|
Storage.shared.write(
|
|
|
|
|
with: { transaction in
|
|
|
|
|
self?.approveMessageRequestIfNeeded(
|
|
|
|
|
for: self?.thread,
|
|
|
|
|
with: (transaction as! YapDatabaseReadWriteTransaction),
|
|
|
|
|
isNewThread: !oldThreadShouldBeVisible,
|
|
|
|
|
timestamp: (sentTimestamp - 1) // Set 1ms earlier as this is used for sorting
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
completion: { [weak self] in
|
|
|
|
|
Storage.write(with: { transaction in
|
|
|
|
|
MessageSender.send(message, with: attachments, in: thread, using: transaction)
|
|
|
|
@ -351,7 +357,16 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Show an error indicating that approving the thread failed
|
|
|
|
|
promise.catch(on: DispatchQueue.main) { [weak self] _ in
|
|
|
|
|
let alert = UIAlertController(title: "Session", message: "An error occurred when trying to accept this message request", preferredStyle: .alert)
|
|
|
|
|
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
|
|
|
|
|
self?.present(alert, animated: true, completion: nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
promise.retainUntilComplete()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func handleMessageSent() {
|
|
|
|
@ -1119,8 +1134,8 @@ extension ConversationVC {
|
|
|
|
|
navigationController?.popToViewController(viewControllers[messageRequestsIndex - 1], animated: true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileprivate func approveMessageRequestIfNeeded(for thread: TSThread?, with transaction: YapDatabaseReadWriteTransaction, isNewThread: Bool, timestamp: UInt64) {
|
|
|
|
|
guard let contactThread: TSContactThread = thread as? TSContactThread else { return }
|
|
|
|
|
fileprivate func approveMessageRequestIfNeeded(for thread: TSThread?, with transaction: YapDatabaseReadWriteTransaction, isNewThread: Bool, timestamp: UInt64) -> Promise<Void> {
|
|
|
|
|
guard let contactThread: TSContactThread = thread as? TSContactThread else { return Promise.value(()) }
|
|
|
|
|
|
|
|
|
|
// If the contact doesn't exist then we should create it so we can store the 'isApproved' state
|
|
|
|
|
// (it'll be updated with correct profile info if they accept the message request so this
|
|
|
|
@ -1128,23 +1143,27 @@ extension ConversationVC {
|
|
|
|
|
let sessionId: String = contactThread.contactSessionID()
|
|
|
|
|
let contact: Contact = (Storage.shared.getContact(with: sessionId) ?? Contact(sessionID: sessionId))
|
|
|
|
|
|
|
|
|
|
if !contact.isApproved {
|
|
|
|
|
// Default 'didApproveMe' to true for the person approving the message request
|
|
|
|
|
contact.isApproved = true
|
|
|
|
|
contact.didApproveMe = (contact.didApproveMe || !isNewThread)
|
|
|
|
|
Storage.shared.setContact(contact, using: transaction)
|
|
|
|
|
guard !contact.isApproved else { return Promise.value(()) }
|
|
|
|
|
|
|
|
|
|
return Promise.value(())
|
|
|
|
|
.then { _ -> Promise<Void> in
|
|
|
|
|
guard !isNewThread else { return Promise.value(()) }
|
|
|
|
|
|
|
|
|
|
// If we aren't creating a new thread (ie. sending a message request) then send a
|
|
|
|
|
// messageRequestResponse back to the sender (this allows the sender to know that
|
|
|
|
|
// they have been approved and can now use this contact in closed groups)
|
|
|
|
|
if !isNewThread {
|
|
|
|
|
let messageRequestResponse: MessageRequestResponse = MessageRequestResponse(
|
|
|
|
|
isApproved: true
|
|
|
|
|
)
|
|
|
|
|
messageRequestResponse.sentTimestamp = timestamp
|
|
|
|
|
|
|
|
|
|
MessageSender.send(messageRequestResponse, in: contactThread, using: transaction)
|
|
|
|
|
return MessageSender.sendNonDurably(messageRequestResponse, in: contactThread, using: transaction)
|
|
|
|
|
}
|
|
|
|
|
.map { _ in
|
|
|
|
|
// Default 'didApproveMe' to true for the person approving the message request
|
|
|
|
|
contact.isApproved = true
|
|
|
|
|
contact.didApproveMe = (contact.didApproveMe || !isNewThread)
|
|
|
|
|
Storage.shared.setContact(contact, using: transaction)
|
|
|
|
|
|
|
|
|
|
// Hide the 'messageRequestView' since the request has been approved and force a config
|
|
|
|
|
// sync to propagate the contact approval state (both must run on the main thread)
|
|
|
|
@ -1179,13 +1198,22 @@ extension ConversationVC {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@objc func acceptMessageRequest() {
|
|
|
|
|
Storage.write { [weak self] transaction in
|
|
|
|
|
self?.approveMessageRequestIfNeeded(
|
|
|
|
|
for: self?.thread,
|
|
|
|
|
Storage.write { transaction in
|
|
|
|
|
let promise: Promise<Void> = self.approveMessageRequestIfNeeded(
|
|
|
|
|
for: self.thread,
|
|
|
|
|
with: transaction,
|
|
|
|
|
isNewThread: false,
|
|
|
|
|
timestamp: NSDate.millisecondTimestamp()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Show an error indicating that approving the thread failed
|
|
|
|
|
promise.catch(on: DispatchQueue.main) { [weak self] _ in
|
|
|
|
|
let alert = UIAlertController(title: "Session", message: "An error occurred when trying to accept this message request", preferredStyle: .alert)
|
|
|
|
|
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
|
|
|
|
|
self?.present(alert, animated: true, completion: nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
promise.retainUntilComplete()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|