Nothing outside of TSThread should know about legacy colors

pull/1/head
Michael Kirk 7 years ago
parent b612533d46
commit d59e21e7f0

@ -76,9 +76,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (class, readonly, nonatomic) NSArray<NSString *> *conversationColorNames; @property (class, readonly, nonatomic) NSArray<NSString *> *conversationColorNames;
+ (NSString *)defaultConversationColorName;
+ (OWSConversationColor *)defaultConversationColor;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -5,6 +5,7 @@
#import "OWSConversationColor.h" #import "OWSConversationColor.h"
#import "Theme.h" #import "Theme.h"
#import "UIColor+OWS.h" #import "UIColor+OWS.h"
#import <SignalServiceKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -314,56 +315,29 @@ NS_ASSUME_NONNULL_BEGIN
return colorMap; return colorMap;
} }
+ (NSDictionary<NSString *, NSString *> *)ows_legacyConversationColorMap
{
static NSDictionary<NSString *, NSString *> *colorMap;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
colorMap = @{
@"red" : @"crimson",
@"deep_orange" : @"crimson",
@"orange" : @"vermilion",
@"amber" : @"vermilion",
@"brown" : @"burlap",
@"yellow" : @"burlap",
@"pink" : @"plum",
@"purple" : @"violet",
@"deep_purple" : @"violet",
@"indigo" : @"indigo",
@"blue" : @"blue",
@"light_blue" : @"blue",
@"cyan" : @"teal",
@"teal" : @"teal",
@"green" : @"forest",
@"light_green" : @"wintergreen",
@"lime" : @"wintergreen",
@"blue_grey" : @"taupe",
@"grey" : @"steel",
};
});
return colorMap;
}
+ (NSArray<NSString *> *)conversationColorNames + (NSArray<NSString *> *)conversationColorNames
{ {
NSMutableArray<NSString *> *names = [NSMutableArray new]; NSMutableArray<NSString *> *names = [NSMutableArray new];
for (OWSConversationColor *conversationColor in self.allConversationColors) { for (OWSConversationColor *conversationColor in self.allConversationColors) {
[names addObject:conversationColor.name]; [names addObject:conversationColor.name];
} }
#ifdef DEBUG
NSSet<NSString *> *colorNameSet = [NSSet setWithArray:names];
// These constants are duplicated in two places. So this canary exists to make sure they stay in sync.
NSSet<NSString *> *threadColorNameSet = [NSSet setWithArray:TSThread.conversationColorNames];
OWSAssertDebug([colorNameSet isEqual:threadColorNameSet]);
#endif
return [names copy]; return [names copy];
} }
+ (nullable OWSConversationColor *)conversationColorForColorName:(NSString *)conversationColorName + (nullable OWSConversationColor *)conversationColorForColorName:(NSString *)conversationColorName
{ {
NSString *_Nullable mappedColorName = self.ows_legacyConversationColorMap[conversationColorName.lowercaseString]; OWSConversationColor *_Nullable result = self.conversationColorMap[conversationColorName];
if (mappedColorName) {
conversationColorName = mappedColorName; // Any mapping to colorNames should be done in TSThread before this method is called.
} else { OWSAssertDebug(result != nil);
OWSAssertDebug(self.conversationColorMap[conversationColorName] != nil);
}
return self.conversationColorMap[conversationColorName]; return result;
} }
+ (OWSConversationColor *)conversationColorOrDefaultForColorName:(NSString *)conversationColorName + (OWSConversationColor *)conversationColorOrDefaultForColorName:(NSString *)conversationColorName
@ -375,16 +349,9 @@ NS_ASSUME_NONNULL_BEGIN
return [self defaultConversationColor]; return [self defaultConversationColor];
} }
+ (NSString *)defaultConversationColorName
{
NSString *conversationColorName = @"steel";
OWSAssert([self.conversationColorNames containsObject:conversationColorName]);
return conversationColorName;
}
+ (OWSConversationColor *)defaultConversationColor + (OWSConversationColor *)defaultConversationColor
{ {
return [self conversationColorForColorName:self.defaultConversationColorName]; return [self conversationColorForColorName:kTSThread_DefaultConversationColorName];
} }
@end @end

