diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m index 358428aa4..6493dd419 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSAudioMessageView.m @@ -128,6 +128,45 @@ NS_ASSUME_NONNULL_BEGIN self.audioProgressView.progressColor = progressColor; } +- (void)replaceIconWithDownloadProgressIfNecessary:(UIView *)iconView +{ + if (!self.viewItem.attachmentPointer) { + return; + } + + switch (self.viewItem.attachmentPointer.state) { + case TSAttachmentPointerStateFailed: + // We don't need to handle the "tap to retry" state here, + // only download progress. + return; + case TSAttachmentPointerStateEnqueued: + case TSAttachmentPointerStateDownloading: + break; + } + switch (self.viewItem.attachmentPointer.pointerType) { + case TSAttachmentPointerTypeRestoring: + // TODO: Show "restoring" indicator and possibly progress. + return; + case TSAttachmentPointerTypeUnknown: + case TSAttachmentPointerTypeIncoming: + break; + } + NSString *_Nullable uniqueId = self.viewItem.attachmentPointer.uniqueId; + if (uniqueId.length < 1) { + OWSFailDebug(@"Missing uniqueId."); + return; + } + + CGFloat downloadViewSize = self.iconSize; + MediaDownloadView *downloadView = + [[MediaDownloadView alloc] initWithAttachmentId:uniqueId radius:downloadViewSize * 0.5f]; + iconView.layer.opacity = 0.01f; + [self addSubview:downloadView]; + [downloadView autoSetDimensionsToSize:CGSizeMake(downloadViewSize, downloadViewSize)]; + [downloadView autoAlignAxis:ALAxisHorizontal toSameAxisOfView:iconView]; + [downloadView autoAlignAxis:ALAxisVertical toSameAxisOfView:iconView]; +} + #pragma mark - - (CGFloat)hMargin @@ -192,6 +231,8 @@ NS_ASSUME_NONNULL_BEGIN [self addArrangedSubview:self.audioPlayPauseButton]; [self.audioPlayPauseButton setContentHuggingHigh]; + [self replaceIconWithDownloadProgressIfNecessary:self.audioPlayPauseButton]; + NSString *_Nullable filename = self.attachment.sourceFilename; if (filename.length < 1) { filename = [self.attachmentStream.originalFilePath lastPathComponent]; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.h b/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.h index 350b93465..a06a54494 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.h +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.h @@ -7,9 +7,13 @@ NS_ASSUME_NONNULL_BEGIN @class ConversationStyle; @class TSAttachment; +@protocol ConversationViewItem; + @interface OWSGenericAttachmentView : UIStackView -- (instancetype)initWithAttachment:(TSAttachment *)attachment isIncoming:(BOOL)isIncoming; +- (instancetype)initWithAttachment:(TSAttachment *)attachment + isIncoming:(BOOL)isIncoming + viewItem:(id)viewItem; - (void)createContentsWithConversationStyle:(ConversationStyle *)conversationStyle; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m index b95fd220d..2508ced75 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSGenericAttachmentView.m @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) TSAttachment *attachment; @property (nonatomic, nullable) TSAttachmentStream *attachmentStream; +@property (nonatomic, weak) id viewItem; @property (nonatomic) BOOL isIncoming; @property (nonatomic) UILabel *topLabel; @property (nonatomic) UILabel *bottomLabel; @@ -30,7 +31,9 @@ NS_ASSUME_NONNULL_BEGIN @implementation OWSGenericAttachmentView -- (instancetype)initWithAttachment:(TSAttachment *)attachment isIncoming:(BOOL)isIncoming +- (instancetype)initWithAttachment:(TSAttachment *)attachment + isIncoming:(BOOL)isIncoming + viewItem:(id)viewItem { self = [super init]; @@ -40,6 +43,7 @@ NS_ASSUME_NONNULL_BEGIN _attachmentStream = (TSAttachmentStream *)attachment; } _isIncoming = isIncoming; + _viewItem = viewItem; } return self; @@ -130,6 +134,8 @@ NS_ASSUME_NONNULL_BEGIN [fileTypeLabel autoCenterInSuperview]; [fileTypeLabel autoSetDimension:ALDimensionWidth toSize:self.iconWidth - 20.f]; + [self replaceIconWithDownloadProgressIfNecessary:imageView]; + UIStackView *labelsView = [UIStackView new]; labelsView.axis = UILayoutConstraintAxisVertical; labelsView.spacing = [OWSGenericAttachmentView labelVSpacing]; @@ -175,6 +181,46 @@ NS_ASSUME_NONNULL_BEGIN [labelsView addArrangedSubview:bottomLabel]; } +- (void)replaceIconWithDownloadProgressIfNecessary:(UIView *)iconView +{ + if (!self.viewItem.attachmentPointer) { + return; + } + + switch (self.viewItem.attachmentPointer.state) { + case TSAttachmentPointerStateFailed: + // We don't need to handle the "tap to retry" state here, + // only download progress. + return; + case TSAttachmentPointerStateEnqueued: + case TSAttachmentPointerStateDownloading: + break; + } + switch (self.viewItem.attachmentPointer.pointerType) { + case TSAttachmentPointerTypeRestoring: + // TODO: Show "restoring" indicator and possibly progress. + return; + case TSAttachmentPointerTypeUnknown: + case TSAttachmentPointerTypeIncoming: + break; + } + NSString *_Nullable uniqueId = self.viewItem.attachmentPointer.uniqueId; + if (uniqueId.length < 1) { + OWSFailDebug(@"Missing uniqueId."); + return; + } + + CGSize iconViewSize = [iconView sizeThatFits:CGSizeZero]; + CGFloat downloadViewSize = MIN(iconViewSize.width, iconViewSize.height); + MediaDownloadView *downloadView = + [[MediaDownloadView alloc] initWithAttachmentId:uniqueId radius:downloadViewSize * 0.5f]; + iconView.layer.opacity = 0.01f; + [self addSubview:downloadView]; + [downloadView autoSetDimensionsToSize:CGSizeMake(downloadViewSize, downloadViewSize)]; + [downloadView autoAlignAxis:ALAxisHorizontal toSameAxisOfView:iconView]; + [downloadView autoAlignAxis:ALAxisVertical toSameAxisOfView:iconView]; +} + + (UIFont *)topLabelFont { return [UIFont ows_dynamicTypeBodyFont]; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index 4308f3513..d97b87c8f 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -838,7 +838,7 @@ NS_ASSUME_NONNULL_BEGIN conversationStyle:self.conversationStyle]; self.viewItem.lastAudioMessageView = audioMessageView; [audioMessageView createContents]; - [self addProgressViewsIfNecessary:audioMessageView]; + [self addProgressViewsIfNecessary:audioMessageView shouldShowDownloadProgress:NO]; self.loadCellContentBlock = ^{ // Do nothing. @@ -854,10 +854,11 @@ NS_ASSUME_NONNULL_BEGIN { TSAttachment *attachment = (self.viewItem.attachmentStream ?: self.viewItem.attachmentPointer); OWSAssertDebug(attachment); - OWSGenericAttachmentView *attachmentView = - [[OWSGenericAttachmentView alloc] initWithAttachment:attachment isIncoming:self.isIncoming]; + OWSGenericAttachmentView *attachmentView = [[OWSGenericAttachmentView alloc] initWithAttachment:attachment + isIncoming:self.isIncoming + viewItem:self.viewItem]; [attachmentView createContentsWithConversationStyle:self.conversationStyle]; - [self addProgressViewsIfNecessary:attachmentView]; + [self addProgressViewsIfNecessary:attachmentView shouldShowDownloadProgress:NO]; self.loadCellContentBlock = ^{ // Do nothing. @@ -895,7 +896,7 @@ NS_ASSUME_NONNULL_BEGIN // progress or tap-to-retry UI. UIView *attachmentView = [UIView new]; - [self addProgressViewsIfNecessary:attachmentView]; + [self addProgressViewsIfNecessary:attachmentView shouldShowDownloadProgress:YES]; self.loadCellContentBlock = ^{ // Do nothing. @@ -907,12 +908,12 @@ NS_ASSUME_NONNULL_BEGIN return attachmentView; } -- (void)addProgressViewsIfNecessary:(UIView *)bodyMediaView +- (void)addProgressViewsIfNecessary:(UIView *)bodyMediaView shouldShowDownloadProgress:(BOOL)shouldShowDownloadProgress { if (self.viewItem.attachmentStream) { [self addUploadViewIfNecessary:bodyMediaView]; } else if (self.viewItem.attachmentPointer) { - [self addDownloadViewIfNecessary:bodyMediaView]; + [self addDownloadViewIfNecessary:bodyMediaView shouldShowDownloadProgress:(BOOL)shouldShowDownloadProgress]; } } @@ -934,7 +935,7 @@ NS_ASSUME_NONNULL_BEGIN [uploadView setCompressionResistanceLow]; } -- (void)addDownloadViewIfNecessary:(UIView *)bodyMediaView +- (void)addDownloadViewIfNecessary:(UIView *)bodyMediaView shouldShowDownloadProgress:(BOOL)shouldShowDownloadProgress { OWSAssertDebug(self.viewItem.attachmentPointer); @@ -954,6 +955,9 @@ NS_ASSUME_NONNULL_BEGIN case TSAttachmentPointerTypeIncoming: break; } + if (!shouldShowDownloadProgress) { + return; + } NSString *_Nullable uniqueId = self.viewItem.attachmentPointer.uniqueId; if (uniqueId.length < 1) { OWSFailDebug(@"Missing uniqueId."); @@ -1062,7 +1066,9 @@ NS_ASSUME_NONNULL_BEGIN TSAttachment *attachment = (self.viewItem.attachmentStream ?: self.viewItem.attachmentPointer); OWSAssertDebug(attachment); OWSGenericAttachmentView *attachmentView = - [[OWSGenericAttachmentView alloc] initWithAttachment:attachment isIncoming:self.isIncoming]; + [[OWSGenericAttachmentView alloc] initWithAttachment:attachment + isIncoming:self.isIncoming + viewItem:self.viewItem]; [attachmentView createContentsWithConversationStyle:self.conversationStyle]; result = [attachmentView measureSizeWithMaxMessageWidth:maxMessageWidth]; break;