From e4def22472e9f9c9bda2a25a0a73d0f71c145095 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Thu, 24 Mar 2022 15:46:53 +1100 Subject: [PATCH] Moved the Storage.write call into the `self.approveMessageRequestIfNeeded` call --- .../ConversationVC+Interaction.swift | 201 +++++++++--------- Session/Meta/AppDelegate.swift | 2 +- 2 files changed, 103 insertions(+), 100 deletions(-) diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 21f0dfbee..0b26218e7 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -263,49 +263,46 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc let linkPreviewDraft = snInputView.linkPreviewInfo?.draft let tsMessage = TSOutgoingMessage.from(message, associatedWith: thread) - Storage.write(with: { transaction in - let promise: Promise = 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) - }, completion: { [weak self] in - tsMessage.linkPreview = OWSLinkPreview.from(message.linkPreview) - - Storage.shared.write( - with: { transaction in - tsMessage.save(with: transaction as! YapDatabaseReadWriteTransaction) - }, - completion: { [weak self] in - // At this point the TSOutgoingMessage should have its link preview set, so we can scroll to the bottom knowing - // the height of the new message cell - self?.scrollToBottom(isAnimated: false) - } - ) - - Storage.shared.write { transaction in - MessageSender.send(message, with: [], in: thread, using: transaction as! YapDatabaseReadWriteTransaction) + let promise: Promise = self.approveMessageRequestIfNeeded( + for: self.thread, + 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) + }, completion: { [weak self] in + tsMessage.linkPreview = OWSLinkPreview.from(message.linkPreview) + + Storage.shared.write( + with: { transaction in + tsMessage.save(with: transaction as! YapDatabaseReadWriteTransaction) + }, + completion: { [weak self] in + // At this point the TSOutgoingMessage should have its link preview set, so we can scroll to the bottom knowing + // the height of the new message cell + self?.scrollToBottom(isAnimated: false) } - - 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() - }) + ) + + 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() } func sendAttachments(_ attachments: [SignalAttachment], with text: String, onComplete: (() -> ())? = nil) { @@ -329,44 +326,41 @@ 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 = self.approveMessageRequestIfNeeded( - for: self.thread, - with: transaction, - isNewThread: !oldThreadShouldBeVisible, - timestamp: (sentTimestamp - 1) // Set 1ms earlier as this is used for sorting + let promise: Promise = self.approveMessageRequestIfNeeded( + for: self.thread, + 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.write(with: { transaction in + MessageSender.send(message, with: attachments, in: thread, using: transaction) + }, completion: { [weak self] in + // At this point the TSOutgoingMessage should have its attachments set, so we can scroll to the bottom knowing + // the height of the new message cell + self?.scrollToBottom(isAnimated: false) + }) + self?.handleMessageSent() + + // Attachment successfully sent - dismiss the screen + onComplete?() + } ) - .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.write(with: { transaction in - MessageSender.send(message, with: attachments, in: thread, using: transaction) - }, completion: { [weak self] in - // At this point the TSOutgoingMessage should have its attachments set, so we can scroll to the bottom knowing - // the height of the new message cell - self?.scrollToBottom(isAnimated: false) - }) - self?.handleMessageSent() - - // Attachment successfully sent - dismiss the screen - onComplete?() - } - ) - } + } + + // 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) + } - // 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() - }) + promise.retainUntilComplete() } func handleMessageSent() { @@ -1103,7 +1097,7 @@ extension ConversationVC: UIDocumentInteractionControllerDelegate { extension ConversationVC { - fileprivate func approveMessageRequestIfNeeded(for thread: TSThread?, with transaction: YapDatabaseReadWriteTransaction, isNewThread: Bool, timestamp: UInt64) -> Promise { + fileprivate func approveMessageRequestIfNeeded(for thread: TSThread?, isNewThread: Bool, timestamp: UInt64) -> Promise { 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 @@ -1134,7 +1128,17 @@ extension ConversationVC { } return promise - .then { MessageSender.sendNonDurably(messageRequestResponse, in: contactThread, using: transaction) } + .then { _ -> Promise in + let (promise, seal) = Promise.pending() + Storage.writeSync { transaction in + MessageSender.sendNonDurably(messageRequestResponse, in: contactThread, using: transaction) + .done { seal.fulfill(()) } + .catch { _ in seal.fulfill(()) } // Fulfill even if this failed; the configuration in the swarm should be at most 2 days old + .retainUntilComplete() + } + + return promise + } .map { _ in if self?.presentedViewController is ModalActivityIndicatorViewController { self?.dismiss(animated: true, completion: nil) // Dismiss the loader @@ -1143,9 +1147,11 @@ extension ConversationVC { } .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) + Storage.write { transaction in + 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) @@ -1190,23 +1196,20 @@ extension ConversationVC { } @objc func acceptMessageRequest() { - Storage.write { transaction in - let promise: Promise = 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: NSLocalizedString("MESSAGE_REQUESTS_APPROVAL_ERROR_MESSAGE", comment: ""), preferredStyle: .alert) - alert.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""), style: .default, handler: nil)) - self?.present(alert, animated: true, completion: nil) - } - - promise.retainUntilComplete() + let promise: Promise = self.approveMessageRequestIfNeeded( + for: self.thread, + 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: NSLocalizedString("MESSAGE_REQUESTS_APPROVAL_ERROR_MESSAGE", comment: ""), preferredStyle: .alert) + alert.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""), style: .default, handler: nil)) + self?.present(alert, animated: true, completion: nil) } + + promise.retainUntilComplete() } @objc func deleteMessageRequest() { diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index a6815f954..6f1182807 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -29,7 +29,7 @@ extension AppDelegate { // Note: SQLite only supports a single write thread so we can be sure this will retrieve the most up-to-date data Storage.writeSync { transaction in - guard Storage.shared.getUser()?.name != nil, let configurationMessage = ConfigurationMessage.getCurrent(with: transaction) else { + guard Storage.shared.getUser(using: transaction)?.name != nil, let configurationMessage = ConfigurationMessage.getCurrent(with: transaction) else { seal.fulfill(()) return }