From 553a94286f0bb6bbcb37ccf17289a8ede669117a Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Jul 2018 18:40:35 -0600 Subject: [PATCH 01/10] update protobufs to sync group color --- .../protobuf/OWSSignalServiceProtos.proto | 1 + .../src/Messages/OWSSignalServiceProtos.pb.h | 10 ++++ .../src/Messages/OWSSignalServiceProtos.pb.m | 49 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/SignalServiceKit/protobuf/OWSSignalServiceProtos.proto b/SignalServiceKit/protobuf/OWSSignalServiceProtos.proto index 7a996aabf..de40d78ba 100644 --- a/SignalServiceKit/protobuf/OWSSignalServiceProtos.proto +++ b/SignalServiceKit/protobuf/OWSSignalServiceProtos.proto @@ -324,4 +324,5 @@ message GroupDetails { optional Avatar avatar = 4; optional bool active = 5 [default = true]; optional uint32 expireTimer = 6; + optional string color = 7; } diff --git a/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.h b/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.h index a93af9e92..bca3f4892 100644 --- a/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.h +++ b/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.h @@ -2840,15 +2840,18 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro #define GroupDetails_avatar @"avatar" #define GroupDetails_active @"active" #define GroupDetails_expireTimer @"expireTimer" +#define GroupDetails_color @"color" @interface OWSSignalServiceProtosGroupDetails : PBGeneratedMessage { @private BOOL hasActive_:1; BOOL hasName_:1; + BOOL hasColor_:1; BOOL hasAvatar_:1; BOOL hasId_:1; BOOL hasExpireTimer_:1; BOOL active_:1; NSString* name; + NSString* color; OWSSignalServiceProtosGroupDetailsAvatar* avatar; NSData* id; UInt32 expireTimer; @@ -2859,12 +2862,14 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro - (BOOL) hasAvatar; - (BOOL) hasActive; - (BOOL) hasExpireTimer; +- (BOOL) hasColor; @property (readonly, strong) NSData* id; @property (readonly, strong) NSString* name; @property (readonly, strong) NSArray * members; @property (readonly, strong) OWSSignalServiceProtosGroupDetailsAvatar* avatar; - (BOOL) active; @property (readonly) UInt32 expireTimer; +@property (readonly, strong) NSString* color; - (NSString*)membersAtIndex:(NSUInteger)index; + (instancetype) defaultInstance; @@ -2994,6 +2999,11 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro - (UInt32) expireTimer; - (OWSSignalServiceProtosGroupDetailsBuilder*) setExpireTimer:(UInt32) value; - (OWSSignalServiceProtosGroupDetailsBuilder*) clearExpireTimer; + +- (BOOL) hasColor; +- (NSString*) color; +- (OWSSignalServiceProtosGroupDetailsBuilder*) setColor:(NSString*) value; +- (OWSSignalServiceProtosGroupDetailsBuilder*) clearColor; @end diff --git a/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.m b/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.m index 269e1c511..c5eeef317 100644 --- a/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.m +++ b/SignalServiceKit/src/Messages/OWSSignalServiceProtos.pb.m @@ -12439,6 +12439,7 @@ static OWSSignalServiceProtosContactDetailsAvatar* defaultOWSSignalServiceProtos @property (strong) OWSSignalServiceProtosGroupDetailsAvatar* avatar; @property BOOL active; @property UInt32 expireTimer; +@property (strong) NSString* color; @end @implementation OWSSignalServiceProtosGroupDetails @@ -12485,6 +12486,13 @@ static OWSSignalServiceProtosContactDetailsAvatar* defaultOWSSignalServiceProtos hasExpireTimer_ = !!_value_; } @synthesize expireTimer; +- (BOOL) hasColor { + return !!hasColor_; +} +- (void) setHasColor:(BOOL) _value_ { + hasColor_ = !!_value_; +} +@synthesize color; - (instancetype) init { if ((self = [super init])) { self.id = [NSData data]; @@ -12492,6 +12500,7 @@ static OWSSignalServiceProtosContactDetailsAvatar* defaultOWSSignalServiceProtos self.avatar = [OWSSignalServiceProtosGroupDetailsAvatar defaultInstance]; self.active = YES; self.expireTimer = 0; + self.color = @""; } return self; } @@ -12535,6 +12544,9 @@ static OWSSignalServiceProtosGroupDetails* defaultOWSSignalServiceProtosGroupDet if (self.hasExpireTimer) { [output writeUInt32:6 value:self.expireTimer]; } + if (self.hasColor) { + [output writeString:7 value:self.color]; + } [self.unknownFields writeToCodedOutputStream:output]; } - (SInt32) serializedSize { @@ -12568,6 +12580,9 @@ static OWSSignalServiceProtosGroupDetails* defaultOWSSignalServiceProtosGroupDet if (self.hasExpireTimer) { size_ += computeUInt32Size(6, self.expireTimer); } + if (self.hasColor) { + size_ += computeStringSize(7, self.color); + } size_ += self.unknownFields.serializedSize; memoizedSerializedSize = size_; return size_; @@ -12624,6 +12639,9 @@ static OWSSignalServiceProtosGroupDetails* defaultOWSSignalServiceProtosGroupDet if (self.hasExpireTimer) { [output appendFormat:@"%@%@: %@\n", indent, @"expireTimer", [NSNumber numberWithInteger:self.expireTimer]]; } + if (self.hasColor) { + [output appendFormat:@"%@%@: %@\n", indent, @"color", self.color]; + } [self.unknownFields writeDescriptionTo:output withIndent:indent]; } - (void) storeInDictionary:(NSMutableDictionary *)dictionary { @@ -12645,6 +12663,9 @@ static OWSSignalServiceProtosGroupDetails* defaultOWSSignalServiceProtosGroupDet if (self.hasExpireTimer) { [dictionary setObject: [NSNumber numberWithInteger:self.expireTimer] forKey: @"expireTimer"]; } + if (self.hasColor) { + [dictionary setObject: self.color forKey: @"color"]; + } [self.unknownFields storeInDictionary:dictionary]; } - (BOOL) isEqual:(id)other { @@ -12667,6 +12688,8 @@ static OWSSignalServiceProtosGroupDetails* defaultOWSSignalServiceProtosGroupDet (!self.hasActive || self.active == otherMessage.active) && self.hasExpireTimer == otherMessage.hasExpireTimer && (!self.hasExpireTimer || self.expireTimer == otherMessage.expireTimer) && + self.hasColor == otherMessage.hasColor && + (!self.hasColor || [self.color isEqual:otherMessage.color]) && (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields])); } - (NSUInteger) hash { @@ -12689,6 +12712,9 @@ static OWSSignalServiceProtosGroupDetails* defaultOWSSignalServiceProtosGroupDet if (self.hasExpireTimer) { hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.expireTimer] hash]; } + if (self.hasColor) { + hashCode = hashCode * 31 + [self.color hash]; + } hashCode = hashCode * 31 + [self.unknownFields hash]; return hashCode; } @@ -13009,6 +13035,9 @@ static OWSSignalServiceProtosGroupDetailsAvatar* defaultOWSSignalServiceProtosGr if (other.hasExpireTimer) { [self setExpireTimer:other.expireTimer]; } + if (other.hasColor) { + [self setColor:other.color]; + } [self mergeUnknownFields:other.unknownFields]; return self; } @@ -13059,6 +13088,10 @@ static OWSSignalServiceProtosGroupDetailsAvatar* defaultOWSSignalServiceProtosGr [self setExpireTimer:[input readUInt32]]; break; } + case 58: { + [self setColor:[input readString]]; + break; + } } } } @@ -13177,6 +13210,22 @@ static OWSSignalServiceProtosGroupDetailsAvatar* defaultOWSSignalServiceProtosGr resultGroupDetails.expireTimer = 0; return self; } +- (BOOL) hasColor { + return resultGroupDetails.hasColor; +} +- (NSString*) color { + return resultGroupDetails.color; +} +- (OWSSignalServiceProtosGroupDetailsBuilder*) setColor:(NSString*) value { + resultGroupDetails.hasColor = YES; + resultGroupDetails.color = value; + return self; +} +- (OWSSignalServiceProtosGroupDetailsBuilder*) clearColor { + resultGroupDetails.hasColor = NO; + resultGroupDetails.color = @""; + return self; +} @end From 4d3d5d98e1c21c8fdc937a2ec5a4c38a164d28c6 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Jul 2018 19:05:00 -0600 Subject: [PATCH 02/10] Sync colors with contacts --- .../Jobs/MultiDeviceProfileKeyUpdateJob.swift | 24 ++++++++++++----- .../DebugUI/DebugUISyncMessages.m | 11 +++++--- SignalMessaging/contacts/OWSContactsSyncing.m | 26 ++++++++++++------- .../src/Devices/OWSContactsOutputStream.h | 3 ++- .../src/Devices/OWSContactsOutputStream.m | 2 ++ .../DeviceSyncing/OWSSyncContactsMessage.h | 2 +- .../DeviceSyncing/OWSSyncContactsMessage.m | 7 +++-- .../src/Messages/OWSMessageManager.m | 8 +++--- SignalServiceKit/src/Util/DataSource.h | 2 +- SignalServiceKit/src/Util/DataSource.m | 2 +- 10 files changed, 59 insertions(+), 28 deletions(-) diff --git a/Signal/src/Jobs/MultiDeviceProfileKeyUpdateJob.swift b/Signal/src/Jobs/MultiDeviceProfileKeyUpdateJob.swift index 00fbde15d..c8f3df93e 100644 --- a/Signal/src/Jobs/MultiDeviceProfileKeyUpdateJob.swift +++ b/Signal/src/Jobs/MultiDeviceProfileKeyUpdateJob.swift @@ -16,10 +16,13 @@ import SignalMessaging let TAG = "[MultiDeviceProfileKeyUpdateJob]" - let profileKey: OWSAES256Key - let identityManager: OWSIdentityManager - let messageSender: MessageSender - let profileManager: OWSProfileManager + private let profileKey: OWSAES256Key + private let identityManager: OWSIdentityManager + private let messageSender: MessageSender + private let profileManager: OWSProfileManager + private var editingDatabaseConnection: YapDatabaseConnection { + return OWSPrimaryStorage.shared().dbReadWriteConnection + } @objc public required init(profileKey: OWSAES256Key, identityManager: OWSIdentityManager, messageSender: MessageSender, profileManager: OWSProfileManager) { self.profileKey = profileKey @@ -45,8 +48,17 @@ import SignalMessaging identityManager: self.identityManager, profileManager: self.profileManager) - let dataSource = DataSourceValue.dataSource(withSyncMessage: syncContactsMessage.buildPlainTextAttachmentData()) - self.messageSender.enqueueTemporaryAttachment(dataSource, + var dataSource: DataSource? = nil + self.editingDatabaseConnection.readWrite { transaction in + dataSource = DataSourceValue.dataSource(withSyncMessageData: syncContactsMessage.buildPlainTextAttachmentData(with: transaction)) + } + + guard let attachmentDataSource = dataSource else { + owsFail("\(self.logTag) in \(#function) dataSource was unexpectedly nil") + return + } + + self.messageSender.enqueueTemporaryAttachment(attachmentDataSource, contentType: OWSMimeTypeApplicationOctetStream, in: syncContactsMessage, success: { diff --git a/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m index a9b1c94d9..3cf600cef 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUISyncMessages.m @@ -99,8 +99,13 @@ NS_ASSUME_NONNULL_BEGIN [[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts identityManager:self.identityManager profileManager:self.profileManager]; - DataSource *dataSource = - [DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]]; + __block DataSource *dataSource; + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + dataSource = [DataSourceValue + dataSourceWithSyncMessageData:[syncContactsMessage + buildPlainTextAttachmentDataWithTransaction:transaction]]; + }]; + [self.messageSender enqueueTemporaryAttachment:dataSource contentType:OWSMimeTypeApplicationOctetStream inMessage:syncContactsMessage @@ -118,7 +123,7 @@ NS_ASSUME_NONNULL_BEGIN __block DataSource *dataSource; [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { dataSource = [DataSourceValue - dataSourceWithSyncMessage:[syncGroupsMessage buildPlainTextAttachmentDataWithTransaction:transaction]]; + dataSourceWithSyncMessageData:[syncGroupsMessage buildPlainTextAttachmentDataWithTransaction:transaction]]; }]; [self.messageSender enqueueTemporaryAttachment:dataSource contentType:OWSMimeTypeApplicationOctetStream diff --git a/SignalMessaging/contacts/OWSContactsSyncing.m b/SignalMessaging/contacts/OWSContactsSyncing.m index 1919f2d9b..b1061fc74 100644 --- a/SignalMessaging/contacts/OWSContactsSyncing.m +++ b/SignalMessaging/contacts/OWSContactsSyncing.m @@ -95,6 +95,11 @@ NSString *const kOWSPrimaryStorageOWSContactsSyncingLastMessageKey [self sendSyncContactsMessageIfPossible]; } +- (YapDatabaseConnection *)editingDatabaseConnection +{ + return OWSPrimaryStorage.sharedManager.dbReadWriteConnection; +} + #pragma mark - Methods - (void)sendSyncContactsMessageIfNecessary @@ -119,11 +124,13 @@ NSString *const kOWSPrimaryStorageOWSContactsSyncingLastMessageKey identityManager:self.identityManager profileManager:self.profileManager]; - NSData *messageData = [syncContactsMessage buildPlainTextAttachmentData]; - - NSData *lastMessageData = - [OWSPrimaryStorage.dbReadConnection objectForKey:kOWSPrimaryStorageOWSContactsSyncingLastMessageKey - inCollection:kOWSPrimaryStorageOWSContactsSyncingCollection]; + __block NSData *messageData; + __block NSData *lastMessageData; + [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + messageData = [syncContactsMessage buildPlainTextAttachmentDataWithTransaction:transaction]; + lastMessageData = [transaction objectForKey:kOWSPrimaryStorageOWSContactsSyncingLastMessageKey + inCollection:kOWSPrimaryStorageOWSContactsSyncingCollection]; + }]; if (lastMessageData && [lastMessageData isEqual:messageData]) { // Ignore redundant contacts sync message. @@ -132,17 +139,16 @@ NSString *const kOWSPrimaryStorageOWSContactsSyncingLastMessageKey self.isRequestInFlight = YES; - DataSource *dataSource = - [DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]]; + DataSource *dataSource = [DataSourceValue dataSourceWithSyncMessageData:messageData]; [self.messageSender enqueueTemporaryAttachment:dataSource contentType:OWSMimeTypeApplicationOctetStream inMessage:syncContactsMessage success:^{ DDLogInfo(@"%@ Successfully sent contacts sync message.", self.logTag); - [OWSPrimaryStorage.dbReadWriteConnection setObject:messageData - forKey:kOWSPrimaryStorageOWSContactsSyncingLastMessageKey - inCollection:kOWSPrimaryStorageOWSContactsSyncingCollection]; + [self.editingDatabaseConnection setObject:messageData + forKey:kOWSPrimaryStorageOWSContactsSyncingLastMessageKey + inCollection:kOWSPrimaryStorageOWSContactsSyncingCollection]; dispatch_async(self.serialQueue, ^{ self.isRequestInFlight = NO; diff --git a/SignalServiceKit/src/Devices/OWSContactsOutputStream.h b/SignalServiceKit/src/Devices/OWSContactsOutputStream.h index 1f9734102..abbbda025 100644 --- a/SignalServiceKit/src/Devices/OWSContactsOutputStream.h +++ b/SignalServiceKit/src/Devices/OWSContactsOutputStream.h @@ -16,7 +16,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)writeSignalAccount:(SignalAccount *)signalAccount recipientIdentity:(nullable OWSRecipientIdentity *)recipientIdentity profileKeyData:(nullable NSData *)profileKeyData - contactsManager:(id)contactsManager; + contactsManager:(id)contactsManager + conversationColorName:(NSString *)conversationColorName; @end diff --git a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m index 6b66f838a..62d9af284 100644 --- a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m +++ b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m @@ -24,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN recipientIdentity:(nullable OWSRecipientIdentity *)recipientIdentity profileKeyData:(nullable NSData *)profileKeyData contactsManager:(id)contactsManager + conversationColorName:(NSString *)conversationColorName { OWSAssert(signalAccount); OWSAssert(signalAccount.contact); @@ -32,6 +33,7 @@ NS_ASSUME_NONNULL_BEGIN OWSSignalServiceProtosContactDetailsBuilder *contactBuilder = [OWSSignalServiceProtosContactDetailsBuilder new]; [contactBuilder setName:signalAccount.contact.fullName]; [contactBuilder setNumber:signalAccount.recipientId]; + [contactBuilder setColor:conversationColorName]; if (recipientIdentity != nil) { OWSSignalServiceProtosVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosVerifiedBuilder new]; diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h index fde635292..c1b8bc027 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h @@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; -- (NSData *)buildPlainTextAttachmentData; +- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; @end diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m index 0612d2bc1..288b29ee8 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m @@ -13,6 +13,7 @@ #import "SignalAccount.h" #import "TSAttachment.h" #import "TSAttachmentStream.h" +#import "TSContactThread.h" #import "TextSecureKitEnv.h" NS_ASSUME_NONNULL_BEGIN @@ -70,7 +71,7 @@ NS_ASSUME_NONNULL_BEGIN return syncMessageBuilder; } -- (NSData *)buildPlainTextAttachmentData +- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { id contactsManager = TextSecureKitEnv.sharedEnv.contactsManager; @@ -86,10 +87,12 @@ NS_ASSUME_NONNULL_BEGIN [self.identityManager recipientIdentityForRecipientId:signalAccount.recipientId]; NSData *_Nullable profileKeyData = [self.profileManager profileKeyDataForRecipientId:signalAccount.recipientId]; + TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:signalAccount.recipientId transaction:transaction]; [contactsOutputStream writeSignalAccount:signalAccount recipientIdentity:recipientIdentity profileKeyData:profileKeyData - contactsManager:contactsManager]; + contactsManager:contactsManager + conversationColorName:contactThread.conversationColorName]; } [contactsOutputStream flush]; diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 6bd4c892e..1cf944b0e 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -657,8 +657,9 @@ NS_ASSUME_NONNULL_BEGIN [[OWSSyncContactsMessage alloc] initWithSignalAccounts:self.contactsManager.signalAccounts identityManager:self.identityManager profileManager:self.profileManager]; - DataSource *dataSource = - [DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]]; + DataSource *dataSource = [DataSourceValue + dataSourceWithSyncMessageData:[syncContactsMessage + buildPlainTextAttachmentDataWithTransaction:transaction]]; [self.messageSender enqueueTemporaryAttachment:dataSource contentType:OWSMimeTypeApplicationOctetStream inMessage:syncContactsMessage @@ -673,7 +674,8 @@ NS_ASSUME_NONNULL_BEGIN } else if (syncMessage.request.type == OWSSignalServiceProtosSyncMessageRequestTypeGroups) { OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init]; DataSource *dataSource = [DataSourceValue - dataSourceWithSyncMessage:[syncGroupsMessage buildPlainTextAttachmentDataWithTransaction:transaction]]; + dataSourceWithSyncMessageData:[syncGroupsMessage + buildPlainTextAttachmentDataWithTransaction:transaction]]; [self.messageSender enqueueTemporaryAttachment:dataSource contentType:OWSMimeTypeApplicationOctetStream inMessage:syncGroupsMessage diff --git a/SignalServiceKit/src/Util/DataSource.h b/SignalServiceKit/src/Util/DataSource.h index 00b474ab3..c65d693c8 100755 --- a/SignalServiceKit/src/Util/DataSource.h +++ b/SignalServiceKit/src/Util/DataSource.h @@ -47,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable DataSource *)dataSourceWithOversizeText:(NSString *_Nullable)text; -+ (DataSource *)dataSourceWithSyncMessage:(NSData *)data; ++ (DataSource *)dataSourceWithSyncMessageData:(NSData *)data; + (DataSource *)emptyDataSource; diff --git a/SignalServiceKit/src/Util/DataSource.m b/SignalServiceKit/src/Util/DataSource.m index cca0a78ee..df21acf9f 100755 --- a/SignalServiceKit/src/Util/DataSource.m +++ b/SignalServiceKit/src/Util/DataSource.m @@ -158,7 +158,7 @@ NS_ASSUME_NONNULL_BEGIN return [self dataSourceWithData:data fileExtension:kOversizeTextAttachmentFileExtension]; } -+ (DataSource *)dataSourceWithSyncMessage:(NSData *)data ++ (DataSource *)dataSourceWithSyncMessageData:(NSData *)data { return [self dataSourceWithData:data fileExtension:kSyncMessageFileExtension]; } From d53f583e45c1f8fc694e035677b3f4747fde2990 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Jul 2018 19:47:16 -0600 Subject: [PATCH 03/10] sync colors with group --- SignalServiceKit/src/Devices/OWSGroupsOutputStream.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m b/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m index 7cfad1e3d..2dd42492d 100644 --- a/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m +++ b/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m @@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN [groupBuilder setId:group.groupId]; [groupBuilder setName:group.groupName]; [groupBuilder setMembersArray:group.groupMemberIds]; + [groupBuilder setColor:groupThread.conversationColorName]; NSData *avatarPng; if (group.groupImage) { From 61cb19ef6b912135308a680d565e8f56081c29ec Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Jul 2018 20:27:51 -0600 Subject: [PATCH 04/10] trigger sync when colors updates --- Signal.xcodeproj/project.pbxproj | 4 + ...nversationConfigurationSyncOperation.swift | 118 ++++++++++++++++++ .../OWSConversationSettingsViewController.m | 3 + 3 files changed, 125 insertions(+) create mode 100644 Signal/src/Jobs/ConversationConfigurationSyncOperation.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 3378c94a0..7dbd0234a 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -417,6 +417,7 @@ 4C20B2B720CA0034001BAC90 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542DF51208B82E9007B4E76 /* ThreadViewModel.swift */; }; 4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */; }; 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4AEC4420EC343B0020E72B /* DismissableTextField.swift */; }; + 4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC0B59B20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift */; }; 70377AAB1918450100CAF501 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70377AAA1918450100CAF501 /* MobileCoreServices.framework */; }; 768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; }; 76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; }; @@ -1077,6 +1078,7 @@ 4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = ""; }; 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearchViewController.swift; sourceTree = ""; }; 4C4AEC4420EC343B0020E72B /* DismissableTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissableTextField.swift; sourceTree = ""; }; + 4CC0B59B20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationConfigurationSyncOperation.swift; sourceTree = ""; }; 69349DE607F5BA6036C9AC60 /* Pods-SignalShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalShareExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SignalShareExtension/Pods-SignalShareExtension.debug.xcconfig"; sourceTree = ""; }; 70377AAA1918450100CAF501 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; 748A5CAEDD7C919FC64C6807 /* Pods_SignalTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SignalTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2016,6 +2018,7 @@ 45CD81EE1DC030E7004C9430 /* SyncPushTokensJob.swift */, 452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */, 451686AA1F520CDA00AC3D4B /* MultiDeviceProfileKeyUpdateJob.swift */, + 4CC0B59B20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift */, ); path = Jobs; sourceTree = ""; @@ -3198,6 +3201,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */, 3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */, 34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */, 452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */, diff --git a/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift b/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift new file mode 100644 index 000000000..eaf64e0da --- /dev/null +++ b/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift @@ -0,0 +1,118 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +import Foundation + +@objc +class ConversationConfigurationSyncOperation: OWSOperation { + + enum ColorSyncOperationError: Error { + case assertionError(description: String) + } + + var dbConnection: YapDatabaseConnection { + return OWSPrimaryStorage.shared().dbReadConnection + } + + var messageSender: MessageSender { + return Environment.current().messageSender + } + + var contactsManager: OWSContactsManager { + return Environment.current().contactsManager + } + + var profileManager: OWSProfileManager { + return OWSProfileManager.shared() + } + + var identityManager: OWSIdentityManager { + return OWSIdentityManager.shared() + } + + let thread: TSThread + + @objc + init(thread: TSThread) { + self.thread = thread + super.init() + } + + override 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) + } + + func sync(contactThread: TSContactThread) { + guard let signalAccount: SignalAccount = self.contactsManager.signalAccount(forRecipientId: contactThread.contactIdentifier()) else { + reportAssertionError(description: "unable to find signalAccount") + return + } + + let syncMessage: OWSSyncContactsMessage = OWSSyncContactsMessage(signalAccounts: [signalAccount], + identityManager: self.identityManager, + profileManager: self.profileManager) + + var dataSource: DataSource? = nil + self.dbConnection.readWrite { transaction in + let messageData: Data = syncMessage.buildPlainTextAttachmentData(with: transaction) + dataSource = DataSourceValue.dataSource(withSyncMessageData: messageData) + } + + guard let attachmentDataSource = dataSource else { + self.reportAssertionError(description: "unable to build attachment data source") + return + } + + self.messageSender.enqueueTemporaryAttachment(attachmentDataSource, + contentType: OWSMimeTypeApplicationOctetStream, + in: syncMessage, + success: { + self.reportSuccess() + }, + failure: { error in + self.reportError(error) + }) + } + + 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() + + var dataSource: DataSource? = nil + self.dbConnection.read { transaction in + let messageData: Data = syncMessage.buildPlainTextAttachmentData(with: transaction) + dataSource = DataSourceValue.dataSource(withSyncMessageData: messageData) + } + + guard let attachmentDataSource = dataSource else { + self.reportAssertionError(description: "unable to build attachment data source") + return + } + + self.messageSender.enqueueTemporaryAttachment(attachmentDataSource, + contentType: OWSMimeTypeApplicationOctetStream, + in: syncMessage, + success: { + self.reportSuccess() + }, + failure: { error in + self.reportError(error) + }) + } + +} diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index 60a993e25..b3edc0a07 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -1269,6 +1269,9 @@ const CGFloat kIconViewLength = 24; [self.contactsManager.avatarCache removeAllImages]; [self updateTableContents]; [self.conversationSettingsViewDelegate conversationColorWasUpdated]; + ConversationConfigurationSyncOperation *operation = [[ConversationConfigurationSyncOperation alloc] initWithThread:self.thread]; + + [self dismissViewControllerAnimated:YES completion:nil]; }]; From 8a43435dfc3153309f7b56669e2d513be0cfbfe9 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Jul 2018 20:28:17 -0600 Subject: [PATCH 05/10] avoid deadlock --- .../OWSConversationSettingsViewController.m | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index b3edc0a07..c5e1705cc 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -1265,16 +1265,18 @@ const CGFloat kIconViewLength = 24; DDLogDebug(@"%@ in %s picked color: %@", self.logTag, __PRETTY_FUNCTION__, colorName); [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.thread updateConversationColorName:colorName transaction:transaction]; - - [self.contactsManager.avatarCache removeAllImages]; - [self updateTableContents]; - [self.conversationSettingsViewDelegate conversationColorWasUpdated]; - ConversationConfigurationSyncOperation *operation = [[ConversationConfigurationSyncOperation alloc] initWithThread:self.thread]; - - - - [self dismissViewControllerAnimated:YES completion:nil]; }]; + + [self.contactsManager.avatarCache removeAllImages]; + [self updateTableContents]; + [self.conversationSettingsViewDelegate conversationColorWasUpdated]; + + ConversationConfigurationSyncOperation *operation = + [[ConversationConfigurationSyncOperation alloc] initWithThread:self.thread]; + OWSAssert(operation.isReady); + [operation start]; + + [self dismissViewControllerAnimated:YES completion:nil]; } - (void)colorPickerDidCancel:(ColorPickerViewController *)colorPicker From 3530bf4fe049d72836b787554def4d7be4b05958 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Jul 2018 20:31:26 -0600 Subject: [PATCH 06/10] sync configuration off main thread --- .../OWSConversationSettingsViewController.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index c5e1705cc..268fd8df7 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -1271,10 +1271,12 @@ const CGFloat kIconViewLength = 24; [self updateTableContents]; [self.conversationSettingsViewDelegate conversationColorWasUpdated]; - ConversationConfigurationSyncOperation *operation = - [[ConversationConfigurationSyncOperation alloc] initWithThread:self.thread]; - OWSAssert(operation.isReady); - [operation start]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + ConversationConfigurationSyncOperation *operation = + [[ConversationConfigurationSyncOperation alloc] initWithThread:self.thread]; + OWSAssert(operation.isReady); + [operation start]; + }); [self dismissViewControllerAnimated:YES completion:nil]; } From 66e726a1f16f5c1885158ac86ca40b153043c246 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 5 Jul 2018 13:55:28 -0600 Subject: [PATCH 07/10] DRY per CR --- ...nversationConfigurationSyncOperation.swift | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift b/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift index eaf64e0da..94bfd06f6 100644 --- a/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift +++ b/Signal/src/Jobs/ConversationConfigurationSyncOperation.swift @@ -11,35 +11,35 @@ class ConversationConfigurationSyncOperation: OWSOperation { case assertionError(description: String) } - var dbConnection: YapDatabaseConnection { + private var dbConnection: YapDatabaseConnection { return OWSPrimaryStorage.shared().dbReadConnection } - var messageSender: MessageSender { + private var messageSender: MessageSender { return Environment.current().messageSender } - var contactsManager: OWSContactsManager { + private var contactsManager: OWSContactsManager { return Environment.current().contactsManager } - var profileManager: OWSProfileManager { + private var profileManager: OWSProfileManager { return OWSProfileManager.shared() } - var identityManager: OWSIdentityManager { + private var identityManager: OWSIdentityManager { return OWSIdentityManager.shared() } - let thread: TSThread + private let thread: TSThread @objc - init(thread: TSThread) { + public init(thread: TSThread) { self.thread = thread super.init() } - override func run() { + override public func run() { if let contactThread = thread as? TSContactThread { sync(contactThread: contactThread) } else if let groupThread = thread as? TSGroupThread { @@ -54,7 +54,7 @@ class ConversationConfigurationSyncOperation: OWSOperation { self.reportError(error) } - func sync(contactThread: TSContactThread) { + private func sync(contactThread: TSContactThread) { guard let signalAccount: SignalAccount = self.contactsManager.signalAccount(forRecipientId: contactThread.contactIdentifier()) else { reportAssertionError(description: "unable to find signalAccount") return @@ -75,18 +75,10 @@ class ConversationConfigurationSyncOperation: OWSOperation { return } - self.messageSender.enqueueTemporaryAttachment(attachmentDataSource, - contentType: OWSMimeTypeApplicationOctetStream, - in: syncMessage, - success: { - self.reportSuccess() - }, - failure: { error in - self.reportError(error) - }) + self.sendConfiguration(attachmentDataSource: attachmentDataSource, syncMessage: syncMessage) } - func sync(groupThread: TSGroupThread) { + 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? @@ -104,6 +96,10 @@ class ConversationConfigurationSyncOperation: OWSOperation { return } + self.sendConfiguration(attachmentDataSource: attachmentDataSource, syncMessage: syncMessage) + } + + private func sendConfiguration(attachmentDataSource: DataSource, syncMessage: OWSOutgoingSyncMessage) { self.messageSender.enqueueTemporaryAttachment(attachmentDataSource, contentType: OWSMimeTypeApplicationOctetStream, in: syncMessage, From 92705490a07aa35311f4d0e68387f5465e915a82 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 5 Jul 2018 16:40:08 -0600 Subject: [PATCH 08/10] No write transaction needed for syncing colors // FREEBIE --- SignalMessaging/contacts/OWSContactsSyncing.m | 2 +- SignalServiceKit/src/Contacts/TSThread.m | 17 +++++++++++++++-- .../DeviceSyncing/OWSSyncContactsMessage.h | 2 +- .../DeviceSyncing/OWSSyncContactsMessage.m | 16 +++++++++++++--- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/SignalMessaging/contacts/OWSContactsSyncing.m b/SignalMessaging/contacts/OWSContactsSyncing.m index b1061fc74..f2285ab09 100644 --- a/SignalMessaging/contacts/OWSContactsSyncing.m +++ b/SignalMessaging/contacts/OWSContactsSyncing.m @@ -126,7 +126,7 @@ NSString *const kOWSPrimaryStorageOWSContactsSyncingLastMessageKey __block NSData *messageData; __block NSData *lastMessageData; - [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [self.editingDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { messageData = [syncContactsMessage buildPlainTextAttachmentDataWithTransaction:transaction]; lastMessageData = [transaction objectForKey:kOWSPrimaryStorageOWSContactsSyncingLastMessageKey inCollection:kOWSPrimaryStorageOWSContactsSyncingCollection]; diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index d0ef2ea89..06d172ad5 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -47,7 +47,14 @@ NS_ASSUME_NONNULL_BEGIN _lastMessageDate = nil; _creationDate = [NSDate date]; _messageDraft = nil; - _conversationColorName = [self.class randomConversationColorName]; + + NSString *_Nullable contactId = self.contactIdentifier; + if (contactId.length > 0) { + // To be consistent with colors synced to desktop + _conversationColorName = [self.class stableConversationColorNameForString:contactId]; + } else { + _conversationColorName = [self.class stableConversationColorNameForString:self.uniqueId]; + } } return self; @@ -61,7 +68,13 @@ NS_ASSUME_NONNULL_BEGIN } if (!_conversationColorName) { - _conversationColorName = [self.class stableConversationColorNameForString:self.uniqueId]; + NSString *_Nullable contactId = self.contactIdentifier; + if (contactId.length > 0) { + // To be consistent with colors synced to desktop + _conversationColorName = [self.class stableConversationColorNameForString:contactId]; + } else { + _conversationColorName = [self.class stableConversationColorNameForString:self.uniqueId]; + } } return self; diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h index c1b8bc027..e536c1685 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.h @@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; -- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; +- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadTransaction *)transaction; @end diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m index 288b29ee8..6dbf0cd49 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m @@ -71,7 +71,7 @@ NS_ASSUME_NONNULL_BEGIN return syncMessageBuilder; } -- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadTransaction *)transaction { id contactsManager = TextSecureKitEnv.sharedEnv.contactsManager; @@ -87,12 +87,22 @@ NS_ASSUME_NONNULL_BEGIN [self.identityManager recipientIdentityForRecipientId:signalAccount.recipientId]; NSData *_Nullable profileKeyData = [self.profileManager profileKeyDataForRecipientId:signalAccount.recipientId]; - TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:signalAccount.recipientId transaction:transaction]; + + NSString *conversationColorName = (NSString *)^() { + TSContactThread *_Nullable contactThread = + [TSContactThread fetchObjectWithUniqueID:signalAccount.recipientId transaction:transaction]; + if (contactThread) { + return contactThread.conversationColorName; + } else { + return [TSThread stableConversationColorNameForString:signalAccount.recipientId]; + } + }(); + [contactsOutputStream writeSignalAccount:signalAccount recipientIdentity:recipientIdentity profileKeyData:profileKeyData contactsManager:contactsManager - conversationColorName:contactThread.conversationColorName]; + conversationColorName:conversationColorName]; } [contactsOutputStream flush]; From a66c88e3cf79dc29e8f316339a2a274a8060c392 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 5 Jul 2018 16:56:14 -0600 Subject: [PATCH 09/10] Fix getter for contact threads, remove sneaky read transaction for DM config. --- SignalServiceKit/src/Contacts/TSThread.m | 2 +- .../src/Contacts/Threads/TSContactThread.h | 2 +- .../src/Contacts/Threads/TSContactThread.m | 12 ++-------- .../src/Devices/OWSContactsOutputStream.h | 5 ++++- .../src/Devices/OWSContactsOutputStream.m | 11 +++------- .../DeviceSyncing/OWSSyncContactsMessage.m | 22 ++++++++++--------- 6 files changed, 23 insertions(+), 31 deletions(-) diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index 06d172ad5..a8504165c 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -67,7 +67,7 @@ NS_ASSUME_NONNULL_BEGIN return self; } - if (!_conversationColorName) { + if (_conversationColorName.length == 0) { NSString *_Nullable contactId = self.contactIdentifier; if (contactId.length > 0) { // To be consistent with colors synced to desktop diff --git a/SignalServiceKit/src/Contacts/Threads/TSContactThread.h b/SignalServiceKit/src/Contacts/Threads/TSContactThread.h index e8c94e1c1..0c28b19b2 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSContactThread.h +++ b/SignalServiceKit/src/Contacts/Threads/TSContactThread.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN relay:(nullable NSString *)relay; // Unlike getOrCreateThreadWithContactId, this will _NOT_ create a thread if one does not already exist. -+ (nullable instancetype)getThreadWithContactId:(NSString *)contactId; ++ (nullable instancetype)getThreadWithContactId:(NSString *)contactId transaction:(YapDatabaseReadTransaction *)transaction; - (NSString *)contactIdentifier; diff --git a/SignalServiceKit/src/Contacts/Threads/TSContactThread.m b/SignalServiceKit/src/Contacts/Threads/TSContactThread.m index 2570a0c4e..1fbf3dc36 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSContactThread.m +++ b/SignalServiceKit/src/Contacts/Threads/TSContactThread.m @@ -83,17 +83,9 @@ NS_ASSUME_NONNULL_BEGIN return thread; } -+ (nullable instancetype)getThreadWithContactId:(NSString *)contactId ++ (nullable instancetype)getThreadWithContactId:(NSString *)contactId transaction:(YapDatabaseReadTransaction *)transaction; { - OWSAssert(contactId.length > 0); - - __block TSContactThread *_Nullable thread; - [[self dbReadWriteConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) { - thread = - [TSContactThread fetchObjectWithUniqueID:[self threadIdFromContactId:contactId] transaction:transaction]; - }]; - - return thread; + return [TSContactThread fetchObjectWithUniqueID:[self threadIdFromContactId:contactId] transaction:transaction]; } - (NSString *)contactIdentifier { diff --git a/SignalServiceKit/src/Devices/OWSContactsOutputStream.h b/SignalServiceKit/src/Devices/OWSContactsOutputStream.h index abbbda025..46fe918fe 100644 --- a/SignalServiceKit/src/Devices/OWSContactsOutputStream.h +++ b/SignalServiceKit/src/Devices/OWSContactsOutputStream.h @@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN +@class OWSDisappearingMessagesConfiguration; @class OWSRecipientIdentity; @class SignalAccount; @@ -17,7 +18,9 @@ NS_ASSUME_NONNULL_BEGIN recipientIdentity:(nullable OWSRecipientIdentity *)recipientIdentity profileKeyData:(nullable NSData *)profileKeyData contactsManager:(id)contactsManager - conversationColorName:(NSString *)conversationColorName; + conversationColorName:(NSString *)conversationColorName +disappearingMessagesConfiguration:(nullable OWSDisappearingMessagesConfiguration *)disappearingMessagesConfiguration; + @end diff --git a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m index 62d9af284..87cda89df 100644 --- a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m +++ b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m @@ -25,6 +25,7 @@ NS_ASSUME_NONNULL_BEGIN profileKeyData:(nullable NSData *)profileKeyData contactsManager:(id)contactsManager conversationColorName:(NSString *)conversationColorName +disappearingMessagesConfiguration:(nullable OWSDisappearingMessagesConfiguration *)disappearingMessagesConfiguration { OWSAssert(signalAccount); OWSAssert(signalAccount.contact); @@ -67,14 +68,8 @@ NS_ASSUME_NONNULL_BEGIN // legacy client "not specifying". [contactBuilder setExpireTimer:0]; - TSContactThread *_Nullable contactThread = [TSContactThread getThreadWithContactId:signalAccount.recipientId]; - if (contactThread) { - OWSDisappearingMessagesConfiguration *_Nullable disappearingMessagesConfiguration = - [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:contactThread.uniqueId]; - - if (disappearingMessagesConfiguration && disappearingMessagesConfiguration.isEnabled) { - [contactBuilder setExpireTimer:disappearingMessagesConfiguration.durationSeconds]; - } + if (disappearingMessagesConfiguration && disappearingMessagesConfiguration.isEnabled) { + [contactBuilder setExpireTimer:disappearingMessagesConfiguration.durationSeconds]; } if ([OWSBlockingManager.sharedManager isRecipientIdBlocked:signalAccount.recipientId]) { diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m index 6dbf0cd49..3b0a3d948 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.m @@ -88,21 +88,23 @@ NS_ASSUME_NONNULL_BEGIN NSData *_Nullable profileKeyData = [self.profileManager profileKeyDataForRecipientId:signalAccount.recipientId]; - NSString *conversationColorName = (NSString *)^() { - TSContactThread *_Nullable contactThread = - [TSContactThread fetchObjectWithUniqueID:signalAccount.recipientId transaction:transaction]; - if (contactThread) { - return contactThread.conversationColorName; - } else { - return [TSThread stableConversationColorNameForString:signalAccount.recipientId]; - } - }(); + OWSDisappearingMessagesConfiguration *_Nullable disappearingMessagesConfiguration; + NSString *conversationColorName; + + TSContactThread *_Nullable contactThread = [TSContactThread getThreadWithContactId:signalAccount.recipientId transaction:transaction]; + if (contactThread) { + conversationColorName = contactThread.conversationColorName; + disappearingMessagesConfiguration = [contactThread disappearingMessagesConfigurationWithTransaction:transaction]; + } else { + conversationColorName = [TSThread stableConversationColorNameForString:signalAccount.recipientId]; + } [contactsOutputStream writeSignalAccount:signalAccount recipientIdentity:recipientIdentity profileKeyData:profileKeyData contactsManager:contactsManager - conversationColorName:conversationColorName]; + conversationColorName:conversationColorName + disappearingMessagesConfiguration:disappearingMessagesConfiguration]; } [contactsOutputStream flush]; From f0175c0b6fd848ec707935e24e97a2654a961ac3 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 10 Jul 2018 11:55:14 -0600 Subject: [PATCH 10/10] feature gate color syncing // FREEBIE --- .../ThreadSettings/OWSConversationSettingsViewController.m | 4 +--- SignalServiceKit/src/Devices/OWSContactsOutputStream.m | 2 ++ SignalServiceKit/src/Devices/OWSGroupsOutputStream.m | 2 ++ SignalServiceKit/src/TSConstants.h | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m index 268fd8df7..807a35df6 100644 --- a/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m +++ b/Signal/src/ViewControllers/ThreadSettings/OWSConversationSettingsViewController.m @@ -281,9 +281,7 @@ const CGFloat kIconViewLength = 24; [weakSelf showMediaGallery]; }]]; - -//#define SHOW_CONVERSATION_COLORS_UI -#ifdef SHOW_CONVERSATION_COLORS_UI +#ifdef CONVERSATION_COLORS_ENABLED [mainSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ NSString *colorName = self.thread.conversationColorName; diff --git a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m index 87cda89df..fdcb5a8c2 100644 --- a/SignalServiceKit/src/Devices/OWSContactsOutputStream.m +++ b/SignalServiceKit/src/Devices/OWSContactsOutputStream.m @@ -34,7 +34,9 @@ disappearingMessagesConfiguration:(nullable OWSDisappearingMessagesConfiguration OWSSignalServiceProtosContactDetailsBuilder *contactBuilder = [OWSSignalServiceProtosContactDetailsBuilder new]; [contactBuilder setName:signalAccount.contact.fullName]; [contactBuilder setNumber:signalAccount.recipientId]; +#ifdef CONVERSATION_COLORS_ENABLED [contactBuilder setColor:conversationColorName]; +#endif if (recipientIdentity != nil) { OWSSignalServiceProtosVerifiedBuilder *verifiedBuilder = [OWSSignalServiceProtosVerifiedBuilder new]; diff --git a/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m b/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m index 2dd42492d..99051ab2a 100644 --- a/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m +++ b/SignalServiceKit/src/Devices/OWSGroupsOutputStream.m @@ -26,7 +26,9 @@ NS_ASSUME_NONNULL_BEGIN [groupBuilder setId:group.groupId]; [groupBuilder setName:group.groupName]; [groupBuilder setMembersArray:group.groupMemberIds]; +#ifdef CONVERSATION_COLORS_ENABLED [groupBuilder setColor:groupThread.conversationColorName]; +#endif NSData *avatarPng; if (group.groupImage) { diff --git a/SignalServiceKit/src/TSConstants.h b/SignalServiceKit/src/TSConstants.h index bfde2bb48..2ab6e363f 100644 --- a/SignalServiceKit/src/TSConstants.h +++ b/SignalServiceKit/src/TSConstants.h @@ -17,6 +17,8 @@ typedef NS_ENUM(NSInteger, TSWhisperMessageType) { #define textSecureHTTPTimeOut 10 +//#define CONVERSATION_COLORS_ENABLED + #define kLegalTermsUrlString @"https://signal.org/legal/" #define SHOW_LEGAL_TERMS_LINK