diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index c10d5fb81..079b71d8f 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -216,6 +216,7 @@ 34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */; }; 34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */; }; 34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF001206BD5A500025978 /* OWSBubbleView.m */; }; + 34DBF007206C3CB200025978 /* OWSBubbleStrokeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF006206C3CB200025978 /* OWSBubbleStrokeView.m */; }; 34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */; }; 34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */; }; 34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */; }; @@ -841,6 +842,8 @@ 34DBF000206BD5A400025978 /* OWSMessageTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageTextView.h; sourceTree = ""; }; 34DBF001206BD5A500025978 /* OWSBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBubbleView.m; sourceTree = ""; }; 34DBF002206BD5A500025978 /* OWSBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBubbleView.h; sourceTree = ""; }; + 34DBF005206C3CB100025978 /* OWSBubbleStrokeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBubbleStrokeView.h; sourceTree = ""; }; + 34DBF006206C3CB200025978 /* OWSBubbleStrokeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBubbleStrokeView.m; sourceTree = ""; }; 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AudioProgressView.swift; sourceTree = ""; }; 34E3EF0B1EFC235B007F6822 /* DebugUIDiskUsage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIDiskUsage.h; sourceTree = ""; }; 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = ""; }; @@ -1651,6 +1654,8 @@ 34D1F0971F867BFC0066283D /* ConversationViewCell.m */, 34D1F0B81F8800D90066283D /* OWSAudioMessageView.h */, 34D1F0B91F8800D90066283D /* OWSAudioMessageView.m */, + 34DBF005206C3CB100025978 /* OWSBubbleStrokeView.h */, + 34DBF006206C3CB200025978 /* OWSBubbleStrokeView.m */, 34DBF002206BD5A500025978 /* OWSBubbleView.h */, 34DBF001206BD5A500025978 /* OWSBubbleView.m */, 34D1F09A1F867BFC0066283D /* OWSContactOffersCell.h */, @@ -3135,6 +3140,7 @@ 3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */, 34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */, 452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */, + 34DBF007206C3CB200025978 /* OWSBubbleStrokeView.m in Sources */, 34D1F0BA1F8800D90066283D /* OWSAudioMessageView.m in Sources */, 34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */, 45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */, diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleStrokeView.h b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleStrokeView.h new file mode 100644 index 000000000..c2ddcc92b --- /dev/null +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleStrokeView.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +@class OWSBubbleView; + +@interface OWSBubbleStrokeView : UIView + +@property (nonatomic, weak) OWSBubbleView *bubbleView; + +@property (nonatomic) UIColor *strokeColor; +@property (nonatomic) CGFloat strokeThickness; + +- (void)updateLayers; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleStrokeView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleStrokeView.m new file mode 100644 index 000000000..c96c1f4ff --- /dev/null +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleStrokeView.m @@ -0,0 +1,114 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +#import "OWSBubbleStrokeView.h" +#import "OWSBubbleView.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface OWSBubbleStrokeView () + +@property (nonatomic) CAShapeLayer *shapeLayer; + +@end + +#pragma mark - + +@implementation OWSBubbleStrokeView + +- (instancetype)init +{ + self = [super init]; + if (!self) { + return self; + } + + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + + return self; +} + +- (void)setStrokeColor:(UIColor *)strokeColor +{ + _strokeColor = strokeColor; + + [self updateLayers]; +} + +- (void)setStrokeThickness:(CGFloat)strokeThickness +{ + _strokeThickness = strokeThickness; + + [self updateLayers]; +} + +- (void)setFrame:(CGRect)frame +{ + BOOL didChange = !CGSizeEqualToSize(self.frame.size, frame.size); + + [super setFrame:frame]; + + if (didChange || !self.shapeLayer) { + [self updateLayers]; + } +} + +- (void)setBounds:(CGRect)bounds +{ + BOOL didChange = !CGSizeEqualToSize(self.bounds.size, bounds.size); + + [super setBounds:bounds]; + + if (didChange || !self.shapeLayer) { + [self updateLayers]; + } +} + +- (void)setCenter:(CGPoint)center +{ + [super setCenter:center]; + + [self updateLayers]; +} + +- (void)updateLayers +{ + if (!self.shapeLayer) { + self.shapeLayer = [CAShapeLayer new]; + [self.layer addSublayer:self.shapeLayer]; + } + + // Don't fill the shape layer; we just want a stroke around the border. + self.shapeLayer.fillColor = [UIColor clearColor].CGColor; + + self.clipsToBounds = YES; + + if (!self.bubbleView) { + return; + } + + self.shapeLayer.strokeColor = self.strokeColor.CGColor; + self.shapeLayer.lineWidth = self.strokeThickness; + self.shapeLayer.zPosition = 100.f; + + UIBezierPath *bezierPath = [UIBezierPath new]; + + UIBezierPath *boundsBezierPath = [UIBezierPath bezierPathWithRect:self.bounds]; + [bezierPath appendPath:boundsBezierPath]; + + UIBezierPath *bubbleBezierPath = [self.bubbleView maskPath]; + // We need to convert between coordinate systems using layers, not views. + CGPoint bubbleOffset = [self.layer convertPoint:CGPointZero fromLayer:self.bubbleView.layer]; + CGAffineTransform transform = CGAffineTransformMakeTranslation(bubbleOffset.x, bubbleOffset.y); + [bubbleBezierPath applyTransform:transform]; + [bezierPath appendPath:bubbleBezierPath]; + + self.shapeLayer.path = bezierPath.CGPath; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h index a1f5436aa..7184fc315 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h @@ -13,16 +13,19 @@ extern const CGFloat kBubbleThornVInset; extern const CGFloat kBubbleTextHInset; extern const CGFloat kBubbleTextVInset; +@class OWSBubbleStrokeView; + @interface OWSBubbleView : UIView +@property (nonatomic, weak, nullable) OWSBubbleStrokeView *bubbleStrokeView; + @property (nonatomic) BOOL isOutgoing; @property (nonatomic) BOOL hideTail; -@property (nonatomic) CAShapeLayer *maskLayer; -@property (nonatomic) CAShapeLayer *shapeLayer; - @property (nonatomic, nullable) UIColor *bubbleColor; +- (UIBezierPath *)maskPath; + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m index 0bde2233a..0ee1379bc 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m @@ -3,6 +3,7 @@ // #import "OWSBubbleView.h" +#import "OWSBubbleStrokeView.h" #import NS_ASSUME_NONNULL_BEGIN @@ -17,6 +18,15 @@ const CGFloat kBubbleThornVInset = 0; const CGFloat kBubbleTextHInset = 10.f; const CGFloat kBubbleTextVInset = 10.f; +@interface OWSBubbleView () + +@property (nonatomic) CAShapeLayer *maskLayer; +@property (nonatomic) CAShapeLayer *shapeLayer; + +@end + +#pragma mark - + @implementation OWSBubbleView - (void)setIsOutgoing:(BOOL)isOutgoing @@ -26,7 +36,7 @@ const CGFloat kBubbleTextVInset = 10.f; _isOutgoing = isOutgoing; if (didChange || !self.shapeLayer) { - [self updateMask]; + [self updateLayers]; } } @@ -37,8 +47,11 @@ const CGFloat kBubbleTextVInset = 10.f; [super setFrame:frame]; if (didChange || !self.shapeLayer) { - [self updateMask]; + [self updateLayers]; } + + // We need to inform the "bubble stroke view" (if any) any time our frame changes. + [self.bubbleStrokeView updateLayers]; } - (void)setBounds:(CGRect)bounds @@ -48,8 +61,19 @@ const CGFloat kBubbleTextVInset = 10.f; [super setBounds:bounds]; if (didChange || !self.shapeLayer) { - [self updateMask]; + [self updateLayers]; } + + // We need to inform the "bubble stroke view" (if any) any time our frame changes. + [self.bubbleStrokeView updateLayers]; +} + +- (void)setCenter:(CGPoint)center +{ + [super setCenter:center]; + + // We need to inform the "bubble stroke view" (if any) any time our frame changes. + [self.bubbleStrokeView updateLayers]; } - (void)setBubbleColor:(nullable UIColor *)bubbleColor @@ -57,12 +81,12 @@ const CGFloat kBubbleTextVInset = 10.f; _bubbleColor = bubbleColor; if (!self.shapeLayer) { - [self updateMask]; + [self updateLayers]; } self.shapeLayer.fillColor = bubbleColor.CGColor; } -- (void)updateMask +- (void)updateLayers { if (!self.shapeLayer) { self.shapeLayer = [CAShapeLayer new]; @@ -73,15 +97,21 @@ const CGFloat kBubbleTextVInset = 10.f; self.layer.mask = self.maskLayer; } - UIBezierPath *bezierPath = - [self.class maskPathForSize:self.bounds.size isOutgoing:self.isOutgoing isRTL:self.isRTL]; + UIBezierPath *bezierPath = [self maskPath]; self.shapeLayer.fillColor = self.bubbleColor.CGColor; + // self.shapeLayer.bounds = self.bounds; self.shapeLayer.path = bezierPath.CGPath; + // self.maskLayer.bounds = self.bounds; self.maskLayer.path = bezierPath.CGPath; } +- (UIBezierPath *)maskPath +{ + return [self.class maskPathForSize:self.bounds.size isOutgoing:self.isOutgoing isRTL:self.isRTL]; +} + + (UIBezierPath *)maskPathForSize:(CGSize)size isOutgoing:(BOOL)isOutgoing isRTL:(BOOL)isRTL { UIBezierPath *bezierPath = [UIBezierPath new]; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index c0b4fb018..260d1d7dc 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -8,6 +8,7 @@ #import "ConversationViewItem.h" #import "NSAttributedString+OWS.h" #import "OWSAudioMessageView.h" +#import "OWSBubbleStrokeView.h" #import "OWSBubbleView.h" #import "OWSExpirationTimerView.h" #import "OWSGenericAttachmentView.h" @@ -426,6 +427,22 @@ CG_INLINE CGSize CGSizeCeil(CGSize size) } lastSubview = bodyMediaView; bottomMargin = 0; + + BOOL shouldStrokeMediaView = [bodyMediaView isKindOfClass:[UIImageView class]]; + if (shouldStrokeMediaView) { + OWSBubbleStrokeView *bubbleStrokeView = [OWSBubbleStrokeView new]; + bubbleStrokeView.strokeThickness = 1.f; + bubbleStrokeView.strokeColor = [UIColor colorWithWhite:0.f alpha:0.1f]; + bubbleStrokeView.bubbleView = self.bubbleView; + + [self.bubbleView addSubview:bubbleStrokeView]; + [bubbleStrokeView autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:bodyMediaView]; + [bubbleStrokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:bodyMediaView]; + [bubbleStrokeView autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:bodyMediaView]; + [bubbleStrokeView autoPinEdge:ALEdgeRight toEdge:ALEdgeRight ofView:bodyMediaView]; + self.bubbleView.bubbleStrokeView = bubbleStrokeView; + OWSAssert(self.bubbleView.bubbleStrokeView); + } } OWSMessageTextView *_Nullable bodyTextView = nil; @@ -1233,6 +1250,7 @@ CG_INLINE CGSize CGSizeCeil(CGSize size) self.bubbleView.hidden = YES; self.bubbleView.bubbleColor = nil; + self.bubbleView.bubbleStrokeView = nil; for (UIView *subview in self.bubbleView.subviews) { [subview removeFromSuperview]; diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 61c3cbe56..08b531e5c 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -703,6 +703,27 @@ NS_ASSUME_NONNULL_BEGIN thread:thread]; } ++ (DebugUIMessagesAction *)fakeOutgoingPngAction:(TSThread *)thread + actionLabel:(NSString *)actionLabel + imageSize:(CGSize)imageSize + backgroundColor:(UIColor *)backgroundColor + textColor:(UIColor *)textColor + imageLabel:(NSString *)imageLabel + messageState:(TSOutgoingMessageState)messageState + hasCaption:(BOOL)hasCaption +{ + OWSAssert(thread); + + return [self fakeOutgoingMediaAction:actionLabel + messageState:messageState + hasCaption:hasCaption + fakeAssetLoader:[DebugUIMessagesAssetLoader pngInstanceWithSize:imageSize + backgroundColor:backgroundColor + textColor:textColor + label:imageLabel] + thread:thread]; +} + + (DebugUIMessagesAction *)fakeOutgoingTinyPdfAction:(TSThread *)thread messageState:(TSOutgoingMessageState)messageState hasCaption:(BOOL)hasCaption @@ -1018,6 +1039,27 @@ NS_ASSUME_NONNULL_BEGIN thread:thread]; } ++ (DebugUIMessagesAction *)fakeIncomingPngAction:(TSThread *)thread + actionLabel:(NSString *)actionLabel + imageSize:(CGSize)imageSize + backgroundColor:(UIColor *)backgroundColor + textColor:(UIColor *)textColor + imageLabel:(NSString *)imageLabel + isAttachmentDownloaded:(BOOL)isAttachmentDownloaded + hasCaption:(BOOL)hasCaption +{ + OWSAssert(thread); + + return [self fakeIncomingMediaAction:actionLabel + isAttachmentDownloaded:isAttachmentDownloaded + hasCaption:hasCaption + fakeAssetLoader:[DebugUIMessagesAssetLoader pngInstanceWithSize:imageSize + backgroundColor:backgroundColor + textColor:textColor + label:imageLabel] + thread:thread]; +} + + (DebugUIMessagesAction *)fakeIncomingTinyPdfAction:(TSThread *)thread isAttachmentDownloaded:(BOOL)isAttachmentDownloaded hasCaption:(BOOL)hasCaption @@ -1338,6 +1380,112 @@ NS_ASSUME_NONNULL_BEGIN [self fakeOutgoingTinyPngAction:thread messageState:TSOutgoingMessageStateSentToService hasCaption:NO], [self fakeOutgoingTinyPngAction:thread messageState:TSOutgoingMessageStateSentToService hasCaption:YES], ]]; + if (includeLabels) { + [actions addObject:[self fakeOutgoingTextMessageAction:thread + messageState:TSOutgoingMessageStateSentToService + text:@"⚠️ Outgoing Reserved Color Png ⚠️"]]; + } + [actions addObjectsFromArray:@[ + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing White Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[UIColor whiteColor] + textColor:[UIColor ows_signalBrandBlueColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateUnsent + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing White Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[UIColor whiteColor] + textColor:[UIColor ows_signalBrandBlueColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateAttemptingOut + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing White Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[UIColor whiteColor] + textColor:[UIColor ows_signalBrandBlueColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateSentToService + hasCaption:YES], + + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Unsent' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingUnsent] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateUnsent + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Unsent' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingUnsent] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateAttemptingOut + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Unsent' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingUnsent] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateSentToService + hasCaption:YES], + + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Sending' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSending] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateUnsent + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Sending' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSending] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateAttemptingOut + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Sending' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSending] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateSentToService + hasCaption:YES], + + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Sent' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSent] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateUnsent + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Sent' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSent] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateAttemptingOut + hasCaption:YES], + [self fakeOutgoingPngAction:thread + actionLabel:@"Fake Outgoing 'Outgoing Sent' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSent] + textColor:[UIColor whiteColor] + imageLabel:@"W" + messageState:TSOutgoingMessageStateSentToService + hasCaption:YES], + ]]; if (includeLabels) { [actions addObject:[self fakeOutgoingTextMessageAction:thread messageState:TSOutgoingMessageStateSentToService @@ -1476,6 +1624,44 @@ NS_ASSUME_NONNULL_BEGIN [self fakeIncomingTinyPngAction:thread isAttachmentDownloaded:YES hasCaption:NO], [self fakeIncomingTinyPngAction:thread isAttachmentDownloaded:YES hasCaption:YES], ]]; + if (includeLabels) { + [actions + addObject:[self fakeIncomingTextMessageAction:thread text:@"⚠️ Incoming Reserved Color Png ⚠️"]]; + } + [actions addObjectsFromArray:@[ + [self fakeIncomingPngAction:thread + actionLabel:@"Fake Incoming White Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[UIColor whiteColor] + textColor:[UIColor ows_signalBrandBlueColor] + imageLabel:@"W" + isAttachmentDownloaded:YES + hasCaption:YES], + [self fakeIncomingPngAction:thread + actionLabel:@"Fake Incoming White Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[UIColor whiteColor] + textColor:[UIColor ows_signalBrandBlueColor] + imageLabel:@"W" + isAttachmentDownloaded:NO + hasCaption:YES], + [self fakeIncomingPngAction:thread + actionLabel:@"Fake Incoming 'Incoming' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorIncoming] + textColor:[UIColor whiteColor] + imageLabel:@"W" + isAttachmentDownloaded:YES + hasCaption:YES], + [self fakeIncomingPngAction:thread + actionLabel:@"Fake Incoming 'Incoming' Png" + imageSize:CGSizeMake(200.f, 200.f) + backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorIncoming] + textColor:[UIColor whiteColor] + imageLabel:@"W" + isAttachmentDownloaded:NO + hasCaption:YES], + ]]; if (includeLabels) { [actions addObject:[self fakeIncomingTextMessageAction:thread text:@"⚠️ Incoming Tiny Pdf ⚠️"]]; } @@ -1519,7 +1705,7 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(thread); - return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"Fake All Media" + return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"All Fake Media" subactions:[self allFakeMediaActions:thread includeLabels:YES]]; } @@ -1527,7 +1713,7 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(thread); - return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Fake Random Media" + return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Random Fake Media" subactions:[self allFakeMediaActions:thread includeLabels:NO]]; } @@ -1744,7 +1930,7 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(thread); - return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"Fake All Text" + return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"All Fake Text" subactions:[self allFakeTextActions:thread includeLabels:YES]]; } @@ -1752,7 +1938,7 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(thread); - return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Fake Random Text" + return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Random Fake Text" subactions:[self allFakeTextActions:thread includeLabels:NO]]; } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h index 909c60431..dc35286d5 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h @@ -28,6 +28,10 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)wideLandscapePngInstance; + (instancetype)largePngInstance; + (instancetype)tinyPngInstance; ++ (instancetype)pngInstanceWithSize:(CGSize)size + backgroundColor:(UIColor *)backgroundColor + textColor:(UIColor *)textColor + label:(NSString *)label; + (instancetype)tinyPdfInstance; + (instancetype)largePdfInstance; + (instancetype)missingPngInstance; diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m index 39800f291..6781d3450 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m @@ -456,6 +456,17 @@ NS_ASSUME_NONNULL_BEGIN return instance; } ++ (instancetype)pngInstanceWithSize:(CGSize)size + backgroundColor:(UIColor *)backgroundColor + textColor:(UIColor *)textColor + label:(NSString *)label +{ + return [DebugUIMessagesAssetLoader fakePngAssetLoaderWithImageSize:size + backgroundColor:backgroundColor + textColor:textColor + label:label]; +} + + (instancetype)tinyPdfInstance { static DebugUIMessagesAssetLoader *instance = nil; diff --git a/SignalMessaging/utils/OWSMessagesBubbleImageFactory.swift b/SignalMessaging/utils/OWSMessagesBubbleImageFactory.swift index 9a3907bce..eb8bccdc6 100644 --- a/SignalMessaging/utils/OWSMessagesBubbleImageFactory.swift +++ b/SignalMessaging/utils/OWSMessagesBubbleImageFactory.swift @@ -57,17 +57,25 @@ public class OWSMessagesBubbleImageFactory: NSObject { } } + public static let bubbleColorIncoming = UIColor.jsq_messageBubbleLightGray()! + + public static let bubbleColorOutgoingUnsent = UIColor.gray + + public static let bubbleColorOutgoingSending = UIColor.ows_fadedBlue + + public static let bubbleColorOutgoingSent = UIColor.ows_materialBlue + public func bubbleColor(message: TSMessage) -> UIColor { if message is TSIncomingMessage { - return UIColor.jsq_messageBubbleLightGray()! + return OWSMessagesBubbleImageFactory.bubbleColorIncoming } else if let outgoingMessage = message as? TSOutgoingMessage { switch outgoingMessage.messageState { case .unsent: - return UIColor.gray + return OWSMessagesBubbleImageFactory.bubbleColorOutgoingUnsent case .attemptingOut: - return UIColor.ows_fadedBlue + return OWSMessagesBubbleImageFactory.bubbleColorOutgoingSending default: - return UIColor.ows_materialBlue + return OWSMessagesBubbleImageFactory.bubbleColorOutgoingSent } } else { owsFail("Unexpected message type: \(message)")