diff --git a/Signal/src/ViewControllers/ColorPickerViewController.swift b/Signal/src/ViewControllers/ColorPickerViewController.swift index 429a80cc7..a1bcac6c4 100644 --- a/Signal/src/ViewControllers/ColorPickerViewController.swift +++ b/Signal/src/ViewControllers/ColorPickerViewController.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation diff --git a/Signal/src/ViewControllers/ConversationView/Cells/MediaAlbumCellView.swift b/Signal/src/ViewControllers/ConversationView/Cells/MediaAlbumCellView.swift index 9319a2938..5e4beb8d0 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/MediaAlbumCellView.swift +++ b/Signal/src/ViewControllers/ConversationView/Cells/MediaAlbumCellView.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // import Foundation @@ -11,6 +11,9 @@ public class MediaAlbumCellView: UIStackView { @objc public let itemViews: [ConversationMediaView] + @objc + public var moreItemsView: ConversationMediaView? + private static let kSpacingPts: CGFloat = 2 private static let kMaxItems = 5 @@ -41,8 +44,6 @@ public class MediaAlbumCellView: UIStackView { } private func createContents(maxMessageWidth: CGFloat) { - var moreItemViews = [ConversationMediaView]() - switch itemViews.count { case 0: owsFailDebug("No item views.") @@ -129,7 +130,7 @@ public class MediaAlbumCellView: UIStackView { return } - moreItemViews.append(lastView) + moreItemsView = lastView let tintView = UIView() tintView.backgroundColor = UIColor(white: 0, alpha: 0.4) @@ -151,7 +152,7 @@ public class MediaAlbumCellView: UIStackView { } for itemView in itemViews { - guard !moreItemViews.contains(itemView) else { + guard moreItemsView != itemView else { // Don't display the caption indicator on // the "more" item, if any. continue @@ -277,4 +278,9 @@ public class MediaAlbumCellView: UIStackView { } return bestMediaView } + + @objc + public func isMoreItemsView(mediaView: ConversationMediaView) -> Bool { + return moreItemsView == mediaView + } } diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index 73adb67f4..2cb3d6a67 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "OWSMessageBubbleView.h" @@ -1376,10 +1376,6 @@ const UIDataDetectorTypes kOWSAllowedDataDetectorTypes OWSAssertDebug(self.bodyMediaView); OWSAssertDebug(self.viewItem.mediaAlbumItems.count > 0); - if (self.viewItem.mediaAlbumHasFailedAttachment) { - [self.delegate didTapFailedIncomingAttachment:self.viewItem]; - return; - } if (![self.bodyMediaView isKindOfClass:[OWSMediaAlbumCellView class]]) { OWSFailDebug(@"Unexpected body media view: %@", self.bodyMediaView.class); return; @@ -1392,8 +1388,21 @@ const UIDataDetectorTypes kOWSAllowedDataDetectorTypes return; } + if ([mediaAlbumCellView isMoreItemsViewWithMediaView:mediaView] + && self.viewItem.mediaAlbumHasFailedAttachment) { + [self.delegate didTapFailedIncomingAttachment:self.viewItem]; + return; + } + TSAttachment *attachment = mediaView.attachment; - if (![attachment isKindOfClass:[TSAttachmentStream class]]) { + if ([attachment isKindOfClass:[TSAttachmentPointer class]]) { + TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)attachment; + if (attachmentPointer.state == TSAttachmentPointerStateFailed) { + // Treat the tap as a "retry" tap if the user taps on a failed download. + [self.delegate didTapFailedIncomingAttachment:self.viewItem]; + return; + } + } else if (![attachment isKindOfClass:[TSAttachmentStream class]]) { OWSLogWarn(@"Media attachment not yet downloaded."); return; } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.h b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.h index d106c8249..487d5a7f5 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.h +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "ConversationViewLayout.h" @@ -47,6 +47,8 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType); @property (nonatomic, readonly, nullable) NSString *caption; +@property (nonatomic, readonly) BOOL isFailedDownload; + @end #pragma mark - diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m index d0783da92..60b94a184 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // #import "ConversationViewItem.h" @@ -64,6 +64,16 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) return self; } + +- (BOOL)isFailedDownload +{ + if (![self.attachment isKindOfClass:[TSAttachmentPointer class]]) { + return NO; + } + TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)self.attachment; + return attachmentPointer.state == TSAttachmentPointerStateFailed; +} + @end #pragma mark - @@ -1080,11 +1090,8 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) OWSAssertDebug(self.mediaAlbumItems.count > 0); for (ConversationMediaAlbumItem *mediaAlbumItem in self.mediaAlbumItems) { - if ([mediaAlbumItem.attachment isKindOfClass:[TSAttachmentPointer class]]) { - TSAttachmentPointer *attachmentPointer = (TSAttachmentPointer *)mediaAlbumItem.attachment; - if (attachmentPointer.state == TSAttachmentPointerStateFailed) { - return YES; - } + if (mediaAlbumItem.isFailedDownload) { + return YES; } } return NO;