diff --git a/Signal/Images.xcassets/media_album_caption.imageset/Contents.json b/Signal/Images.xcassets/media_album_caption.imageset/Contents.json new file mode 100644 index 000000000..80c4669a0 --- /dev/null +++ b/Signal/Images.xcassets/media_album_caption.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "caption-24@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "caption-24@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "caption-24@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Signal/Images.xcassets/media_album_caption.imageset/caption-24@1x.png b/Signal/Images.xcassets/media_album_caption.imageset/caption-24@1x.png new file mode 100644 index 000000000..a08533151 Binary files /dev/null and b/Signal/Images.xcassets/media_album_caption.imageset/caption-24@1x.png differ diff --git a/Signal/Images.xcassets/media_album_caption.imageset/caption-24@2x.png b/Signal/Images.xcassets/media_album_caption.imageset/caption-24@2x.png new file mode 100644 index 000000000..8e9f81388 Binary files /dev/null and b/Signal/Images.xcassets/media_album_caption.imageset/caption-24@2x.png differ diff --git a/Signal/Images.xcassets/media_album_caption.imageset/caption-24@3x.png b/Signal/Images.xcassets/media_album_caption.imageset/caption-24@3x.png new file mode 100644 index 000000000..34d9e268c Binary files /dev/null and b/Signal/Images.xcassets/media_album_caption.imageset/caption-24@3x.png differ diff --git a/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift b/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift index 94cd28d49..ea86e276e 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift +++ b/Signal/src/ViewControllers/ConversationView/Cells/MediaGalleryCellView.swift @@ -26,7 +26,7 @@ public class MediaGalleryCellView: UIStackView { self.items = items self.itemViews = MediaGalleryCellView.itemsToDisplay(forItems: items).map { ConversationMediaView(mediaCache: mediaCache, - attachment: $0.attachment) + attachment: $0.attachment) } super.init(frame: .zero) @@ -38,6 +38,8 @@ public class MediaGalleryCellView: UIStackView { } private func createContents(maxMessageWidth: CGFloat) { + var moreItemViews = [ConversationMediaView]() + switch itemViews.count { case 0: owsFailDebug("No item views.") @@ -124,6 +126,8 @@ public class MediaGalleryCellView: UIStackView { return } + moreItemViews.append(lastView) + let tintView = UIView() tintView.backgroundColor = UIColor(white: 0, alpha: 0.4) lastView.addSubview(tintView) @@ -142,11 +146,39 @@ public class MediaGalleryCellView: UIStackView { moreLabel.autoCenterInSuperview() } } + + for itemView in itemViews { + guard !moreItemViews.contains(itemView) else { + // Don't display the caption indicator on + // the "more" item, if any. + continue + } + guard let index = itemViews.index(of: itemView) else { + owsFailDebug("Couldn't determine index of item view.") + continue + } + let item = items[index] + guard let caption = item.caption else { + continue + } + guard caption.count > 0 else { + continue + } + guard let icon = UIImage(named: "media_album_caption") else { + owsFailDebug("Couldn't load icon.") + continue + } + let iconView = UIImageView(image: icon.withRenderingMode(.alwaysTemplate)) + iconView.tintColor = .ows_white + itemView.addSubview(iconView) + itemView.layoutMargins = .zero + iconView.autoPinTopToSuperviewMargin(withInset: 6) + iconView.autoPinLeadingToSuperviewMargin(withInset: 6) + } } private func autoSet(viewSize: CGFloat, - ofViews views: [ConversationMediaView] - ) { + ofViews views: [ConversationMediaView]) { for itemView in views { itemView.autoSetDimensions(to: CGSize(width: viewSize, height: viewSize)) } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m index 521a72ce5..366b68838 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m @@ -52,6 +52,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) - (instancetype)initWithAttachment:(TSAttachment *)attachment attachmentStream:(nullable TSAttachmentStream *)attachmentStream + caption:(nullable NSString *)caption mediaSize:(CGSize)mediaSize { OWSAssertDebug(attachment); @@ -64,6 +65,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) _attachment = attachment; _attachmentStream = attachmentStream; + _caption = caption; _mediaSize = mediaSize; return self; @@ -500,6 +502,19 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) }]; } +- (DisplayableText *)displayableCaptionForText:(NSString *)text attachmentId:(NSString *)attachmentId +{ + OWSAssertDebug(text); + OWSAssertDebug(attachmentId.length > 0); + + NSString *displayableTextCacheKey = [@"attachment-caption-" stringByAppendingString:attachmentId]; + + return [self displayableTextForCacheKey:displayableTextCacheKey + textBlock:^{ + return text; + }]; +} + - (DisplayableText *)displayableTextForCacheKey:(NSString *)displayableTextCacheKey textBlock:(NSString * (^_Nonnull)(void))textBlock { @@ -557,7 +572,6 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) NSArray *attachments = [message attachmentsWithTransaction:transaction]; if ([message isMediaGalleryWithTransaction:transaction]) { OWSAssertDebug(attachments.count > 0); - // TODO: Handle captions? NSArray *mediaGalleryItems = [self mediaGalleryItemsForAttachments:attachments]; self.mediaGalleryItems = mediaGalleryItems; self.messageCellType = OWSMessageCellType_MediaGallery; @@ -675,9 +689,14 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) NSMutableArray *mediaGalleryItems = [NSMutableArray new]; for (TSAttachment *attachment in attachments) { + NSString *_Nullable caption = (attachment.caption + ? [self displayableCaptionForText:attachment.caption attachmentId:attachment.uniqueId].displayText + : nil); + if (![attachment isKindOfClass:[TSAttachmentStream class]]) { [mediaGalleryItems addObject:[[ConversationMediaGalleryItem alloc] initWithAttachment:attachment attachmentStream:nil + caption:caption mediaSize:CGSizeZero]]; continue; } @@ -686,6 +705,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) OWSLogWarn(@"Filtering invalid media."); [mediaGalleryItems addObject:[[ConversationMediaGalleryItem alloc] initWithAttachment:attachment attachmentStream:nil + caption:caption mediaSize:CGSizeZero]]; continue; } @@ -694,6 +714,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) OWSLogWarn(@"Filtering media with invalid size."); [mediaGalleryItems addObject:[[ConversationMediaGalleryItem alloc] initWithAttachment:attachment attachmentStream:nil + caption:caption mediaSize:CGSizeZero]]; continue; } @@ -701,6 +722,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) ConversationMediaGalleryItem *mediaGalleryItem = [[ConversationMediaGalleryItem alloc] initWithAttachment:attachment attachmentStream:attachmentStream + caption:caption mediaSize:mediaSize]; [mediaGalleryItems addObject:mediaGalleryItem]; } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 79a1d2723..28fe02b7e 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -4691,6 +4691,9 @@ typedef OWSContact * (^OWSContactBlock)(YapDatabaseReadWriteTransaction *transac [SignalAttachment attachmentWithDataSource:dataSource dataUTI:[MIMETypeUtil utiTypeForMIMEType:fakeAssetLoader.mimeType] imageQuality:TSImageQualityOriginal]; + if (arc4random_uniform(2) == 0) { + attachment.captionText = [self randomText]; + } [attachments addObject:attachment]; }