@ -76,9 +76,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssertDebug(localNumber.length > 0); OWSAssertDebug(localNumber.length > 0);
OWSAssertDebug(diameter > 0); OWSAssertDebug(diameter > 0);
NSString *colorName = [OWSConversationColor defaultConversationColorName]; return [self initWithSignalId:localNumber colorName:kTSThread_DefaultConversationColorName diameter:diameter];
return [self initWithSignalId:localNumber colorName:colorName diameter:diameter];
} }
#pragma mark - Dependencies #pragma mark - Dependencies

@ -10,10 +10,11 @@ NS_ASSUME_NONNULL_BEGIN
@class TSInteraction; @class TSInteraction;
@class TSInvalidIdentityKeyReceivingErrorMessage; @class TSInvalidIdentityKeyReceivingErrorMessage;
extern NSString *const kTSThread_DefaultConversationColorName;
/** /**
* TSThread is the superclass of TSContactThread and TSGroupThread * TSThread is the superclass of TSContactThread and TSGroupThread
*/ */
@interface TSThread : TSYapDatabaseObject @interface TSThread : TSYapDatabaseObject
// YES IFF this thread has ever had a message. // YES IFF this thread has ever had a message.
@ -37,6 +38,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)updateConversationColorName:(NSString *)colorName transaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)updateConversationColorName:(NSString *)colorName transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (NSString *)stableColorNameForNewConversationWithString:(NSString *)colorSeed; + (NSString *)stableColorNameForNewConversationWithString:(NSString *)colorSeed;
@property (class, nonatomic, readonly) NSArray<NSString *> *conversationColorNames;
/** /**
* @returns * @returns

@ -19,6 +19,8 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
NSString *const kTSThread_DefaultConversationColorName = @"steel";
@interface TSThread () @interface TSThread ()
@property (nonatomic) NSDate *creationDate; @property (nonatomic) NSDate *creationDate;
@ -69,15 +71,28 @@ NS_ASSUME_NONNULL_BEGIN
} }
if (_conversationColorName.length == 0) { if (_conversationColorName.length == 0) {
NSString *_Nullable contactId = self.contactIdentifier; NSString *_Nullable colorSeed = self.contactIdentifier;
if (contactId.length > 0) { if (colorSeed.length > 0) {
// To be consistent with colors synced to desktop // group threads
_conversationColorName = [self.class stableColorNameForLegacyConversationWithString:contactId]; colorSeed = self.uniqueId;
}
// To be consistent with colors synced to desktop
NSString *colorName = [self.class stableColorNameForLegacyConversationWithString:colorSeed];
OWSAssertDebug(colorName);
_conversationColorName = colorName;
} else if (![[[self class] conversationColorNames] containsObject:_conversationColorName]) {
// If we'd persisted a non-mapped color name
NSString *_Nullable mappedColorName = self.class.legacyConversationColorMap[_conversationColorName];
if (mappedColorName) {
_conversationColorName = mappedColorName;
} else { } else {
_conversationColorName = [self.class stableColorNameForLegacyConversationWithString:self.uniqueId]; OWSFailDebug(@"failure: unexpected unmappable conversationColorName: %@", _conversationColorName);
_conversationColorName = kTSThread_DefaultConversationColorName;
} }
} }
return self; return self;
} }
@ -459,6 +474,11 @@ NS_ASSUME_NONNULL_BEGIN
]; ];
} }
+ (NSArray<NSString *> *)conversationColorNames
{
return [self.colorNamesForNewConversation arrayByAddingObject:kTSThread_DefaultConversationColorName];
}
+ (NSString *)stableConversationColorNameForString:(NSString *)colorSeed colorNames:(NSArray<NSString *> *)colorNames + (NSString *)stableConversationColorNameForString:(NSString *)colorSeed colorNames:(NSArray<NSString *> *)colorNames
{ {
NSData *contactData = [colorSeed dataUsingEncoding:NSUTF8StringEncoding]; NSData *contactData = [colorSeed dataUsingEncoding:NSUTF8StringEncoding];
@ -481,11 +501,20 @@ NS_ASSUME_NONNULL_BEGIN
return [self stableConversationColorNameForString:colorSeed colorNames:self.colorNamesForNewConversation]; return [self stableConversationColorNameForString:colorSeed colorNames:self.colorNamesForNewConversation];
} }
// After introducing new conversation colors, we want to try to maintain as close // After introducing new conversation colors, we want to try to maintain as close as possible to the old color for an
// as possible to the old color for an existing thread. // existing thread.
+ (NSString *)stableColorNameForLegacyConversationWithString:(NSString *)colorSeed + (NSString *)stableColorNameForLegacyConversationWithString:(NSString *)colorSeed
{ {
return [self stableConversationColorNameForString:colorSeed colorNames:self.legacyConversationColorNames]; NSString *legacyColorName =
[self stableConversationColorNameForString:colorSeed colorNames:self.legacyConversationColorNames];
NSString *mappedColorName = self.class.legacyConversationColorMap[legacyColorName];
if (!mappedColorName) {
OWSFailDebug(@"failure: unexpected unmappable legacyColorName: %@", legacyColorName);
return kTSThread_DefaultConversationColorName;
}
return mappedColorName;
} }
+ (NSArray<NSString *> *)legacyConversationColorNames + (NSArray<NSString *> *)legacyConversationColorNames
@ -504,6 +533,37 @@ NS_ASSUME_NONNULL_BEGIN
]; ];
} }
+ (NSDictionary<NSString *, NSString *> *)legacyConversationColorMap
{
static NSDictionary<NSString *, NSString *> *colorMap;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
colorMap = @{
@"red" : @"crimson",
@"deep_orange" : @"crimson",
@"orange" : @"vermilion",
@"amber" : @"vermilion",
@"brown" : @"burlap",
@"yellow" : @"burlap",
@"pink" : @"plum",
@"purple" : @"violet",
@"deep_purple" : @"violet",
@"indigo" : @"indigo",
@"blue" : @"blue",
@"light_blue" : @"blue",
@"cyan" : @"teal",
@"teal" : @"teal",
@"green" : @"forest",
@"light_green" : @"wintergreen",
@"lime" : @"wintergreen",
@"blue_grey" : @"taupe",
@"grey" : @"steel",
};
});
return colorMap;
}
- (void)updateConversationColorName:(NSString *)colorName transaction:(YapDatabaseReadWriteTransaction *)transaction - (void)updateConversationColorName:(NSString *)colorName transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction

@ -27,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
[groupBuilder setName:group.groupName]; [groupBuilder setName:group.groupName];
[groupBuilder setMembers:group.groupMemberIds]; [groupBuilder setMembers:group.groupMemberIds];
[groupBuilder setColor:groupThread.conversationColorName]; [groupBuilder setColor:groupThread.conversationColorName];
OWSAssertDebug([TSThread.conversationColorNames containsObject:groupThread.conversationColorName]);
if ([OWSBlockingManager.sharedManager isGroupIdBlocked:group.groupId]) { if ([OWSBlockingManager.sharedManager isGroupIdBlocked:group.groupId]) {
[groupBuilder setBlocked:YES]; [groupBuilder setBlocked:YES];

@ -108,6 +108,7 @@ NS_ASSUME_NONNULL_BEGIN
conversationColorName = [TSThread stableColorNameForNewConversationWithString:signalAccount.recipientId]; conversationColorName = [TSThread stableColorNameForNewConversationWithString:signalAccount.recipientId];
} }
OWSAssertDebug([TSThread.conversationColorNames containsObject:conversationColorName]);
[contactsOutputStream writeSignalAccount:signalAccount [contactsOutputStream writeSignalAccount:signalAccount
recipientIdentity:recipientIdentity recipientIdentity:recipientIdentity
profileKeyData:profileKeyData profileKeyData:profileKeyData

Loading…
Cancel
Save