diff --git a/SignalMessaging/contacts/OWSSyncManager.m b/SignalMessaging/contacts/OWSSyncManager.m index c101ad773..ef9f5f31d 100644 --- a/SignalMessaging/contacts/OWSSyncManager.m +++ b/SignalMessaging/contacts/OWSSyncManager.m @@ -228,12 +228,9 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag if (!self.tsAccountManager.isRegisteredAndReady) { return; } - - NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults; - BOOL hasLaunchedOnce = [userDefaults boolForKey:@"hasLaunchedOnce"]; - if (hasLaunchedOnce) { // FIXME: Quick and dirty workaround to not do this on initial launch - [self sendConfigurationSyncMessage_AppReady]; - } + + if ([LKSyncMessagesProtocol shouldSkipConfigurationSyncMessage]) { return; } + [self sendConfigurationSyncMessage_AppReady]; }]; } @@ -273,38 +270,13 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag - (AnyPromise *)syncContact:(NSString *)hexEncodedPubKey transaction:(YapDatabaseReadTransaction *)transaction { - TSContactThread *thread = [TSContactThread getThreadWithContactId:hexEncodedPubKey transaction:transaction]; - if (thread != nil && thread.isContactFriend) { - return [self syncContactsForSignalAccounts:@[[[SignalAccount alloc] initWithRecipientId:hexEncodedPubKey]]]; - } + [LKSyncMessagesProtocol syncContactWithHexEncodedPublicKey:hexEncodedPubKey in:transaction]; return [AnyPromise promiseWithValue:@1]; } - (AnyPromise *)syncAllContacts { - NSMutableArray *friends = @[].mutableCopy; - NSMutableArray *promises = @[].mutableCopy; - [TSContactThread enumerateCollectionObjectsUsingBlock:^(TSContactThread *thread, BOOL *stop) { - NSString *hexEncodedPublicKey = thread.contactIdentifier; - if (hexEncodedPublicKey != nil && thread.isContactFriend && thread.shouldThreadBeVisible && !thread.isForceHidden) { - [friends addObject:[[SignalAccount alloc] initWithRecipientId:hexEncodedPublicKey]]; - } - }]; - [friends addObject:[[SignalAccount alloc] initWithRecipientId:self.tsAccountManager.localNumber]]; - NSMutableArray *signalAccounts = @[].mutableCopy; - for (SignalAccount *contact in friends) { - [signalAccounts addObject:contact]; - if (signalAccounts.count >= 3) { - [promises addObject:[self syncContactsForSignalAccounts:[signalAccounts copy]]]; - [signalAccounts removeAllObjects]; - } - } - if (signalAccounts.count > 0) { - [promises addObject:[self syncContactsForSignalAccounts:signalAccounts]]; - } - AnyPromise *promise = PMKJoin(promises); - [promise retainUntilComplete]; - return promise; + return [LKSyncMessagesProtocol syncAllContacts]; } - (AnyPromise *)syncContactsForSignalAccounts:(NSArray *)signalAccounts @@ -327,26 +299,7 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag - (AnyPromise *)syncAllGroups { - NSMutableArray *groupThreads = @[].mutableCopy; - NSMutableArray *promises = @[].mutableCopy; - [TSGroupThread enumerateCollectionObjectsUsingBlock:^(id obj, BOOL *stop) { - if (![obj isKindOfClass:[TSGroupThread class]]) { - if (![obj isKindOfClass:[TSContactThread class]]) { // FIXME: Isn't this redundant? - OWSLogWarn(@"Ignoring non-group thread in thread collection: %@.", obj); - } - return; - } - TSGroupThread *thread = (TSGroupThread *)obj; - if (thread.groupModel.groupType == closedGroup && thread.shouldThreadBeVisible && !thread.isForceHidden) { - [groupThreads addObject:thread]; - } - }]; - for (TSGroupThread *groupThread in groupThreads) { - [promises addObject:[self syncGroupForThread:groupThread]]; - } - AnyPromise *promise = PMKJoin(promises); - [promise retainUntilComplete]; - return promise; + return [LKSyncMessagesProtocol syncAllClosedGroups]; } - (AnyPromise *)syncGroupForThread:(TSGroupThread *)thread @@ -369,20 +322,7 @@ NSString *const kSyncManagerLastContactSyncKey = @"kTSStorageManagerOWSSyncManag - (AnyPromise *)syncAllOpenGroups { - LKSyncOpenGroupsMessage *syncOpenGroupsMessage = [[LKSyncOpenGroupsMessage alloc] init]; - AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { - [self.messageSender sendMessage:syncOpenGroupsMessage - success:^{ - OWSLogInfo(@"Successfully sent open group sync message."); - resolve(@(1)); - } - failure:^(NSError *error) { - OWSLogError(@"Failed to send open group sync message due to error: %@.", error); - resolve(error); - }]; - }]; - [promise retainUntilComplete]; - return promise; + return [LKSyncMessagesProtocol syncAllOpenGroups]; } @end diff --git a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift index bb523c8da..a0056cce2 100644 --- a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift @@ -17,6 +17,76 @@ public final class SyncMessagesProtocol : NSObject { internal static var storage: OWSPrimaryStorage { OWSPrimaryStorage.shared() } + // MARK: - Sending + @objc(shouldSkipConfigurationSyncMessage) + public static func shouldSkipConfigurationSyncMessage() -> Bool { + return !UserDefaults.standard[.hasLaunchedOnce] + } + + @objc(syncContactWithHexEncodedPublicKey:in:) + public static func syncContact(_ hexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) { + if let thread = TSContactThread.getWithContactId(hexEncodedPublicKey, transaction: transaction) { // TODO: Should this be getOrCreate? + let syncManager = SSKEnvironment.shared.syncManager + syncManager.syncContacts(for: [ SignalAccount(recipientId: hexEncodedPublicKey) ]) + } + } + + @objc(syncAllContacts) + public static func objc_syncAllContacts() -> AnyPromise { + return AnyPromise.from(syncAllContacts()) + } + + public static func syncAllContacts() -> Promise { + var friends: [SignalAccount] = [] + TSContactThread.enumerateCollectionObjects { object, _ in + guard let thread = object as? TSContactThread else { return } + let hexEncodedPublicKey = thread.contactIdentifier() + guard thread.isContactFriend && thread.shouldThreadBeVisible && !thread.isForceHidden else { return } + friends.append(SignalAccount(recipientId: hexEncodedPublicKey)) + } + friends.append(SignalAccount(recipientId: getUserHexEncodedPublicKey())) // TODO: We sure about this? + let syncManager = SSKEnvironment.shared.syncManager + let promises = friends.chunked(by: 3).map { friends -> Promise in + return Promise(syncManager.syncContacts(for: friends)).map { _ in } + } + return when(fulfilled: promises) + } + + @objc(syncAllClosedGroups) + public static func objc_syncAllClosedGroups() -> AnyPromise { + return AnyPromise.from(syncAllClosedGroups()) + } + + public static func syncAllClosedGroups() -> Promise { + var groups: [TSGroupThread] = [] + TSGroupThread.enumerateCollectionObjects { object, _ in + guard let group = object as? TSGroupThread, group.groupModel.groupType == .closedGroup, group.shouldThreadBeVisible, !group.isForceHidden else { return } + groups.append(group) + } + let syncManager = SSKEnvironment.shared.syncManager + let promises = groups.map { group -> Promise in + return Promise(syncManager.syncGroup(for: group)).map { _ in } + } + return when(fulfilled: promises) + } + + @objc(syncAllOpenGroups) + public static func objc_syncAllOpenGroups() -> AnyPromise { + return AnyPromise.from(syncAllOpenGroups()) + } + + public static func syncAllOpenGroups() -> Promise { + let openGroupSyncMessage = LKSyncOpenGroupsMessage() + let (promise, seal) = Promise.pending() + let messageSender = SSKEnvironment.shared.messageSender + messageSender.send(openGroupSyncMessage, success: { + seal.fulfill(()) + }) { error in + seal.reject(error) + } + return promise + } + // MARK: - Receiving @objc(isValidSyncMessage:in:) public static func isValidSyncMessage(_ envelope: SSKProtoEnvelope, in transaction: YapDatabaseReadTransaction) -> Bool { diff --git a/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift b/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift index 3d5430bc7..2a4b7874b 100644 --- a/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift +++ b/SignalServiceKit/src/TestUtils/OWSMockSyncManager.swift @@ -20,7 +20,12 @@ public class OWSMockSyncManager: NSObject, OWSSyncManagerProtocol { return AnyPromise() } - + + public func syncGroup(for thread: TSGroupThread) -> AnyPromise { + Logger.info("") + + return AnyPromise() + } @objc public func sendConfigurationSyncMessage() { Logger.info("") diff --git a/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h b/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h index 952e01ba2..ae6d68a6a 100644 --- a/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h +++ b/SignalServiceKit/src/Util/OWSSyncManagerProtocol.h @@ -7,6 +7,7 @@ NS_ASSUME_NONNULL_BEGIN @class AnyPromise; @class SignalAccount; @class YapDatabaseReadTransaction; +@class TSGroupThread; @protocol OWSSyncManagerProtocol @@ -22,6 +23,8 @@ NS_ASSUME_NONNULL_BEGIN - (AnyPromise *)syncAllGroups __attribute__((warn_unused_result)); +- (AnyPromise *)syncGroupForThread:(TSGroupThread *)thread; + - (AnyPromise *)syncAllOpenGroups __attribute__((warn_unused_result)); @end