// // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // import Foundation @objc class ConversationConfigurationSyncOperation: OWSOperation { enum ColorSyncOperationError: Error { case assertionError(description: String) } private var dbConnection: YapDatabaseConnection { return OWSPrimaryStorage.shared().dbReadConnection } private var messageSenderJobQueue: MessageSenderJobQueue { return SSKEnvironment.shared.messageSenderJobQueue } private var contactsManager: OWSContactsManager { return Environment.shared.contactsManager } private var syncManager: OWSSyncManagerProtocol { return SSKEnvironment.shared.syncManager } private let thread: TSThread @objc public init(thread: TSThread) { self.thread = thread super.init() } override public func run() { if let contactThread = thread as? TSContactThread { sync(contactThread: contactThread) } else if let groupThread = thread as? TSGroupThread { sync(groupThread: groupThread) } else { self.reportAssertionError(description: "unknown thread type") } } private func reportAssertionError(description: String) { let error = ColorSyncOperationError.assertionError(description: description) self.reportError(error) } private func sync(contactThread: TSContactThread) { guard let signalAccount: SignalAccount = self.contactsManager.fetchSignalAccount(forRecipientId: contactThread.contactIdentifier()) else { reportAssertionError(description: "unable to find signalAccount") return } syncManager.syncContacts(for: [signalAccount]).retainUntilComplete() } private func sync(groupThread: TSGroupThread) { // TODO sync only the affected group // The current implementation works, but seems wasteful. // Does desktop handle single group sync correctly? // What does Android do? let syncMessage: OWSSyncGroupsMessage = OWSSyncGroupsMessage(groupThread: groupThread) var dataSource: DataSource? self.dbConnection.read { transaction in guard let messageData: Data = syncMessage.buildPlainTextAttachmentData(with: transaction) else { owsFailDebug("could not serialize sync groups data") return } dataSource = DataSourceValue.dataSource(withSyncMessageData: messageData) } guard let attachmentDataSource = dataSource else { self.reportAssertionError(description: "unable to build attachment data source") return } self.sendConfiguration(attachmentDataSource: attachmentDataSource, syncMessage: syncMessage) } private func sendConfiguration(attachmentDataSource: DataSource, syncMessage: OWSOutgoingSyncMessage) { self.messageSenderJobQueue.add(mediaMessage: syncMessage, dataSource: attachmentDataSource, contentType: OWSMimeTypeApplicationOctetStream, sourceFilename: nil, caption: nil, albumMessageId: nil, isTemporaryAttachment: true) self.reportSuccess() } }