From 60c5a84dd263199c2ebc104f46ebc82fd88f163c Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 6 Nov 2018 09:31:52 -0500 Subject: [PATCH] Fix issues in media gallery cells; Improve debug galleries. --- Signal.xcodeproj/project.pbxproj | 16 ++-- Signal/src/Signal-Bridging-Header.h | 1 + .../Cells/ConversationMediaView.swift | 15 ++-- .../Cells/MediaGalleryCellView.swift | 17 ++-- .../Cells/OWSBubbleShapeView.m | 21 +++-- .../ConversationView/Cells/OWSBubbleView.h | 2 +- .../Cells/OWSMessageBubbleView.m | 28 ++++--- .../ViewControllers/DebugUI/DebugUIMessages.m | 81 +++++++++++++------ .../DebugUI/DebugUIMessagesAssetLoader.h | 6 ++ .../DebugUI/DebugUIMessagesAssetLoader.m | 48 +++++++++++ SignalMessaging/utils/ThreadUtil.h | 1 + SignalMessaging/utils/ThreadUtil.m | 4 +- 12 files changed, 177 insertions(+), 63 deletions(-) diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 02a16c138..85af7dc05 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -2287,28 +2287,28 @@ B633C4FD1A1D190B0059AC12 /* Images */ = { isa = PBXGroup; children = ( - 34B6A90A218BA1D0007C4606 /* typing-animation.gif */, - AD83FF461A73428300B5C81A /* audio_play_button_blue.png */, AD83FF381A73426500B5C81A /* audio_pause_button_blue.png */, AD83FF391A73426500B5C81A /* audio_pause_button_blue@2x.png */, + AD83FF3D1A73426500B5C81A /* audio_pause_button.png */, + AD83FF3E1A73426500B5C81A /* audio_pause_button@2x.png */, + AD83FF461A73428300B5C81A /* audio_play_button_blue.png */, AD83FF3A1A73426500B5C81A /* audio_play_button_blue@2x.png */, AD83FF3B1A73426500B5C81A /* audio_play_button.png */, AD83FF3C1A73426500B5C81A /* audio_play_button@2x.png */, - AD83FF3D1A73426500B5C81A /* audio_pause_button.png */, - AD83FF3E1A73426500B5C81A /* audio_pause_button@2x.png */, - B10C9B5B1A7049EC00ECA2BF /* pause_icon.png */, - B10C9B5C1A7049EC00ECA2BF /* pause_icon@2x.png */, - B10C9B5D1A7049EC00ECA2BF /* play_icon.png */, - B10C9B5E1A7049EC00ECA2BF /* play_icon@2x.png */, B633C5041A1D190B0059AC12 /* call@2x.png */, B633C50B1A1D190B0059AC12 /* contact_default_feed.png */, B633C51B1A1D190B0059AC12 /* endcall@2x.png */, FC5CDF371A3393DD00B47253 /* error_white@2x.png */, B633C5411A1D190B0059AC12 /* mute_off@2x.png */, B633C5421A1D190B0059AC12 /* mute_on@2x.png */, + B10C9B5B1A7049EC00ECA2BF /* pause_icon.png */, + B10C9B5C1A7049EC00ECA2BF /* pause_icon@2x.png */, + B10C9B5D1A7049EC00ECA2BF /* play_icon.png */, + B10C9B5E1A7049EC00ECA2BF /* play_icon@2x.png */, FC91203F1A39EFB70074545C /* qr@2x.png */, B633C54C1A1D190B0059AC12 /* quit@2x.png */, B633C5501A1D190B0059AC12 /* savephoto@2x.png */, + 34B6A90A218BA1D0007C4606 /* typing-animation.gif */, FC5CDF381A3393DD00B47253 /* warning_white@2x.png */, ); path = Images; diff --git a/Signal/src/Signal-Bridging-Header.h b/Signal/src/Signal-Bridging-Header.h index c63712043..734b08064 100644 --- a/Signal/src/Signal-Bridging-Header.h +++ b/Signal/src/Signal-Bridging-Header.h @@ -27,6 +27,7 @@ #import "OWSBackup.h" #import "OWSBackupIO.h" #import "OWSBezierPathView.h" +#import "OWSBubbleShapeView.h" #import "OWSBubbleView.h" #import "OWSCallNotificationsAdaptee.h" #import "OWSDatabaseMigration.h" diff --git a/Signal/src/ViewControllers/ConversationView/Cells/ConversationMediaView.swift b/Signal/src/ViewControllers/ConversationView/Cells/ConversationMediaView.swift index 936258d91..68829ef48 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/ConversationMediaView.swift +++ b/Signal/src/ViewControllers/ConversationView/Cells/ConversationMediaView.swift @@ -51,6 +51,12 @@ public class ConversationMediaView: UIView { } } + private func addMediaSubview(_ subview: UIView) { + addSubview(subview) + subview.autoPinEdgesToSuperviewEdges() + // TODO: Possibly add upload/download indicator here. + } + private func configureForAnimatedImage(attachmentStream: TSAttachmentStream) { guard let cacheKey = attachmentStream.uniqueId else { owsFailDebug("Attachment stream missing unique ID.") @@ -65,8 +71,7 @@ public class ConversationMediaView: UIView { animatedImageView.layer.minificationFilter = kCAFilterTrilinear animatedImageView.layer.magnificationFilter = kCAFilterTrilinear animatedImageView.backgroundColor = Theme.offBackgroundColor - addSubview(animatedImageView) - animatedImageView.autoPinEdgesToSuperviewEdges() + addMediaSubview(animatedImageView) loadBlock = { [weak self] in guard let strongSelf = self else { return @@ -112,8 +117,7 @@ public class ConversationMediaView: UIView { stillImageView.layer.minificationFilter = kCAFilterTrilinear stillImageView.layer.magnificationFilter = kCAFilterTrilinear stillImageView.backgroundColor = Theme.offBackgroundColor - addSubview(stillImageView) - stillImageView.autoPinEdgesToSuperviewEdges() + addMediaSubview(stillImageView) loadBlock = { [weak self] in guard let strongSelf = self else { return @@ -158,8 +162,7 @@ public class ConversationMediaView: UIView { stillImageView.layer.minificationFilter = kCAFilterTrilinear stillImageView.layer.magnificationFilter = kCAFilterTrilinear stillImageView.backgroundColor = Theme.offBackgroundColor - addSubview(stillImageView) - stillImageView.autoPinEdgesToSuperviewEdges() + addMediaSubview(stillImageView) // TODO: Hide during upload/download. let videoPlayIcon = UIImage(named: "play_button") diff --git a/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift b/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift index 494ded038..94cd28d49 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift +++ b/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift @@ -7,11 +7,18 @@ import Foundation @objc(OWSMediaGalleryCellView) public class MediaGalleryCellView: UIStackView { private let items: [ConversationMediaGalleryItem] - private let itemViews: [ConversationMediaView] + + @objc + public let itemViews: [ConversationMediaView] private static let kSpacingPts: CGFloat = 2 private static let kMaxItems = 5 + @available(*, unavailable, message: "use other init() instead.") + required public init(coder aDecoder: NSCoder) { + notImplemented() + } + @objc public required init(mediaCache: NSCache, items: [ConversationMediaGalleryItem], @@ -24,7 +31,8 @@ public class MediaGalleryCellView: UIStackView { super.init(frame: .zero) - backgroundColor = Theme.backgroundColor + // UIStackView's backgroundColor property has no effect. + addBackgroundView(withBackgroundColor: Theme.backgroundColor) createContents(maxMessageWidth: maxMessageWidth) } @@ -173,11 +181,6 @@ public class MediaGalleryCellView: UIStackView { } } - @available(*, unavailable, message: "use other init() instead.") - required public init(coder aDecoder: NSCoder) { - notImplemented() - } - private class func itemsToDisplay(forItems items: [ConversationMediaGalleryItem]) -> [ConversationMediaGalleryItem] { // TODO: Unless design changes, we want to display // items which are still downloading and invalid diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleShapeView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleShapeView.m index ac2d0a5f1..dd9cd8ba0 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleShapeView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleShapeView.m @@ -23,7 +23,8 @@ typedef NS_ENUM(NSUInteger, OWSBubbleShapeViewMode) { @property (nonatomic) CAShapeLayer *shapeLayer; @property (nonatomic) CAShapeLayer *maskLayer; -@property (nonatomic, weak) OWSBubbleView *bubbleView; +@property (nonatomic, nullable, weak) OWSBubbleView *bubbleView; +@property (nonatomic) BOOL isConfigured; @end @@ -33,7 +34,6 @@ typedef NS_ENUM(NSUInteger, OWSBubbleShapeViewMode) { - (void)configure { - self.mode = OWSBubbleShapeViewMode_Draw; self.opaque = NO; self.backgroundColor = [UIColor clearColor]; self.layoutMargins = UIEdgeInsetsZero; @@ -42,8 +42,11 @@ typedef NS_ENUM(NSUInteger, OWSBubbleShapeViewMode) { [self.layer addSublayer:self.shapeLayer]; self.maskLayer = [CAShapeLayer new]; -} + self.isConfigured = YES; + + [self updateLayers]; +} - (instancetype)initDraw { @@ -100,7 +103,6 @@ typedef NS_ENUM(NSUInteger, OWSBubbleShapeViewMode) { _innerShadowOpacity = opacity; [self configure]; - [self updateLayers]; return self; } @@ -176,15 +178,24 @@ typedef NS_ENUM(NSUInteger, OWSBubbleShapeViewMode) { [self updateLayers]; } +- (void)setBubbleView:(nullable OWSBubbleView *)bubbleView +{ + _bubbleView = bubbleView; + + [self updateLayers]; +} + - (void)updateLayers { if (!self.shapeLayer) { return; } - if (!self.bubbleView) { return; } + if (!self.isConfigured) { + return; + } // Prevent the layer from animating changes. [CATransaction begin]; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h index 09f5a49a7..5119d3c1a 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h @@ -21,7 +21,7 @@ typedef NS_OPTIONS(NSUInteger, OWSDirectionalRectCorner) { - (void)updateLayers; -- (void)setBubbleView:(OWSBubbleView *)bubbleView; +- (void)setBubbleView:(nullable OWSBubbleView *)bubbleView; @end diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index 077d30d46..8af2f3e7d 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -351,15 +351,6 @@ const UIDataDetectorTypes kOWSAllowedDataDetectorTypes if (self.hasBodyMediaWithThumbnail) { [self.stackView addArrangedSubview:bodyMediaView]; - - OWSBubbleShapeView *innerShadowView = [[OWSBubbleShapeView alloc] - initInnerShadowWithColor:(Theme.isDarkThemeEnabled ? UIColor.ows_whiteColor - : UIColor.ows_blackColor) - radius:0.5f - opacity:0.15f]; - [bodyMediaView addSubview:innerShadowView]; - [self.bubbleView addPartnerView:innerShadowView]; - [self.viewConstraints addObjectsFromArray:[innerShadowView ows_autoPinToSuperviewEdges]]; } else { OWSAssertDebug(self.cellType == OWSMessageCellType_ContactShare); @@ -620,7 +611,8 @@ const UIDataDetectorTypes kOWSAllowedDataDetectorTypes - (BOOL)hasFullWidthMediaView { - return (self.hasBodyMediaWithThumbnail || self.cellType == OWSMessageCellType_ContactShare); + return (self.hasBodyMediaWithThumbnail || self.cellType == OWSMessageCellType_ContactShare + || self.cellType == OWSMessageCellType_MediaGallery); } - (BOOL)canFooterOverlayMedia @@ -802,6 +794,14 @@ const UIDataDetectorTypes kOWSAllowedDataDetectorTypes self.unloadCellContentBlock = ^{ [galleryView unloadMedia]; }; + for (UIView *itemView in galleryView.itemViews) { + OWSBubbleShapeView *strokeView = [[OWSBubbleShapeView alloc] initDraw]; + strokeView.strokeColor = [UIColor colorWithWhite:0.5f alpha:0.4f]; + strokeView.strokeThickness = 1.f; + [itemView addSubview:strokeView]; + [self.bubbleView addPartnerView:strokeView]; + [self.viewConstraints addObjectsFromArray:[strokeView ows_autoPinToSuperviewEdges]]; + } return galleryView; } @@ -821,6 +821,14 @@ const UIDataDetectorTypes kOWSAllowedDataDetectorTypes }; [self addAttachmentUploadViewIfNecessary]; + OWSBubbleShapeView *innerShadowView = [[OWSBubbleShapeView alloc] + initInnerShadowWithColor:(Theme.isDarkThemeEnabled ? UIColor.ows_whiteColor : UIColor.ows_blackColor) + radius:0.5f + opacity:0.15f]; + [mediaView addSubview:innerShadowView]; + [self.bubbleView addPartnerView:innerShadowView]; + [self.viewConstraints addObjectsFromArray:[innerShadowView ows_autoPinToSuperviewEdges]]; + return mediaView; } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 1cbab0b33..e4ab8bfbe 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -4645,52 +4645,85 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac const uint32_t kMinImageCount = 2; const uint32_t kMaxImageCount = 10; uint32_t imageCount = kMinImageCount + arc4random_uniform(kMaxImageCount - kMinImageCount); - [self sendMediaGalleryInThread:thread imageCount:imageCount]; + NSString *_Nullable messageBody = (arc4random_uniform(2) > 0 ? @"This is the media gallery title..." : nil); + [self sendMediaGalleryInThread:thread imageCount:imageCount messageBody:messageBody]; } + (void)sendExemplaryMediaGalleriesInThread:(TSThread *)thread { OWSLogInfo(@""); - [self sendMediaGalleryInThread:thread imageCount:2]; - [self sendMediaGalleryInThread:thread imageCount:3]; - [self sendMediaGalleryInThread:thread imageCount:4]; - [self sendMediaGalleryInThread:thread imageCount:5]; - [self sendMediaGalleryInThread:thread imageCount:6]; + [self sendMediaGalleryInThread:thread imageCount:2 messageBody:nil]; + [self sendMediaGalleryInThread:thread imageCount:3 messageBody:nil]; + [self sendMediaGalleryInThread:thread imageCount:4 messageBody:nil]; + [self sendMediaGalleryInThread:thread imageCount:5 messageBody:nil]; + [self sendMediaGalleryInThread:thread imageCount:6 messageBody:nil]; + [self sendMediaGalleryInThread:thread imageCount:7 messageBody:nil]; + NSString *messageBody = @"This is the media gallery title..."; + [self sendMediaGalleryInThread:thread imageCount:2 messageBody:messageBody]; + [self sendMediaGalleryInThread:thread imageCount:3 messageBody:messageBody]; + [self sendMediaGalleryInThread:thread imageCount:4 messageBody:messageBody]; + [self sendMediaGalleryInThread:thread imageCount:5 messageBody:messageBody]; + [self sendMediaGalleryInThread:thread imageCount:6 messageBody:messageBody]; + [self sendMediaGalleryInThread:thread imageCount:7 messageBody:messageBody]; } -+ (void)sendMediaGalleryInThread:(TSThread *)thread imageCount:(uint32_t)imageCount ++ (void)sendMediaGalleryInThread:(TSThread *)thread + imageCount:(uint32_t)imageCount + messageBody:(nullable NSString *)messageBody + fakeAssetLoaders:(NSArray *)fakeAssetLoaders { OWSAssertDebug(imageCount > 0); OWSLogInfo(@""); NSMutableArray *attachments = [NSMutableArray new]; for (uint32_t i = 0; i < imageCount; i++) { - UIColor *imageColor = [UIColor colorWithRed:arc4random_uniform(256) / 255.f - green:arc4random_uniform(256) / 255.f - blue:arc4random_uniform(256) / 255.f - alpha:1.f]; - UIImage *image = [UIImage imageWithColor:imageColor size:CGSizeMake(10.f, 10.f)]; - OWSAssertDebug(image); - NSData *pngData = UIImagePNGRepresentation(image); - OWSAssertDebug(pngData); - NSString *filePath = [OWSFileSystem temporaryFilePathWithFileExtension:@"png"]; - [pngData writeToFile:filePath atomically:YES]; - OWSAssertDebug([NSFileManager.defaultManager fileExistsAtPath:filePath]); - DataSource *dataSource = [DataSourcePath dataSourceWithFilePath:filePath shouldDeleteOnDeallocation:YES]; - SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource - dataUTI:(NSString *)kUTTypePNG - imageQuality:TSImageQualityOriginal]; + DebugUIMessagesAssetLoader *fakeAssetLoader + = fakeAssetLoaders[arc4random_uniform((uint32_t)fakeAssetLoaders.count)]; + OWSAssertDebug([NSFileManager.defaultManager fileExistsAtPath:fakeAssetLoader.filePath]); + DataSource *dataSource = + [DataSourcePath dataSourceWithFilePath:fakeAssetLoader.filePath shouldDeleteOnDeallocation:NO]; + SignalAttachment *attachment = + [SignalAttachment attachmentWithDataSource:dataSource + dataUTI:[MIMETypeUtil utiTypeForMIMEType:fakeAssetLoader.mimeType] + imageQuality:TSImageQualityOriginal]; [attachments addObject:attachment]; } [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - TSOutgoingMessage *message = - [ThreadUtil enqueueMessageWithAttachments:attachments inThread:thread quotedReplyModel:nil]; + TSOutgoingMessage *message = [ThreadUtil enqueueMessageWithAttachments:attachments + messageBody:messageBody + inThread:thread + quotedReplyModel:nil]; OWSLogError(@"timestamp: %llu.", message.timestamp); }]; } ++ (void)sendMediaGalleryInThread:(TSThread *)thread + imageCount:(uint32_t)imageCount + messageBody:(nullable NSString *)messageBody +{ + OWSAssertDebug(thread); + + NSArray *fakeAssetLoaders = @[ + [DebugUIMessagesAssetLoader jpegInstance], + [DebugUIMessagesAssetLoader largePngInstance], + [DebugUIMessagesAssetLoader tinyPngInstance], + [DebugUIMessagesAssetLoader gifInstance], + [DebugUIMessagesAssetLoader mp4Instance], + ]; + [DebugUIMessagesAssetLoader prepareAssetLoaders:fakeAssetLoaders + success:^{ + [self sendMediaGalleryInThread:thread + imageCount:imageCount + messageBody:messageBody + fakeAssetLoaders:fakeAssetLoaders]; + } + failure:^{ + OWSLogError(@"Could not prepare fake asset loaders."); + }]; +} + #endif @end diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h index b0fc7d97d..ff3ba42f4 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.h @@ -41,6 +41,12 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)oversizeTextInstance; + (instancetype)oversizeTextInstanceWithText:(NSString *)text; +#pragma mark - + ++ (void)prepareAssetLoaders:(NSArray *)assetLoaders + success:(dispatch_block_t)success + failure:(dispatch_block_t)failure; + @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m index f2c46c35b..e851c553a 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessagesAssetLoader.m @@ -5,9 +5,11 @@ #import "DebugUIMessagesAssetLoader.h" #import #import +#import #import #import #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -151,6 +153,9 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertDebug(label.length > 0); @autoreleasepool { + imageSize.width /= UIScreen.mainScreen.scale; + imageSize.height /= UIScreen.mainScreen.scale; + CGRect frame = CGRectZero; frame.size = imageSize; CGFloat smallDimension = MIN(imageSize.width, imageSize.height); @@ -575,6 +580,49 @@ NS_ASSUME_NONNULL_BEGIN return instance; } +#pragma mark - + ++ (void)prepareAssetLoaders:(NSArray *)assetLoaders + success:(dispatch_block_t)success + failure:(dispatch_block_t)failure +{ + + NSMutableArray *promises = [NSMutableArray array]; + NSMutableArray *errors = [NSMutableArray array]; + + for (DebugUIMessagesAssetLoader *assetLoader in assetLoaders) { + // Use chained promises to make the code more readable. + AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { + assetLoader.prepareBlock( + ^{ + // The value doesn't matter, we just need any non-NSError value. + resolve(@(1)); + }, + ^{ + NSError *error = + [NSError errorWithDomain:@"DebugUI" + code:0 + userInfo:@{ NSLocalizedDescriptionKey : @"Could not prepare fake assets." }]; + @synchronized(errors) { + [errors addObject:error]; + } + resolve(error); + }); + }]; + [promises addObject:promise]; + } + + // We could use PMKJoin() or PMKWhen(). + [PMKJoin(promises) + .then(^(id value) { + success(); + }) + .catch(^(id error) { + OWSLogError(@"Could not prepare fake asset loaders: %@.", error); + failure(); + }) retainUntilComplete]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/utils/ThreadUtil.h b/SignalMessaging/utils/ThreadUtil.h index 1afec1ba7..2d7908058 100644 --- a/SignalMessaging/utils/ThreadUtil.h +++ b/SignalMessaging/utils/ThreadUtil.h @@ -54,6 +54,7 @@ NS_ASSUME_NONNULL_BEGIN quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel; + (TSOutgoingMessage *)enqueueMessageWithAttachments:(NSArray *)attachments + messageBody:(nullable NSString *)messageBody inThread:(TSThread *)thread quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel; diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index c7a3a296a..cd4cab181 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -96,11 +96,13 @@ NS_ASSUME_NONNULL_BEGIN return [self enqueueMessageWithAttachments:@[ attachment, ] + messageBody:attachment.captionText inThread:thread quotedReplyModel:quotedReplyModel]; } + (TSOutgoingMessage *)enqueueMessageWithAttachments:(NSArray *)attachments + messageBody:(nullable NSString *)messageBody inThread:(TSThread *)thread quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel { @@ -117,8 +119,6 @@ NS_ASSUME_NONNULL_BEGIN uint32_t expiresInSeconds = (configuration.isEnabled ? configuration.durationSeconds : 0); BOOL isVoiceMessage = (attachments.count == 1 && attachments.lastObject.isVoiceMessage); - // TODO: Support multi-image captions. - NSString *_Nullable messageBody = attachments.lastObject.captionText; TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread