Made a couple of tweaks to the GRDBStorage interface
Updated the ControlMessageProcessRecord to allow for duplicate handling of UnsendRequest messages
This commit is contained in:
parent
1720e85e8f
commit
4133a49a34
|
@ -397,7 +397,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
|
|||
let webRTCSession: WebRTCSession = self.webRTCSession
|
||||
|
||||
GRDBStorage.shared
|
||||
.write { db in webRTCSession.sendOffer(db, to: sessionId, isRestartingICEConnection: true) }
|
||||
.read { db in webRTCSession.sendOffer(db, to: sessionId, isRestartingICEConnection: true) }
|
||||
.retainUntilComplete()
|
||||
}
|
||||
|
||||
|
|
|
@ -417,7 +417,7 @@ final class EditClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegat
|
|||
|
||||
ModalActivityIndicatorViewController.present(fromViewController: navigationController) { _ in
|
||||
GRDBStorage.shared
|
||||
.write { db in
|
||||
.writeAsync { db in
|
||||
if !updatedMemberIds.contains(userPublicKey) {
|
||||
return try MessageSender.leave(db, groupPublicKey: threadId)
|
||||
}
|
||||
|
|
|
@ -196,27 +196,28 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate
|
|||
let selectedContacts = self.selectedContacts
|
||||
let message: String? = (selectedContacts.count > 20) ? "Please wait while the group is created..." : nil
|
||||
ModalActivityIndicatorViewController.present(fromViewController: navigationController!, message: message) { [weak self] _ in
|
||||
let promise: Promise<SessionThread> = GRDBStorage.shared.write { db in
|
||||
try MessageSender.createClosedGroup(db, name: name, members: selectedContacts)
|
||||
}
|
||||
|
||||
let _ = promise.done(on: DispatchQueue.main) { thread in
|
||||
GRDBStorage.shared.write { db in
|
||||
try? MessageSender.syncConfiguration(db, forceSyncNow: true).retainUntilComplete()
|
||||
GRDBStorage.shared
|
||||
.writeAsync { db in
|
||||
try MessageSender.createClosedGroup(db, name: name, members: selectedContacts)
|
||||
}
|
||||
|
||||
self?.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||
SessionApp.presentConversation(for: thread.id, action: .compose, animated: false)
|
||||
}
|
||||
promise.catch(on: DispatchQueue.main) { [weak self] _ in
|
||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||
|
||||
let title = "Couldn't Create Group"
|
||||
let message = "Please check your internet connection and try again."
|
||||
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""), style: .default, handler: nil))
|
||||
self?.presentAlert(alert)
|
||||
}
|
||||
.done(on: DispatchQueue.main) { thread in
|
||||
GRDBStorage.shared.writeAsync { db in
|
||||
try? MessageSender.syncConfiguration(db, forceSyncNow: true).retainUntilComplete()
|
||||
}
|
||||
|
||||
self?.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||
SessionApp.presentConversation(for: thread.id, action: .compose, animated: false)
|
||||
}
|
||||
.catch(on: DispatchQueue.main) { [weak self] _ in
|
||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||
|
||||
let title = "Couldn't Create Group"
|
||||
let message = "Please check your internet connection and try again."
|
||||
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""), style: .default, handler: nil))
|
||||
self?.presentAlert(alert)
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1680,7 +1680,7 @@ extension ConversationVC {
|
|||
|
||||
return promise
|
||||
.then { _ -> Promise<Void> in
|
||||
GRDBStorage.shared.write { db in
|
||||
GRDBStorage.shared.writeAsync { db in
|
||||
try MessageSender.sendNonDurably(
|
||||
db,
|
||||
message: messageRequestResponse,
|
||||
|
|
|
@ -359,7 +359,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
|
|||
// MARK: - Functions
|
||||
|
||||
public func updateDraft(to draft: String) {
|
||||
GRDBStorage.shared.write { db in
|
||||
GRDBStorage.shared.writeAsync { db in
|
||||
try SessionThread
|
||||
.filter(id: self.threadId)
|
||||
.updateAll(db, SessionThread.Columns.messageDraft.set(to: draft))
|
||||
|
|
|
@ -92,24 +92,26 @@ final class JoinOpenGroupModal: Modal {
|
|||
|
||||
presentingViewController.dismiss(animated: true, completion: nil)
|
||||
|
||||
GRDBStorage.shared.write { db in
|
||||
OpenGroupManager.shared.add(
|
||||
db,
|
||||
roomToken: room,
|
||||
server: server,
|
||||
publicKey: publicKey,
|
||||
isConfigMessage: false
|
||||
)
|
||||
}
|
||||
.done(on: DispatchQueue.main) { _ in
|
||||
GRDBStorage.shared.write { db in
|
||||
try MessageSender.syncConfiguration(db, forceSyncNow: true).retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
|
||||
GRDBStorage.shared
|
||||
.writeAsync { db in
|
||||
OpenGroupManager.shared.add(
|
||||
db,
|
||||
roomToken: room,
|
||||
server: server,
|
||||
publicKey: publicKey,
|
||||
isConfigMessage: false
|
||||
)
|
||||
}
|
||||
}
|
||||
.catch(on: DispatchQueue.main) { error in
|
||||
let alert = UIAlertController(title: "Couldn't Join", message: error.localizedDescription, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "BUTTON_OK".localized(), style: .default, handler: nil))
|
||||
presentingViewController.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
.done(on: DispatchQueue.main) { _ in
|
||||
GRDBStorage.shared.writeAsync { db in
|
||||
try MessageSender.syncConfiguration(db, forceSyncNow: true).retainUntilComplete() // FIXME: It's probably cleaner to do this inside addOpenGroup(...)
|
||||
}
|
||||
}
|
||||
.catch(on: DispatchQueue.main) { error in
|
||||
let alert = UIAlertController(title: "Couldn't Join", message: error.localizedDescription, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "BUTTON_OK".localized(), style: .default, handler: nil))
|
||||
presentingViewController.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -591,18 +591,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
|
||||
guard Date().timeIntervalSince(lastSync) > (7 * 24 * 60 * 60) else { return } // Sync every 2 days
|
||||
|
||||
GRDBStorage.shared.write { db in
|
||||
try MessageSender.syncConfiguration(db, forceSyncNow: false)
|
||||
.done {
|
||||
// Only update the 'lastConfigurationSync' timestamp if we have done the
|
||||
// first sync (Don't want a new device config sync to override config
|
||||
// syncs from other devices)
|
||||
if UserDefaults.standard[.hasSyncedInitialConfiguration] {
|
||||
UserDefaults.standard[.lastConfigurationSync] = Date()
|
||||
}
|
||||
GRDBStorage.shared
|
||||
.writeAsync { db in try MessageSender.syncConfiguration(db, forceSyncNow: false) }
|
||||
.done {
|
||||
// Only update the 'lastConfigurationSync' timestamp if we have done the
|
||||
// first sync (Don't want a new device config sync to override config
|
||||
// syncs from other devices)
|
||||
if UserDefaults.standard[.hasSyncedInitialConfiguration] {
|
||||
UserDefaults.standard[.lastConfigurationSync] = Date()
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -444,7 +444,9 @@ class NotificationActionHandler {
|
|||
throw NotificationError.failDebug("unable to find thread with id: \(threadId)")
|
||||
}
|
||||
|
||||
let promise: Promise<Void> = GRDBStorage.shared.write { db in
|
||||
let (promise, seal) = Promise<Void>.pending()
|
||||
|
||||
GRDBStorage.shared.writeAsync { db in
|
||||
let interaction: Interaction = try Interaction(
|
||||
threadId: thread.id,
|
||||
authorId: getUserHexEncodedPublicKey(db),
|
||||
|
@ -468,12 +470,15 @@ class NotificationActionHandler {
|
|||
in: thread
|
||||
)
|
||||
}
|
||||
|
||||
promise.catch { [weak self] error in
|
||||
GRDBStorage.shared.read { db in
|
||||
.done { seal.fulfill(()) }
|
||||
.catch { error in
|
||||
GRDBStorage.shared.read { [weak self] db in
|
||||
self?.notificationPresenter.notifyForFailedSend(db, in: thread)
|
||||
}
|
||||
|
||||
seal.reject(error)
|
||||
}
|
||||
.retainUntilComplete()
|
||||
|
||||
return promise
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ final class JoinOpenGroupVC: BaseVC, UIPageViewControllerDataSource, UIPageViewC
|
|||
|
||||
ModalActivityIndicatorViewController.present(fromViewController: navigationController, canCancel: false) { [weak self] _ in
|
||||
GRDBStorage.shared
|
||||
.write { db in
|
||||
.writeAsync { db in
|
||||
OpenGroupManager.shared.add(
|
||||
db,
|
||||
roomToken: roomToken,
|
||||
|
|
|
@ -154,17 +154,16 @@ final class NukeDataModal: Modal {
|
|||
|
||||
@objc private func clearDeviceOnly() {
|
||||
ModalActivityIndicatorViewController.present(fromViewController: self, canCancel: false) { [weak self] _ in
|
||||
GRDBStorage.shared.write { db in
|
||||
try MessageSender.syncConfiguration(db, forceSyncNow: true)
|
||||
.ensure(on: DispatchQueue.main) {
|
||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||
|
||||
UserDefaults.removeAll() // Not done in the nuke data implementation as unlinking requires this to happen later
|
||||
General.cache.mutate { $0.encodedPublicKey = nil } // Remove the cached key so it gets re-cached on next access
|
||||
NotificationCenter.default.post(name: .dataNukeRequested, object: nil)
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
GRDBStorage.shared
|
||||
.writeAsync { db in try MessageSender.syncConfiguration(db, forceSyncNow: true) }
|
||||
.ensure(on: DispatchQueue.main) {
|
||||
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
|
||||
|
||||
UserDefaults.removeAll() // Not done in the nuke data implementation as unlinking requires this to happen later
|
||||
General.cache.mutate { $0.encodedPublicKey = nil } // Remove the cached key so it gets re-cached on next access
|
||||
NotificationCenter.default.post(name: .dataNukeRequested, object: nil)
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
|
|||
}
|
||||
}
|
||||
GRDBStorage.shared
|
||||
.write { db in
|
||||
.writeAsync { db in
|
||||
try MessageSender
|
||||
.sendNonDurably(
|
||||
db,
|
||||
|
|
|
@ -71,6 +71,13 @@ public struct ControlMessageProcessRecord: Codable, FetchableRecord, Persistable
|
|||
// the unique constraints on that table prevent duplicate messages
|
||||
if message is VisibleMessage { return nil }
|
||||
|
||||
// Allow duplicates for UnsendRequest messages, if a user received an UnsendRequest
|
||||
// as a push notification the it wouldn't include a serverHash and, as a result,
|
||||
// wouldn't get deleted from the server - since the logic only runs if we find a
|
||||
// matching message the safest option is to allow duplicate handling to avoid an
|
||||
// edge-case where a message doesn't get deleted
|
||||
if message is UnsendRequest { return nil }
|
||||
|
||||
// Allow duplicates for all call messages, the double checking will be done on
|
||||
// message handling to make sure the messages are for the same ongoing call
|
||||
if message is CallMessage { return nil }
|
||||
|
|
|
@ -130,7 +130,7 @@ public enum MessageSendJob: JobExecutor {
|
|||
details.message.threadId = (details.message.threadId ?? job.threadId)
|
||||
|
||||
// Perform the actual message sending
|
||||
GRDBStorage.shared.write { db -> Promise<Void> in
|
||||
GRDBStorage.shared.writeAsync { db -> Promise<Void> in
|
||||
try MessageSender.sendImmediate(
|
||||
db,
|
||||
message: details.message,
|
||||
|
@ -170,6 +170,7 @@ public enum MessageSendJob: JobExecutor {
|
|||
failure(job, error, false)
|
||||
}
|
||||
}
|
||||
.retainUntilComplete()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ public enum SendReadReceiptsJob: JobExecutor {
|
|||
}
|
||||
|
||||
GRDBStorage.shared
|
||||
.write { db in
|
||||
.writeAsync { db in
|
||||
try MessageSender.sendImmediate(
|
||||
db,
|
||||
message: ReadReceipt(
|
||||
|
|
|
@ -194,7 +194,7 @@ public final class OpenGroupManager: NSObject {
|
|||
// Note: We don't do this after the db commit as it can fail (resulting in endless loading)
|
||||
OpenGroupAPI.workQueue.async {
|
||||
dependencies.storage
|
||||
.write { db in
|
||||
.writeAsync { db in
|
||||
OpenGroupAPI
|
||||
.capabilitiesAndRoom(
|
||||
db,
|
||||
|
@ -809,7 +809,7 @@ public final class OpenGroupManager: NSObject {
|
|||
// Trigger the download on a background queue
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
dependencies.storage
|
||||
.write { db in
|
||||
.writeAsync { db in
|
||||
OpenGroupAPI
|
||||
.downloadFile(
|
||||
db,
|
||||
|
@ -832,6 +832,7 @@ public final class OpenGroupManager: NSObject {
|
|||
seal.fulfill(imageData)
|
||||
}
|
||||
.catch { seal.reject($0) }
|
||||
.retainUntilComplete()
|
||||
}
|
||||
|
||||
dependencies.mutableCache.mutate { cache in
|
||||
|
|
|
@ -164,8 +164,7 @@ extension MessageSender {
|
|||
}
|
||||
|
||||
if let error: Error = errors.first { return Promise(error: error) }
|
||||
|
||||
return GRDBStorage.shared.write { db in
|
||||
return GRDBStorage.shared.writeAsync { db in
|
||||
try MessageSender.sendImmediate(
|
||||
db,
|
||||
message: message,
|
||||
|
|
|
@ -221,7 +221,7 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView
|
|||
|
||||
ModalActivityIndicatorViewController.present(fromViewController: shareVC!, canCancel: false, message: "vc_share_sending_message".localized()) { activityIndicator in
|
||||
GRDBStorage.shared
|
||||
.write { [weak self] db -> Promise<Void> in
|
||||
.writeAsync { [weak self] db -> Promise<Void> in
|
||||
guard let thread: SessionThread = try SessionThread.fetchOne(db, id: threadId) else {
|
||||
activityIndicator.dismiss { }
|
||||
self?.shareVC?.shareViewFailed(error: MessageSenderError.noThread)
|
||||
|
|
Loading…
Reference in New Issue